策略模式

来源:互联网 发布:女士袜子淘宝网 编辑:程序博客网 时间:2024/05/22 10:27

需求:

要实现鸭子飞 叫 游泳等功能: (部分要着功能,部分不要该功能)

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();
    }
}


////////////////////////////////////////////////////////////////

鸭子会飞
鸭子不会叫
鸭子天生就会游泳

////////////////////////////////////////////////////////////////


原则之一:
把应用中可能需要变化之处,把他们独立出来,不要和那些不需要变化的代码混在一起。
(把变化的部分取出来并封装起来,以便以后可以轻易的扩展此变化的部分,而不影响
不需要变化的其他部分,使得系统变的更有弹性)


原则之二:
    针对接口编程,而不是针对实现编程
    
原则之三:
    多用组合少用继承