Swift中的策略模式

最近,我在NSCoder Night Madrid上发表了有关战略模式的演讲 人们喜欢它! 我认为我们的社区也将从这些知识中受益。 因此,在本指南中,我将解释iOS的策略模式并提供一些示例。

首先,我们应该定义这种模式。 在Wikipedia中,其定义如下:

在计算机编程中, 策略模式是一种行为软件设计模式 ,可以在运行时选择算法。 代码不是直接实现单个算法,而是接收运行时指令,以说明要使用的算法系列中的哪个。

definition⁉️这个定义非常理论化,所以我认为我们可以更轻松地定义它:

将算法封装在类中,使它们在运行时可重用和互换。

分类

设计模式根据其目标分为三类:

  • 创造力的
  • 结构性
  • 行为的

是的,策略模式是一种行为模式,因为它与对象的行为有关。 容易吧?

在许多情况下,我们可以使用它。 让我们谈谈三个非常具体的场景,在这些场景中我们可以清楚地看到战略模式的价值。

1️⃣用不同的方法做同样的事情

当您需要以不同的方式在代码中执行相同的操作时,可以使用它是一个明显的示例。

2️⃣而不是继承

如果您需要扩展类的功能并执行此操作,则需要创建一个继承自该类的新类。

3️⃣if / else块的替代方法

这是我最喜欢的。 有时,如果您查看一个类,您会发现它的if / else或switch块太多,我是说条件块。 这表明该班级的职责比应有的多。 使用策略模式将有助于您分发它们。

假设我们需要创建一个Logger类,该类在控制台中打印一条消息。 此外,此类还允许您打印样式化的消息: 小写大写大写 。 因此,可能的实现可能是这样的:

  • 内容: 定义我们要封装的动作的协议。 在我们的示例中,操作将是 记录一条消息
  • 谁: 包含符合策略的对象的对象。 在我们的示例中, 使用策略记录消息 的对象可能是对象
  • 方法: 该策略的具体实施。 每个实现都是不同的。 在我们的示例中,我们将有 三个 策略, 每个样式一个。

因此,前面使用策略的示例如下所示:

在我的公司eDreams ODIGEO (在线旅行社)中,用户可以选择单程或往返。 因此,当我们需要打开日历来选择日期时,根据选择的旅行类型,选择策略会有所不同。 例如,如果是往返行程,则返回日期必须晚于出发日期。

因此,我们有两种选择策略,当打开日历时,我们指定应使用的策略:

https://gist.github.com/Juanpe/e43441aeeb5d43e83db80e05469e306b

表单验证

当我们在应用程序中使用表单时,我们有多种类型的字段,文本,数字,密码,电子邮件……此外,每种表单都有其自己的验证条件。 然后,我们可以定义一个验证策略,每个领域都知道如何验证自己。

https://gist.github.com/Juanpe/4749d6269d7e7368d900bda88d4b8776

🎨绘制UITableView单元格

绘制单元格也是有用的。 想象一下,我们需要绘制非常不同的单元格。 然后,我们将拥有一个抽屉,该抽屉将使用视图模型绘制特定的单元格。

https://gist.github.com/Juanpe/30123af0421999591d9d430acc9f762d

in在购物车中付款

确切地说,付款方式是在我们的应用中,我们提供了几种付款方式来支付购物车:现金,卡,支票……在这种情况下,我们将为每种方式使用特定的策略,因此,当我们仅开始付款时我们将需要指定金额和付款界面。

https://gist.github.com/Juanpe/c1f92f0ce726246978f8e22548c428e7

🔫在游戏中交换武器

改变上下文,在游戏中,玩家使用武器交换武器或射击。 所有武器的动作都相同,但是每种武器都有自己的射击方式,玩家不需要知道,这是玩家射击时每种武器都知道该做什么。

该策略是最有用和最简单的设计模式之一。 另外,如果我们使用此模式,则您做得很好,也许您不知道:

符合一些SOLID原则

  1. 单一责任。 当我们制定策略来做不同的事情时,我们会发现我们原来的班级的责任更少。
  2. 开关。 如果我们使用策略扩展对象的功能,则不需要更新原始对象。 与第一个示例一样,如果要添加新样式,则只需创建新策略。 否则,我们需要在Styles枚举中添加新的大小写。

最佳实践

在谈论软件设计时,使用设计模式是一种好习惯。

代码可测试性

如果我们直接减轻对象的责任,我们将使对象更具可测试性。


我希望本文能帮助您学习更多策略模式,正如我之前所说的那样,它具有很多优点,并且其实现并不复杂。

注意:找到新的设计模式时,我们想在任何地方使用它。 可是等等! 我们必须分析我们是否应该使用它。 有时我们会过度设计。

感谢您阅读我的教程。 如果对您有用或认为对某人有用,请共享它。 如果您有任何疑问或任何改进建议,请在下面发表评论。