采用标准的oo技术设计的鸭子
增加会飞的鸭子
单单是在Duck的超类中加入fly方法,会使所有的鸭子都会飞了。
对代码的局部修改影响层面可不只是局部。当为了复用的目的使用继承,结局不完美。
可是有人说可以把fly方法覆盖掉就行了,但是加入DecoyDeck(不会飞,也不会叫)又会是怎样呢?
利用接口又如何呢?
但是利用接口又会导致一个很严重的问题?
重复的代码又会变多!
接口的设计原则:
找出应用中可能需要变化支出,把它独立出来不要和那些不需要变化的代码混在一起,也就是把变化的部分取出来封装起来,好让其他部分不会受到影响。
换句话来说,如果每次新的需求依赖,都会是某方面的代码发生变化,那么你就可以确定,这部分的代码需要被抽取出来。
根据提取出变化与不需变化的的原则,可以把鸭子分为鸭子类,鸭子的行为又可以分为飞行类和呱呱叫类。
设计原则:我们是针对接口编程,不是针对实现编程。
从现在开始,鸭子的行为将被放在分开的类中,这个类专门提供某行为的接口的实现。
这样鸭子就不需要知道行为的实现的细节。
这种做法与以前的不同:
行为来自Duck超类的具体实现,或者是继承某个接口并有子类实现而来,这两种做法都是依赖于“实现”,我们被实现绑定得死死的,没有办法可以改变行为。
为什么要做成接口,如果做成抽象类,那样利用多态,不是更加好吗。
针对接口编程真正的意思实施“针对超类型编程”
接口是一个多义词,有着很多层概念,如Java中的interface构造。面向接口编程的关键是在于利用多态。利用多态,程序会根据执行的实际情况来执行真正的行为,不会死死绑定具体的实现。
超类型指的是只要是实现着个超类型的类都可以用这个超类型作为类型,声明类型时不需要声明具体的类型。
整合鸭子的行为:
关键在于,鸭子现在将飞行和呱呱叫的动作委托给别人处理,而不是在鸭子的内部声明Duck的呱呱叫和飞行的方法。
public class Duck(){
QuackBehavior quackBehavior;
//还有更多
public voi performQuack(){
quackBehavior.quack();
}
}
如何设定flyBehavior和quackBehavior的实例变量?
public class MallardDuck extends Duck{
public MallerdDuck(){
quackBehavior = new Quack();
flyBehavior = new FlyWithSwings();
}
}
设计的原则:
多用组合,少用继承!!!
使用组合建立起的系统具有很大的弹性,不仅可以将算法封装成类,更可以运行的时候动态地改变行为,只要组合的对象符合正确的接口标准就行。
OO基础:
抽象,继承,封装,多态
OO原则:
封装变化
多用组合,少用继承
针对接口编程,不针对实现编程
OO要点:
知道OO基础,并不足以让你设计出良好的系统。
良好的OO设计要满足三个特性:可重用性,可扩充性,维护性。
设计模式可以帮助我们设计出良好的OO设计质量的系统。
模式被认为是历经验证的OO设计经验。
模式不是代码,而是指针对设计问题的解决方案,你可以把模式应用到你的程序中。
模式不是发明,而是发现。
大多的模式和原则都是着力于软件的变化主题。
我们厂把系统的变化部分抽取出来。
模式为开发人员提供共同的语言。