装饰模式:
起因:
小菜要去见美女娇娇,怎么穿衣呢?这可让小菜发愁,于是他就向大鸟求助,没想到大鸟竟然让他写一个给人穿衣的代码!!!还说什么这也有一种模式可以引出!这个大鸟真是厉害啊!学以致用,什么都可以联想到设计模式!
![](https://img-blog.csdn.net/20141222183700789?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGlzaGFvcmFuMzY5/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
具体介绍:
装饰模式:动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活。
比如这个穿衣的例子:我们可以把衣服抽象成一个类,人抽象成一个类,然后让衣服类(相当于装饰抽象类Decorator类)继承人这个类(人类里面有使用对象的方法。),用一个其他的类来扩展人类(相当于ConcreteComponent类)的功能--穿衣。在客户端只用实例化一个人类然后依次按顺序调用衣服类中穿衣服的方法就可以了。就相当于我们把每个装饰对象的实现和如何使用这个对象分开了,每个装饰对象只要关心自己的功能就行,不需要知道自己如何被调用。
好处:
装饰模式是可以为已有功能动态地添加新功能的一种方式,可以有效地把类的核心职责和装饰功能区分开了,而且可以去除相关类中的重复逻辑。可以向旧的类中添加一些新的功能,而不修改旧类,只需要扩展就行。
那么我们需要把所需的功能按正确的顺序串联起来进行控制的时候就可以运用装饰者模式。
然而,装饰模式很容易和建造者模式弄混,下面我们来讲一下建造者模式,来对比一下两者到底有什么不同的地方。
建造者模式“
起因:
今天,小菜和大鸟一起去外边大排档吃饭。但是小菜的饭被炒的很好吃,但是大鸟的就被抄的特别难吃,不是忘了加盐,就是放的鸡蛋少。于是大鸟感慨:“肯德基和麦当劳的食物卖的火都是有理由的,他们的食物什么时候吃都是一个味道,不会因为忘记添加什么食材而把食物弄的非常难吃!”就这样大鸟得出了一个设计模式----建造者模式。
具体介绍:
建造者模式又称为生成器模式,即将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
就拿建造小人来说吧,要想建造一个小人,如果我们一步一步的写生成胳膊,生成脑袋的代码的话很容易就会忘掉一个胳膊或者一个腿的代码。但是如果我们把整个建造小人的完整过程封装起来的话,我们用到建造小人的时候只要调用这个‘过程’不就可以了吗?是不是不论怎么样也不会丢掉胳膊或者退了!也就是如果我们用了建造者模式,那么用户就只需指定需要建造的类型就可以得到他们,而具体建造的过程和细节就不需要知道了。
那么这个过程该怎么描述呢?让我们看着类图来说明。
首先,我们应该抽象一个建造过程类(PersonBuilder)相当于图中的Builder类,用来定义建造小人过程中的各种抽象方法。然后让具体的创建小人的类(PersonThinBuilder)相当于图中ConcreteBuilder类,继承PersonBuilder抽象类,把父类中的建造小人的抽象方法重写,实现各个部位的建造。最后我们需要一个类来接受客户端的命令,完成建造某个客户要求的某个小人。这个类就是PersonDirector类相当于途中的Director类。就这样我们的一个创建小人的过程就出来了,而且客户端只要调用这些类就行,不用知道小人到底是怎么造成的。而且保证造成的小人是客户要求的。
好处:建造者模式使得建造代码与表示代码分离,由于建造者模式隐藏了该产品是如何组装的,所以若需要改变一个产品的内部表示,只需要再定义一个具体的建造者就可以了。
那么当我们主要是用于创建一些复杂的对象,这些对象内部构建间的建造顺序通常是稳定的,但是对象内部的构建面临着复杂的变化的时候可以运用建造者模式。
两模式对比:
由上面的描述我们可以明显的找出两个模式的不同点是:装饰模式封装的过程是没有固定的顺序的,你可以按照任何一个顺序进行封装(比如虽然穿衣的顺序不同,但是都是穿规定的那几件衣服);而建造者模式对象内部构建间顺序通常都是稳定的,不会轻易改变,但是对象内部却有着复杂的变化(比如肯德基的每个汉堡的制作流程都是相同的,有口味不同的原因就是放的配料不同,但是同一种的汉堡味道肯定是相同的)。另外建造者模式是注重对象间的顺序,但是装饰模式是注重结构功能的顺序。