一:设计模式的分类
- 创建型(creational,主要用于处理对象的创建,实例化对象):单例,简单工厂,工厂,抽象工厂,建造者,原型
- 结构型(structural,处理类或对象间的组合):适配器,桥接,装饰,组合,外观,享元,代理
- 行为型(behavioral,描述类或对象怎样进行交互和职责分配):模板方法,命令,迭代器,观察者,中介,备忘录,解释器,状态,策略,职责链,访问者
可以思考一下,为什么会分成三类?为什么三类就可以概括这23种设计模式?有没有设计模式可以属于多种类型?
二:装饰器模式
定义
动态地给一个对象添加一些额外的职责。就增加功能来说,装饰器模式相比生成子类更为灵活。
解读
在装饰器模式的定义中,有几个描述值得注意
- 动态:此处的动态,是指在程序运行时,被装饰对象才会知道,我们给被装饰对象添加了哪些装饰,如果使用子类继承的方式,那我们在编写代码时,就已经规定了该子类将要为被装饰对象添加哪些装饰,这样对比起来,装饰器模式的装饰方式,可以定义为“动态”。
- 额外的职责:额外的职责,说明我们并不想对被装饰对象做修改,我们只是想为其“添加”一些功能,它并不用关心我们用哪些功能装饰了它。
- 比生成子类更为灵活:就像对于“动态”的解释,如果我们使用子类继承来为其添加功能,每一个子类,都只能为其添加确定的,在编码时就规定好了的功能,并不能随心所欲地做选择和随意搭配,而装饰器模式可以在要进行使用时,再决定为其添加哪些装饰,且可以随意搭配
注意事项
我们需要明确的一点是,装饰器模式属于结构型的设计模式,它讨论的主要内容是类或对象之间的组合,并不是对象的创建。
结构图
HeadFirst中的图:
大话设计模式中的图:
现在我们有两种装饰模式的uml图,他们大致相同,只有component的部分,有一些区别:
- headFirst将之放到了装饰的各个子类中,并且放到了类的构造方法里面。
- 大话设计模式将之放到了装饰的父类中,并且作为成员变量存在,另外添加了方法来为之赋值。
从结果来看,两种方式都完成了“装饰”的作用,但是出现这种区别的原因是什么呢?
我认为是因为各自举例时,使用的场景不同决定的,
对于大话设计模式,使用了一个为人物穿衣打扮的举例,在这个例子中,人没了衣服,和衣服没了人,都不影响它本身自己的存在。
对于headFirst,使用了一个冲咖啡时放调料的举例,在这个例子中,对于顾客来说,咖啡是一个整体,一杯摩卡咖啡,就必须添加了巧克力,没有添加巧克力的咖啡不能称之为摩卡,只有巧克力没有咖啡也不能称之为摩卡。
当然,实际上在真正写代码时,两种方式可以互换,并不会影响功能的实现。这里仅仅从业务角度来讨论一下出现差别的原因。
对于UML图的关系,如果按照四种来理解,就是
- 关联(聚合,组合)
- 依赖
- 继承
- 实现
一般关系表现为继承或实现关系(is a),关联关系表现为变量(has a ),依赖关系表现为函数中的参数(use a )。
如果按照六种来理解,还可以将聚合和组合区别于关联
也就是说,其实聚合和组合都可以看作是特殊的关联关系,他们只是为了细化关联关系的强弱存在的。