ü
设计原则
2
:针对接口编程而不是针对实现编程。
这里的接口有多个含义,它能够是
java
中的
interface
,也能够是抽象类。
“针对接口编程”,
关键就在多态
。利用多态,程序能够针对超类型编程,执行时会根据实际情况执行到真正的行为,不会被绑死在超类型的行为上。“针对超类型编程”这句话,能够更明确地说成“变量的声明类型应该是超类型,一般是一个抽象类或者是一个接口,如此,只
要是具体实现此超类型的类所产生的对象,均可以指定给这个变量
。
举个例子:
假设有一个抽象类
Animal
,其下有两个实现类
Dog
和
Cat
继承自
Animal
。作法以下:
²
针对实现编程:
Dog dog = new Dog();
bj.bark();
注:
声明变量“
dog
”
为
Dog
类型
(
是
Animal
的具体实现
)
,会形成咱们必须针对具体实现编码。
²
针对接口
/
抽象类编程
:
Animal animal = new Dog();
Animal.makeSound();
注:利用
animal
进行多态的调用。
设计原则3:多用组合(composition),少用继承
使用组合创建系统具备很大的弹性,不只可将行为封装成类,更能够“在运行时动态地改变行为
”
,只要组合的行为对象符合正确的接口标准便可。
例如:在设计原则一中咱们把“飞行行为”和“呱呱叫行为”这两个变化的行 为从鸭子类中分离出来。这里咱们就设计这两个行为和鸭子类:
以上 以上为两个行为接口和它的实现类。此时咱们要作的就是把两个行为整合到鸭子类中,具体怎么整合?继承吗?继承只能继承一个特定的类,所以用继承将不能“在运行时动态地改变行为”。那么咱们选用组合。
在Duck类中“加入两个实例变量”,分别为“flyBehavior”与“quackBehavior”,声明为接口类型(而不是具体类实现类型),每一个鸭子对象都会动态地设置这些变量以在运行时引用正确的行为类型(例如:FlyWithWings、Squeak等)。
此时咱们就把两个行为组合到
Duck
类中了,既然使用了组合,咱们怎么
在运行时动态地改变行为呢?以下咱们写一个
main
函数来看看:
p
ublic static void mian(String args[]){
Duck duck = new Duck();
duck
.setFlyBehavior(new FlyNoWay());
duck
.setQuackBehavior(new Quack());
//
此时若想要鸭子能飞,咱们能够经过
setter
方法
在运行时动态地改变行为
duck.setFlyBehavior(new FlyWithWings());
}
Sping
中依赖注入(IOC)使用的就是组合。