继承
- 对于
Duck,swim是所有的子类都需要具备的,因此在父类中实现能够很好的实现代码的复用。 - 但同样的,
fly,qucak这类的行为只有部分Duck具备,或者有些行为不确定是不是所有的Duck都具备。因此如果在父类中实现,则在一些子类中就多了一些自己不需要的功能,行为怪异。 - 所以:继承虽然是实现代码复用的一种方式,但它同样的会导致代码的可维护性与灵活性不足,给子类带来某种冗余。
接口与行为类
-
为了解决类似
fly,qucak这类只有部分Duck具备的行为,我们很自然的考虑了接口 -
实现接口有两种方式
-
Duck子类同时继承接口(is a),并实现各自的行为代码,但是这样会导致同样行为的子类之间代码冗余- 另一种方式则是引入行为类,由行为类来继承接口,而
Duck子类包含行为实例(has a),这能很好的实现行为逻辑的复用,并保持代码的灵活性
- 另一种方式则是引入行为类,由行为类来继承接口,而
-
可以看出行为类这种
has a的关系,更具代码复用性与灵活性,应该被优先考虑。
-
-
Has a行为的3种方式has a的实现有3种方式:成员变量、构造函数注入、方法注入- 在
Duck子类中直接实例化具体的行为类,这样会导致代码的强耦合(成员变量) - 通过参数化的方式,在
Duck子类实例化的时候传递行为实例,这样能够实现代码的解耦,保持灵活性,可测性。(参数注入) - 所以实现
has a行为优先考虑参数注入。
委托(行为传递)
Duck的performFly行为由flybehavior类来实现的方式叫委托。委托将额外的行为和逻辑封装到代理类中,从而增加了代码的灵活性和可复用性。- 委托不必是参数注入,它是一种通用的行为传递机制,可以用于各种情况,包括参数注入、事件处理、回调函数等。
行为为什么可以是类
- 类是包含
variables和methods的结构,行为也可以是类,如fly行为就可以有最大最小速度等variables,并提供fly的方法。
设计模式
- Identify the aspects of your application that vary and separate them from what stays the same.(这个概念很简单,但它几乎构成了每个设计模式的基础。所有模式都提供了一种方法,让系统的一部分独立于所有其他部分而变化)
- favor composition over inheritance(组合优于继承,组合更具灵活性,并且不失复用)
总结
本案例体现了:
- 继承的优缺点
- 接口的组合优于继承,接口的灵活性,
is-avs has-a - 委托的行为传递机制概念
- 重要概念:所有模式都提供了一种方法,让系统的一部分独立于所有其他部分而变化