设计模式-策略模式

1.介绍:
1)策略模式(Strategy Pattern)中,定义算法族(策略组),分别封装起来,让他们之间可以相互替换,此模式让算法的变化独立于使用算法的客户。比如下文中出现的野鸭是使用算法的客服,实现会飞接口的类组是算法组,在野鸭类中可以使用、替换算法组中某个类。

2)这个算法体现了几个设计原则,第一把变化的代码从不变的代码中分离出来;第二针对接口编程而不是具体类(定义了策略接口);第三多用组合/聚合,少用继承(客服通过组合方式使用策略)

2.原理类图
在这里插入图片描述
3.策略模式的注意事项和细节
  策略模式的关键是:分析项目中变化部分与不变部分
  策略模式的核心思想是:多用组合/聚合 少用继承;用行为类组合,而不是行为的继承。更有弹性。
  体现了“对修改关闭,对拓展开放”原则,客服端增加行为不用修改原有代码,只要添加一种策略模式(或者行为)即可,避免了使用多重转移语句(if…else if …else)
  需要注意的是:每添加一个策略就要增加一个类,当策略过多是会导致类数目庞大的

4.代码的实现
当使用继承的时候的时候:会出现的问题
鸭子类的父类

public abstract class Duck {
    //鸭子的信息描述
    public abstract void display();

    public void quack(){
        System.out.println("鸭子嘎嘎叫~~~");
    }

    public void swim(){
        System.out.println("鸭子会游泳~~~");
    }

    /**
     * 因为并不是所有的鸭子都会飞,这样继承了这个鸭子类的子类就要重写了这个方法
     */
    public void fly(){
        System.out.println("鸭子会飞~~~");
    }
}

野鸭

public class WildDuck extends Duck{
    @Override
    public void display() {
        System.out.println("这个一个野鸭");
    }
}

北京鸭

public class PekingDuck extends Duck{
    @Override
    public void display() {
        System.out.println("这个一个北京鸭");
    }
    @Override
    public void fly() {
        System.out.println("飞行的很糟糕");
    }
}

玩具鸭,因为玩具鸭不会飞,但是也继承了父类方法,所以需要重写

public class ToyDuck extends Duck{
    @Override
    public void display() {
        System.out.println("这个一个玩具鸭");
    }

    /**
     * 因为玩具鸭不会飞所以需要重写
     */
    @Override
    public void fly() {
        System.out.println("玩具鸭不会飞");
    }
}

从上面的代码中可以看出来,如果是通过继承来写,则不要父类中的方法时候,就显得多余了。加上如果需要额外加上鸭子吃的食物是什么的时候,这样又要修改父类里面的方法,每个子类的方法也要修改了。
如果是用策略模式是怎样的呢:
fly的策略接口

/**
 * 鸭子飞行为的接口,算法组的接口
 */
public interface FlyInf {
    public void fly();
}

fly实现类接口,fly的各种表现

//飞行好的行为
public class GoodFly implements FlyInf {
    @Override
    public void fly() {
        System.out.println("飞行的很棒");
    }
}

//飞行一般的行为
public class BadFly implements FlyInf {
    @Override
    public void fly() {
        System.out.println("飞行的很糟糕");
    }
}

//不会飞行的行为
public class NoFly implements FlyInf {
    @Override
    public void fly() {
        System.out.println("不能飞行");
    }
}

将策略接口组合到使用者的身上
修改后的duck类

public abstract class Duck {
    
    FlyInf flyInf;
    
    //鸭子的信息描述
    public abstract void display();

    public void quack(){
        System.out.println("鸭子嘎嘎叫~~~");
    }
    
    public void swim(){
        System.out.println("鸭子会游泳~~~");
    }

    /**
     * 通过接口调用方法
     */
     public void fly(){
        if (this.flyInf != null) {
            flyInf.fly();
        }
    }
    
     /**
     * 修改策略
     * @param flyInf
     */
    public void setFlyInf(FlyInf flyInf) {
        this.flyInf = flyInf;
    }
    
}

修改后的野鸭类

public class WildDuck extends Duck{
    
    //将策略组合到使用者上
    public WildDuck(){
        this.flyInf = new GoodFly();
    }
    @Override
    public void display() {
        System.out.println("这个一个野鸭");
    }
}

修改后的北京鸭类

public class PekingDuck extends Duck{
    
    public PekingDuck(){
        this.flyInf = new BadFly();
    }
    
    @Override
    public void display() {
        System.out.println("这个一个北京鸭");
    }
    
}

修改后的玩具鸭类

public class ToyDuck extends Duck{

    public ToyDuck(){
        this.flyInf = new NoFly();
    }

    @Override
    public void display() {
        System.out.println("这个一个玩具鸭");
    }

}

主类

public class TestStrategy {
    public static void main(String[] args) {
        WildDuck wildDuck = new WildDuck();
        wildDuck.fly();
        
        PekingDuck pekingDuck = new PekingDuck();
        pekingDuck.fly();
        
        ToyDuck toyDuck = new ToyDuck();
        toyDuck.fly();

        //改变了策略中的某个飞行行为
        toyDuck.setFlyInf(new GoodFly());
        System.out.println("玩具鸭被装上了翅膀可以飞了");
        toyDuck.fly();
    }
}

输出
在这里插入图片描述
策略模式在JDK中的使用:

public class TestStrategy2 {
    public static void main(String[] args) {
        Integer[] a = {1,8,2,3,7,6};
        //comparator是一个策略接口,实现自定义的策略
        Comparator comparator =  new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                if (o1 > o2){
                    return 1;
                }else {
                    return -1;
                }
            }
        };
        
        Arrays.sort(a, comparator);
        System.out.println(Arrays.toString(a));
    }
}

总结:策略模式,是将行为独立成为模块,需要的时候去拿自己对应行为的实现类就可以了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值