粗俗的理解
一个好的程序能根据不同的情况容易的改变一些行为,而不用大面积的修改代码。并且具有良好的可扩展性
一个你可能使用过的例子
在Java或者是Android中的LayoutManager。
View.setLayoutManager(gridLayout);
如果我们在以后突然有了新的需求,要改变布局样式,是不是只需要修改setLayoutManager的参数即可,而不用大面积的修改我们的程序。
问题引入
这里引入一个非常经典的Duck(鸭子)问题。完整篇可以参考《Head First Design Patterns》。
有一个鸭子游戏,其中很多种不同的鸭子,比如,绿头鸭,橡皮鸭,木头鸭等等。他们之间有很多共同的方法,所以要实现这些鸭子,我们可以定义一个父类,分别让这些不同种类的鸭子继承,来减少代码量。
比如我们可以在父类中定义飞行,嘎嘎叫,浮水等。
看起来好像很完美,这的确是我们的正常思路,但是在实际实现的时候好像出现了一些问题,木头鸭也能飞吗?橡皮鸭也会嘎嘎叫吗?橡皮鸭叫起来是吱吱~的。好像重写父类的方法就能解决问题,但如果有更多不同种类的鸭子加入进来,那么重复代码将会变得非常多,系统的逻辑也会变得非常乱。这在面向对象的实现中是不合理的。
上面我们分析得出飞行和叫的方法会随着不同的鸭子种类改变而改变,所以我们把它抽离出来可不可以呢?
分析:
建立一个鸭子的抽象父类
因为飞行和叫的行为需要多种变化,所以建立他们的接口,然后针对每一种行为具体实现对应的算法。
动手实现
按照我们的思路,建立一个抽象父类Duck.java
public abstract class Duck {
public Duck() {
};//构造方法
/*
* 因为每种类型的鸭子都需要显示,但是显示效果都不一样,所以定义成了抽象方法,每一个继承于这个类的子类,都需要强制实现该方法。
* */
public abstract void display();
/*
* 每一种鸭子都能浮水,所以直接实现了该方法。
* */
public void swim() {
System.out.println("All ducks float,even decoys(所有的鸭子都能浮在水面上,包括诱饵鸭)");
}
}
下面我们来设计飞行和叫的功能。
建立飞行接口,FlyBehavior.java
public interface FlyBehavior {
public void fly();
}
建立叫的接口,QuackBehavior.java
public interface QuackBehavior {
public void quack();
}
实现会飞的飞行类。
建立FlyWithWings 类,实现FlyBehavior 接口
public class FlyWithWings implements FlyBehavior {
@Override
public void fly() {
// TODO Auto-generated method stub
System.out.println("I'm flying!!")