需求:
要实现鸭子飞 叫 游泳等功能: (部分要着功能,部分不要该功能)
1、有些鸭子会飞
2、有些鸭子不会飞
3、有些鸭子会叫
4、有些鸭子不会叫
如果我们采用抽象类定义 飞 叫抽象行为,让实现类自己去实现,当飞 叫的行为大部分是要被复用的
(即:大部分鸭子是会叫和会飞的)达不到复用的效果
如果我们采用抽象类中实现 飞叫行为,我们只有在(不需要飞叫的鸭子)重写飞叫行为,应为飞叫
行为是需求不确定的,可变化的,如果产生变化,修改其行为,会影响所有地方子类 。
如果解决上述问题......
应用场景:
策略模式:
定义了算法族,分别封装起来,让他们之间可以互相替换。
在例子中 所有的方法都看成一种算法,其中飞行为和叫行为 我们都进行了封装
实现方式:
/**
*
* function:定义鸭子接口
* @author wanhonghui
*
*/
public abstract class Duck {
/*定义两个变量 鸭子飞和叫的行为变量*/
private FlyBehavior flyBehavior;
private QuckBehavior quckBehavior;
public Duck(FlyBehavior flyBehavior, QuckBehavior quckBehavior) {
this.flyBehavior = flyBehavior;
this.quckBehavior = quckBehavior;
}
/**
* function :鸭子游泳,需求对鸭子会游泳是确定的
*
*/
public void swing(){
System.out.println("鸭子天生就会游泳");
}
/**
* function :显示鸭子(鸭子不同)
*
*/
public abstract void display();
/**
* 功能描述 :委托给飞行为类,这样的好处是实现类关心会飞还是不会飞
*/
public void proxyFly(){
flyBehavior.fly();
}
/**
* 功能描述 :委托给叫行为类
*/
public void proxyQuck(){
quckBehavior.quck();
}
public void setFlyBehavior(FlyBehavior flyBehavior) {
this.flyBehavior = flyBehavior;
}
public void setQuckBehavior(QuckBehavior quckBehavior) {
this.quckBehavior = quckBehavior;
}
}
/**
* 功能描述:飞的行为
* @author Administrator
*/
public interface FlyBehavior {
/**
* 功能描述 :飞的行为
*
*/
public void fly();
}
/**
* 功能描述:鸭子不会飞行为
* @author Administrator
*/
public class FlyNotWay implements FlyBehavior{
@Override
public void fly() {
System.out.println("鸭子不会飞");
}
}
/**
* 功能描述:鸭子会飞行为
* @author Administrator
*/
public class FlyYesWay implements FlyBehavior {
@Override
public void fly() {
System.out.println("鸭子会飞");
}
}
/**
* 功能描述:叫的行为
* @author Administrator
*/
public interface QuckBehavior {
/**
* 功能描述 :叫的行为
*/
public void quck();
}
/**
* 功能描述:鸭子会叫行为
* @author Administrator
*/
public class QuckYesWay implements QuckBehavior {
@Override
public void quck() {
System.out.println("鸭子会叫");
}
}
/**
* 功能描述:鸭子不会叫行为
* @author Administrator
*/
public class QuckNotWay implements QuckBehavior{
@Override
public void quck() {
System.out.println("鸭子不会叫");
}
}
public class RedHeadDuck extends Duck {
public RedHeadDuck(FlyBehavior flyBehavior, QuckBehavior quckBehavior) {
super(flyBehavior, quckBehavior);
}
@Override
public void display() {
System.out.println("我是红头鸭");
}
}
public class MallardDuck extends Duck {
public MallardDuck(FlyBehavior flyBehavior, QuckBehavior quckBehavior) {
super(flyBehavior, quckBehavior);
}
@Override
public void display() {
System.out.println("我是绿头鸭");
}
}
public class Main {
public static void main(String[] args) {
Duck duck = new RedHeadDuck(new FlyYesWay(),new QuckNotWay());
duck.proxyFly();
duck.proxyQuck();
duck.swing();
}
}
鸭子会飞
鸭子不会叫
鸭子天生就会游泳
原则之一:
把应用中可能需要变化之处,把他们独立出来,不要和那些不需要变化的代码混在一起。
(把变化的部分取出来并封装起来,以便以后可以轻易的扩展此变化的部分,而不影响
不需要变化的其他部分,使得系统变的更有弹性)
原则之二:
针对接口编程,而不是针对实现编程
原则之三:
多用组合少用继承