设计原则:
找出应用中可能需要变化之处,把他们独立出来,不要和那些不需要变化的代码混在一起。如果每次新的需求一来,都会是某方面的代码发生变化,那么这部分的代码需要被抽出来,和其他稳定的代码有所区分。
另一种思考方式:把会变化的部分取出并封装起来,以便以后轻易地改动或扩充此部分,而不影响不需要变化的其他部分。
设计原则:
针对接口编程,而不是针对实现编程。针对接口编程真正的意思是“针对超类型(supertype)编程(可以是接口或抽象类)”,针对接口编程关键就在于多态。利用多态,程序可以针对超类编程,执行时会根据实际状况执行到真正的行为,不会被绑死在超类型的行为上。
接口FlyBehavior:飞行行为是变化的,应当独立出来,并由不一样的飞行类来继承飞行动作这个接口。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
public
interface
FlyBehavior {
public
void
fly();
}
//===================================================//
public
class
FlyWithWings
implements
FlyBehavior {
@Override
public
void
fly() {
// TODO Auto-generated method stub
System.out.println(
"I'm flying!!"
);
}
}
//===================================================//
public
class
FlyNoWay
implements
FlyBehavior {
@Override
public
void
fly() {
// TODO Auto-generated method stub
System.out.println(
"I'm can't fly!"
);
}
}
|
接口QuackBehavior:发声行为是变化的,应当独立出来,并由不一样的发声类来继承发声动作这个接口。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
public
interface
QuackBehavior {
public
void
quack();
}
//====================================================//
public
class
Quack
implements
QuackBehavior {
@Override
public
void
quack() {
// TODO Auto-generated method stub
System.out.println(
"Quack"
);
}
}
//====================================================//
public
class
MuteQuack
implements
QuackBehavior {
@Override
public
void
quack() {
// TODO Auto-generated method stub
System.out.println(
"<< Silence >>"
);
}
}
//====================================================//
public
class
Squeak
implements
QuackBehavior {
@Override
public
void
quack() {
// TODO Auto-generated method stub
System.out.println(
"Squeak"
);
}
}
|
Duck 抽象类 鸭子现在将飞行和发声的多做委托给别人处理,而不是在自己类内部飞行和发声。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
public
abstract
class
Duck {
FlyBehavior flyBehavior;
QuackBehavior quackBehavior;
public
Duck() {
// TODO Auto-generated constructor stub
}
public
abstract
void
display();
public
void
performFly() {
flyBehavior.fly();
}
public
void
performQuack() {
quackBehavior.quack();
}
public
void
swim() {
System.out.println(
"All ducks float,even decoys!!"
);
}
}
|
绿头鸭使用Quack类来处理发声所以当performQuack被调用时,发声的职责被委托给Quack对象,而我们得到了真正的发声;使用FlyWithWings作为其FlyBehavior类型
1
2
3
4
5
6
7
8
9
10
11
12
|
public
class
MallardDuck
extends
Duck {
public
MallardDuck() {
// TODO Auto-generated constructor stub
quackBehavior =
new
Quack();
flyBehavior =
new
FlyWithWings();
}
@Override
public
void
display() {
// TODO Auto-generated method stub
System.out.println(
"I'm a real Mallard duck!"
);
}
}
|
测试类:
1
2
3
4
5
6
7
8
9
10
11
|
public
class
TEST_Main {
public
static
void
main(String[] args) {
Duck mallardDuck =
new
MallardDuck();
mallardDuck.performFly();
mallardDuck.performQuack();
}
}
/*输出结果....................
I'm flying!!
Quack
*/
|
动态设定行为
在鸭子里建立了一堆动态的功能没有用到,就太可惜了!假设在Duck类中通过“设定方法(setter method)”来设定鸭子的行为,而不是在鸭子的构造器内实例化。
在Duck类中,加入两个新方法:
1
2
3
4
5
6
|
public
void
setFlyBehavior(FlyBehavior fb) {
flyBehavior = fb;
}
public
void
setQuackBehavior(QuackBehavior qb) {
quackBehavior = qb;
}
|
在运行时想改变鸭子的行为,只需调用鸭子的setter方法就可以。
本文转自 ponpon_ 51CTO博客,原文链接:http://blog.51cto.com/liuxp0827/1351909,如需转载请自行联系原作者