设计模式——策略模式2

继承导致的缺点:

  • 代码在多个子类中重复(有些父类的行为,子类必须覆盖,例如有些鸭子不会飞,那么需要覆盖fly,则导致很多不会飞的子类都有一个什么都不干的fly方法)
  • 运行时的行为不容易改变(实例一旦创建,行为就确定了,很难再进行改变,例如给橡皮鸭装上火箭发射器)
  • 很难知道所有鸭子的全部行为(总有需求变化,增加鸭子的行为)
  • 改变会前一发动全身,造成其他鸭子不想要的改变(比如父类增加了一个会飞的行为,那么所有的子类鸭子都会飞了,在有些情况下造成了意外的错误,例如橡皮鸭飞了起来)

当涉及到“维护”时,为了“复用”(reuse)目的而使用继承,结局并不完美。

 

如果将行为设计成接口,而不同鸭子的实例实现相应的接口,依然有着巨大的缺点:

有可能有100只鸭子实现了会飞的接口,他们的fly方法完全一样(代码重复!!!),并且一旦需求发生改变,需要改变fly方法,要改100处!!!也就是无法代码复用。

 

策略模式:

定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。

特点:

  • 行为都被封装成类,然后通过“有一个”的方式,将行为集成到对象中(行为类作为客户类的属性)。
  • 有非常好的可维护性,如果想增加一种行为,只需要新定义一种行为类,然后增加客户类的一个属性就行了。并且不会影响到已有的系统。
  • 能够动态的替换不同的行为(客户类创建好之后,依然可以通过set方法来设置行为类)。

用策略模式解决鸭子的问题:类图如下:

代码要点:

  • 将经常改变的行为fly和quack剥离出来,设计成接口
  • 对于fly和quack的不同表现形式,分别设计成实现接口的行为类比如:FlyWithWings和Quack。
  • 鸭子的基类包含行为接口类型的属性(稍后要对其赋值)
  • 所有鸭子的实例,继承自鸭子基类,并且对于fly和quack属性进行赋值。
  • 提供fly和quack属性的set方法,可以动态的设置/改变这两个属性。

 

posted @ 2016-10-09 10:41  张驰小方块  阅读(122)  评论(0编辑  收藏  举报