除了类本身,设计模式更强调多 个类/对象之间的关系和交互过程---比接口/类复用的力度更大
Creational patterns 创建型模式
工厂方法模式(虚拟构造器)
– 定义用于创建对象的接口,但让子类决定哪个要实例化的类。
– 工厂方法允许类将实例化推迟到子类。
当client不知道要创建哪个具体类的实例,或者不想在client代码中指明要具体 创建的实例时,用工厂方法。 定义一个用于创建对象的接口,让其子类来决定实例化哪一个类,从而使一个 类的实例化延迟到其子类
当需要增加产品的时候,只需增加工厂方法。
工厂方法:
调用
结构型模式
适配器模式
将某个类/接口转换为client期望的其他形式
通过增加一个接口,将已存在 的子类封装起来,client面向接口编程,从而隐藏了具体子类。
现有方法已经很好,但与用户需求存在一些区别,通过将现有实现方法封装起来,让后将具体实现通过委托给现有方法来满足客户的需求。
现有方法
抽象出一个符合用户需求的接口
通过委托来调用现有方法实现客户需求
客户端
装饰器模式
对每一个特性构造子类,通过委派机制增加到对象上
利用委托和继承
接口
stack装饰器实现最基本的方法
通过继承基本实现,实现原接口,委托给对应的Stack(子类型多态)
装饰器和继承的区别
装饰器在运行时组合功能,继承在编译时组合功能
装饰器由多个协作对象组成,继承产生一个单一的、明确类型的对象
可以混搭多种装饰,多重继承在概念上很困难
行为类模式
策略模式
有多种不同的算法来实现同一个任务,但需要client根据需要 动态切换算法,而不是写死在代码里
为不同的实现算 法构造抽象接口,利用delegation,运行时动态传入client倾向的算法类实例
策略接口
实现该接口的不同算法
通过委托来实现不同策略的调用(子类型多态)
黑盒框架
模板模式
做事情的步骤一样,但具体方法不同(继承+重写)
共性的步骤在抽象类内公共实现,差异化的步骤在各个子类中实现
共性方法不允许被改变,差异化方法在子类重写
简单的说就是模板规定了实现功能的具体步骤,将通用步骤在该模板中实现,差异步骤在子类中实现,但子类无法改变该方法的具体实现顺序。
在模板中实现了共性方法giftWrap,然后将差异化方法留给子类来实现(doSelect,doPayment,doDelivery)同时规定了方法的调用顺序,在processOrder中,可以看到giftWrap以及processOrder的前面都有修饰符final,意味着在其子类中不能对其进行修改,而保证了模板的不可变性,而abstract修饰差异方法,意味着子类(非抽象类)必须实现该方法。
子类继承该模板,重写其中的差异方法
白盒框架
迭代器模式
客户端希望遍历被放入 容器/集合类的一组ADT对象,无需关心容器的具体类型
也就是说,不管对象被放进哪里,都应该提供同样的遍历方式
需要遍历的类型来实现该接口
具体的实现策略来实现该接口
例如:
需要遍历的类
对应的迭代器
调用:
观察者模式
对特定类型的object的特定操作(visit),在运行时将 二者动态绑定到一起,该操作可以灵活更改,无需更改被visit的类。
为ADT预留一个将来可扩展功能的“接入点”,外部实现的功能代码 可以在不改变ADT本身的情况下通过delegation接入ADT
本质上:将数据和作用于数据上的某种/些特定操作分离开来。
可以理解为将类对象的一些对数据的操作委托给visitor来实现。
通用接口
将该类的信息传递给visitor,然后在visitor中重载该方法来实现各种不同类型的调用。
该功能原本可以在对应的类中实现,但将其委托给visitor。
只需要更换visitor的具体实现即可切换算法。
访问者与迭代器的区别:
迭代器:以遍历的方式访问集合数据而无需暴露其内部表示,将“遍历”这项功能delegate到外部的iterator对象。
在特定ADT上执行某种特定操作,但该操作不在ADT内部实现,而是delegate到独立的visitor对象,客户端可灵活 扩展/改变visitor的操作算法,而不影响ADT。
策略与访问者的区别:
二者都是通过delegation建立两个对象的动态联系
– 但是Visitor强调是的外部定义某种对ADT的操作,该操作于ADT自身关系 不大(只是访问ADT),故ADT内部只需要开放accept(visitor)即可,client 通过它设定visitor操作并在外部调用。
– 而Strategy则强调是对ADT内部某些要实现的功能的相应算法的灵活替换。 这些算法是ADT功能的重要组成部分,只不过是delegate到外部strategy类 而已。
区别:visitor是站在外部client的角度,灵活增加对ADT的各种不同操 作(哪怕ADT没实现该操作),strategy则是站在内部ADT的角度, 灵活变化对其内部功能的不同配置。