HeadFirst设计模式<1>

HeadFirst设计模式<1>

1 策略模式

策略模式

../_images/seq_Strategy.jpg

鸭子飞行和嘎嘎叫策略

1573522362069

2 工厂模式

简单工厂

../_images/SimpleFactory.jpg

../_images/seq_SimpleFactory.jpg

工厂方法

../_images/FactoryMethod.jpg

../_images/seq_FactoryMethod.jpg

../_images/loger.jpg

img

抽象工厂

../_images/AbatractFactory.jpg

../_images/seq_AbatractFactory.jpg

简单工厂简单的pizza工厂

  • 通过一个工厂类的方法,创建和返回对象实例

1573522439641

  • 原来混乱的代码:

1573522617683

  • 修改后

1573522695898

  • 简单工厂类图

1573522752878

Pizza店变成加盟店

1573522936624

  • 在创建Pizza时将工厂传进去

1573523017551

  • 想要多一些的质量控制,每个pizza店的工艺又不一样,有的先切再烤,有的先烤再切。

1573523268350

  • 现在来看看Pizza店的多态。将变化的东西移到低层(实现,子类),抽象的共性移到高层(超类或接口)这边把Pizza的工艺流程移到子类中去

1573523356734

1573523869191

1573523896063

  • PizzaStore超类变成,将CreatePizza变成抽象方法,由子类实现方法。

1573524067917

  • 工厂模式的工厂方法

1573524169844

Pizza本身,超类

1573524496988

  • Pizza的多态

1573524542662

最终的User调用

对于pizza店和pizza通过工厂模式形成了一个pizza组件,这边对pizza的实现,就不会违反针对接口编程

1573524588864

简单工厂模式

  • 创建者和产品

1573524759662

所有的底层都依赖于高层,高层与高层之间相互依赖,相互解耦。

1573524813813

  • 工厂UML

1573525037201

Pizza店再次升级,Pizza原料升级

  • Ingredient(成分)超类:

1573525987232

  • Dough(面团)Veggies(蔬菜)Pepperoni(意大利香肠)clam(蛤)子类:

1573526054257

改造Pizza类

  • 抽象方法prepare()

1573526283209

  • cheesepizza

1573526337215

  • 靠近一点工厂

1573526403528

  • 商店如何使用工厂

1573526487108

抽象工厂模式类图

抽象工厂模式:提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。

1573526645560

Pizza店的类图

1573526742871

3 命令模式

命令封装,支持撤销,宏命令,队列请求。

../_images/Command.jpg

../_images/seq_Command.jpg

../_images/Command_eg.jpg

../_images/seq_Command_eg.jpg

餐厅案例

1573570296084

餐馆点餐就是命令模式

1573570996129

1573571069142

1573571209334

回到遥控器

动作请求者和动作执行者解耦,

  • 命令接口:

1573571316249

  • 具体命令:

1573571329868

  • 命令调用者1573571389149

  • 简单测试

    1573652063395

命令的调用者是遥控器 ,命令执行者是灯,如果不用命令模式应该是遥控器直接调用灯。

命令模式最重要变化的是命令的执行者,在执行者有多种多样的时候,就需要命令模式来实现。

命令模式类图

1573653013717

receiver:就是上文中的灯,action方法为light.on()方法。

1573653904898

支持撤销

将每个命令支持撤销方法

1573654115227

1573654125422

1573654144656

1573654169008

使用状态的撤销

1573655612291

1573655671535

1573655711767

宏命令之激进的遥控器

该遥控器要实现自动化功能,一键打开灯光,音响,电视和DVD,直接进入Party模式

1573655867447

1573655893937

1573655990615

1573656028387

1573656102944

队列请求

命令可以在不同的线程中被调用,日程安排,线程池,工作队列等。

日志请求

​ 某些应用需要我们将所有的动作都记录在日志中,并能在系统司机之后,重新调用这些动作恢复到之前的状态,通过新增两个方法(store()和load()),例用对象的序列化(serialization)实现这些方法,序列化最好只用在对象持久化(persistence)上。

​ 怎么做:当我们执行命令的时候,将历史记录储存在磁盘中,一旦系统司机,我们就可以将命令对象重新加载,并成批地依次调用这些对的execute()方法。

​ 许多调用大型数据结构的动作的应用我无法在每次改变发生时被快速的记录。通过使用记录日志,可以将上次检查点(checkpoint)之后的所有操作记录下来。如果系统出状况,从检查点开始应用这些操作。

​ 比方说对于电子表格的应用:将电子表格的操作记录在日志中,而不是每次电子表格一有变化就记录整个电子表格。对于更高级的应用而言,这些技巧可以被扩展应用到事务(Transaction)中,也就是说一群操作必须全部进行完成。

1573657075868

4 状态模式

策略模式和状态模式是双胞胎,在出生时才分开。

策略模式是通过互换算法来创建成功业务的,状态是通过改变对象内部的状态来帮助对象控制自己的行为。

../_images/State.jpg

../_images/seq_State.jpg

../_images/State_eg.jpg

../_images/seq_State_eg.jpg

糖果机

1573657473228

这个一个状态图,每个圆圈都是一个状态。

1573657532071

1573657568594

1573657604552

1573657716301

测试:

1573657748985

激进糖果机

当曲柄转动时,有10%的几率会得到免费糖果。

将之前的状态都变成类创建state接口

1573657914726

1573657981897

1573658056688

1573739509140

  • 类似的实现所有的状态类
  • 糖果机改造

1573739622207

1573739638682

1573739757903

1573739819226

状态模式

允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类。

1573740066555

状态模式和策略模式,状态模式是上下文根本不知道对象发生了改变

十次抽奖

1573740492379

1573740544180

1573740567210

1573740596436

总结

跟策略模式很像,策略模式是将不同的算法(变化的地方)封装成类,实现弹性变化,而状态模式是将不同的状态封装成类,同时客户不会直接改变状态,最好由状态自己改变状态,

posted @ 2019-11-12 23:18  阿杜888  阅读(343)  评论(0编辑  收藏  举报