HeadFirst设计模式<1>
1 策略模式
鸭子飞行和嘎嘎叫策略
2 工厂模式
简单工厂
工厂方法
抽象工厂
简单工厂简单的pizza工厂
- 通过一个工厂类的方法,创建和返回对象实例
- 原来混乱的代码:
- 修改后
- 简单工厂类图
Pizza店变成加盟店
- 在创建Pizza时将工厂传进去
- 想要多一些的质量控制,每个pizza店的工艺又不一样,有的先切再烤,有的先烤再切。
- 现在来看看Pizza店的多态。将变化的东西移到低层(实现,子类),抽象的共性移到高层(超类或接口)这边把Pizza的工艺流程移到子类中去
- PizzaStore超类变成,将CreatePizza变成抽象方法,由子类实现方法。
- 工厂模式的工厂方法
Pizza本身,超类
- Pizza的多态
最终的User调用
对于pizza店和pizza通过工厂模式形成了一个pizza组件,这边对pizza的实现,就不会违反针对接口编程
简单工厂模式
- 创建者和产品
所有的底层都依赖于高层,高层与高层之间相互依赖,相互解耦。
- 工厂UML
Pizza店再次升级,Pizza原料升级
- Ingredient(成分)超类:
- Dough(面团)Veggies(蔬菜)Pepperoni(意大利香肠)clam(蛤)子类:
改造Pizza类
- 抽象方法prepare()
- cheesepizza
- 靠近一点工厂
- 商店如何使用工厂
抽象工厂模式类图
抽象工厂模式:提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。
Pizza店的类图
3 命令模式
命令封装,支持撤销,宏命令,队列请求。
餐厅案例
餐馆点餐就是命令模式
回到遥控器
动作请求者和动作执行者解耦,
- 命令接口:
- 具体命令:
-
命令调用者
-
简单测试
命令的调用者是遥控器 ,命令执行者是灯,如果不用命令模式应该是遥控器直接调用灯。
命令模式最重要变化的是命令的执行者,在执行者有多种多样的时候,就需要命令模式来实现。
命令模式类图
receiver:就是上文中的灯,action方法为light.on()方法。
支持撤销
将每个命令支持撤销方法
使用状态的撤销
宏命令之激进的遥控器
该遥控器要实现自动化功能,一键打开灯光,音响,电视和DVD,直接进入Party模式
队列请求
命令可以在不同的线程中被调用,日程安排,线程池,工作队列等。
日志请求
某些应用需要我们将所有的动作都记录在日志中,并能在系统司机之后,重新调用这些动作恢复到之前的状态,通过新增两个方法(store()和load()),例用对象的序列化(serialization)实现这些方法,序列化最好只用在对象持久化(persistence)上。
怎么做:当我们执行命令的时候,将历史记录储存在磁盘中,一旦系统司机,我们就可以将命令对象重新加载,并成批地依次调用这些对的execute()方法。
许多调用大型数据结构的动作的应用我无法在每次改变发生时被快速的记录。通过使用记录日志,可以将上次检查点(checkpoint)之后的所有操作记录下来。如果系统出状况,从检查点开始应用这些操作。
比方说对于电子表格的应用:将电子表格的操作记录在日志中,而不是每次电子表格一有变化就记录整个电子表格。对于更高级的应用而言,这些技巧可以被扩展应用到事务(Transaction)中,也就是说一群操作必须全部进行完成。
4 状态模式
策略模式和状态模式是双胞胎,在出生时才分开。
策略模式是通过互换算法来创建成功业务的,状态是通过改变对象内部的状态来帮助对象控制自己的行为。
糖果机
这个一个状态图,每个圆圈都是一个状态。
测试:
激进糖果机
当曲柄转动时,有10%的几率会得到免费糖果。
将之前的状态都变成类创建state接口
- 类似的实现所有的状态类
- 糖果机改造
状态模式
允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类。
状态模式和策略模式,状态模式是上下文根本不知道对象发生了改变
十次抽奖
总结
跟策略模式很像,策略模式是将不同的算法(变化的地方)封装成类,实现弹性变化,而状态模式是将不同的状态封装成类,同时客户不会直接改变状态,最好由状态自己改变状态,