情景:
要设计很多鸭子,每个鸭子都有quack(呱呱叫)和swim功能。
可以设计一个Duck类,含有quack()和swim()方法就可以了。具体鸭子类继承Duck类。
如果直接给Duck添加fly()方法,会出现问题,因为有一部分鸭子是不会飞的。
选择创建Flyable接口,只有会飞的鸭子才继承接口,可以解决这一问题,但是造成代码无法复用。
找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起。
因为鸭子的行为是变化的所以把鸭子的行为封装起来,创建一组行为类。
设计原则:针对接口编程,而不是针对实现编程。
针对接口编程的意思是: Dog(); 而不是 Dog();
Animal可以是超类或者接口,主要是通过多态,使得代码容易被扩展。
为每个行为写一个接口,行为的具体实现就是接口的一个实现类。这样具体行为就可以容易的被修改。
行为接口:
-----------
实现行为的具体类:
FlyNoWay "I can't fly" FlyWithWings "I'm flying!" Quack "Quack" MuteQuack "<< Silence >>"
Duck超类:
FlyBehavior flyBehavior;
QuackBehavior quackBehavior;
</span><span style="color: #0000ff;">public</span><span style="color: #000000;"> Duck() {
}</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> performFly() {
flyBehavior.fly(); </span><span style="color: #008000;">//</span><span style="color: #008000;"> 委托给行为类</span>
<span style="color: #000000;"> }
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> performQuack() {
quackBehavior.quack();
}
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> swim() {
System.out.println(</span>"All ducks flost,even decoys!"<span style="color: #000000;">);
}
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> display() {
System.out.println(</span>"I am a duck."<span style="color: #000000;">);
}
}
Duck一个具体实现类:
MallardDuck = = "I'm a real Mallard duck."
测试类:
=
输出:
'm flying!
如果能在Duck类中通过setter动态设置行为,而不是只能在构造方法中绑定,就可以更灵活的改变鸭子的行为。
Duck类:
FlyBehavior flyBehavior;
QuackBehavior quackBehavior;
</span><span style="color: #0000ff;">public</span><span style="color: #000000;"> Duck() {
}
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> setFlyBehavior(FlyBehavior flyBehavior) {
</span><span style="color: #0000ff;">this</span>.flyBehavior =<span style="color: #000000;"> flyBehavior;
}
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> setQuackBehavior(QuackBehavior quackBehavior) {
</span><span style="color: #0000ff;">this</span>.quackBehavior =<span style="color: #000000;"> quackBehavior;
}
</span><span style="color: #008000;">//</span><span style="color: #008000;">......</span>
}
新建一个模型鸭类型,默认不会飞
ModelDuck = = "I am a model duck."
然后建立一个火箭动力类(???)
FlyRocketPowered "I am flying with a rocket."
通过动态改变行为,模型鸭就可以飞啦~~
=
输出:
I can't fly
I am flying with a rocket.
把鸭子的行为封装起来,这样可以自由的改变鸭子的行为,也方便对行为的扩展。
把行为改变为算法,就是策略模式。
设计原则:多用组合,少用继承。
策略模式:定义了算法族,分别封装起来,让他们之间可以相互替换,此模式让算法的变化独立于算法的客户。
(讲道理我觉得书上这个例子举得一点都不好。。。。)
一个简单的例子:
doOperator( num1, AddStrategy doOperator( num1, num1 + SubStrategy doOperator( num1, num1 - MulStrategy doOperator( num1, num1 *
Strategy strategy;
</span><span style="color: #0000ff;">public</span><span style="color: #000000;"> Context(Strategy strategy) {
</span><span style="color: #0000ff;">this</span>.strategy =<span style="color: #000000;"> strategy;
}
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> setStrategy(Strategy strategy) {
</span><span style="color: #0000ff;">this</span>.strategy =<span style="color: #000000;"> strategy;
}
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">int</span> doOperator(<span style="color: #0000ff;">int</span> num1,<span style="color: #0000ff;">int</span><span style="color: #000000;"> num2) {
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> strategy.doOperator(num1,num2);
}
}
测试类:
= Context(2,32,32,3
原文链接:https://www.f2er.com/javaschema/69833.html