写在前面的话

设计模式一直是应用程序开发中很重要的组成部分,我们可能经常用到:工厂模式,单例模式,门面模式等等,但是这个经常也不是那么经常。

更多情况下,在移动端的应用程序开发中,似乎“设计模式”这一理念被淡化了许多(比起后端框架上来就出现的依赖注入)。
但是,在一些ViewController以及对应的Subview编写的地方,使用设计模式可能帮我们更好的梳理结构,因为他们总是一团乱糟,不是吗?

Swift中的装饰器模式

作者:Jeremi Kaczmarczyk
原文链接:https://medium.com/jeremy-codes/decorator-pattern-in-swift-e5fa11ea3c3f

这次,让我们通过一个具体的例子来解释一下什么是装饰器模式。作为经典的参考,装饰器模式的实现是基于“类”与“继承”的,我迫不及待的想用Swift作为一个例子给你详细的说道说道叻。

例子

作为例子,在我们的model层面中,我们创建一个RPG游戏中的角色。首先定义一个protocol。

 

好像也看起来很普通(我觉得很普通)。我们用这个protocol来创建一个实体角色:

 

我觉得还是很普通,但是作为一个RPG游戏来说(我指角色扮演),可太容易变成一匹脱缰的野马了。

 

我们有一些Orc结构体。因为他们内部的数值不一样,所以你也得明确的创建他们。游戏中只有3个Orcs + John的话,倒是也没什么大问题。但是如果你要加上Elves,Dwarves等一干人众,再来个getMana()方法来获取法力值的,我可建议你好好考虑一下,是否要采用“装饰器”模式了。

装饰器

装饰器扮演了4个主要角色,他们是:

  • 核心组件(Core Component) - 是基础类或者协议,我们的核心类会继承或实现它,在这里就是指Character这个protocol;
  • 实体组件(Concrete Component) - 是上面核心组件的继承或实现;
  • 装饰器(Decorator) - 也是上面核心组件的继承或实现,在这里就是指CharacterType这个protocol;
  • 实体装饰器(Concrete Decorator) - 是上面装饰器的实现,实体装饰器用来包裹组件或者其他装饰器,赋予其能力。在这里Warlord,Mage或者Epic就是实体装饰器。

 

装饰器用来处理下面几种情况:

  • 当你想要动态地,透明地,增加扩展一些功能时;
  • 当你想要做出可撤销的改变时
  • 当你已经创建了许多子类,不太可能进行继承时(就像上面的示例一样)

装饰器最大的好处是比继承更为灵活。在Swift中,我们有类似像protocol的方式来避免继承关系,但是之前难以处理。类似struct/protocol的实现看起来不错,有序并且很节省内存,高效的地组织起了我们的APP。为对象添加特定的职责,比如Warloard CharacterType这个例子,可以让Warlord具有“战吼”这一功能,也很有道理。

装饰器模式可以让你避免创建一个在基础层面上,就有很多很多功能的巨大的对象,并且可以减少代码的重复性。如果不这么做的话,想象一下你为了每个特定的功能,需要在基础类中创建多少样板代码。

需要记住的一点是,在装饰器模式中的对象并不是一样的。虽然他们可以一样,但是,最好牢记他们可以是不同的,谨慎总是没有坏处。许许多多的小文件(类)可能把你的工程项目搞得一团糟 :)

总结

通过上面的例子(仅仅是我的观点,不过话说回来整篇文章都是我的观点才对),我们可以清楚的了解到装饰器模式的潜力。使得创建一大堆复杂的但是行为类似的对象创建起来变得更为简单了。如果你和我动手做了做上面的例子,实现了一些自己的类的话,你就能感受到这种魅力。这就是通常所说的设计模式的魔力:简单化程序员之间的交流。这也是为什么我们要学习它们的重要理由。