JAVA设计模式:策略模式

策略模式

策略模式是行为模式之一,它对一系列的算法加以封装,为所有算法定义一个抽象的算法接口,并通过继承该抽象算法接口对所有的算法加以封装和实现,具体的算法选择交由客户端决定。该模式主要用来平滑地处理算法的切换。

一、结构

strategy包含一个算法接口,具体的实现交给子类ConcreteStrategy A与B,例如算法接口为加密,则A可以为对称加密算法,B为非对称加密算法,通过Context调用这些算法,因为Context里面有strategy对象,则对算法持有引用,而operation则具体的调用A或者B的方法

在这里插入图片描述

二、代码示例
2.1 Strategy
public interface Strategy {
    //加密方法
    public void encrypt();
}
2.2 ConcreteStrategyA
public class ConcreteStrategyA implements Strategy {
    @Override
    public void encrypt() {
        System.out.println("执行对称加密");
    }
}
2.3 ConcreteStrategyB
public class ConcreteStrategyB implements Strategy {
    @Override
    public void encrypt() {
        System.out.println("执行非对称加密");
    }
}
2.4 Context
public class Context {
    private Strategy strategy;
    //构造方法
    public Context (Strategy strategy){
        this.strategy = strategy;
    }
    //加密方法
    public void encrypt(){
        this.strategy.encrypt();
    }
}
2.5 MainClass
public class MainClass {
    public static void main(String[] args){
        //未使用策略模式时的代码
        //如果需要使用非对称加密的时,客户端需要将new的对象就换成ConcreteStrategyB
        Strategy strategy = new ConcreteStrategyA();
        strategy.encrypt();

        //使用策略模式的代码,客户通过调用Context来进行加密
        //但真正决定算法的为Context里面new的对象
        Context context = new Context(new ConcreteStrategyA());
        context.encrypt();
    }
}

三、策略模式的角色和职责
  • Strategy:策略(算法)抽象
  • ConcreteStrategy:各种策略(算法)的具体实现
  • Context:策略的外部封装类,或者时策略的容器类,根据不同策略执行不同的行为,策略由外部环境决定。

四、商家促销例子,使用策略模式
4.1 Strategy
public interface Strategy {
    public double cost(double costbefore);
}
4.2 ConcreteStrategyA
public class ConcreteStrategyA implements Strategy {
    //策略一:打八折
    @Override
    public double cost(double costbefore) {
        return costbefore * 0.8;
    }
}
4.3 ConcreteStrategyB
public class ConcreteStrategyB implements Strategy {
    //策略:满100减30
    @Override
    public double cost(double costbefore) {
        return costbefore>=100? costbefore-30:costbefore;
    }
}
4.4 Context
public class Context {
    private Strategy strategy;
    public Context(Strategy strategy){
        super();
        this.strategy = strategy;
    }
    public double cost(double cost){
        return this.strategy.cost(cost);
    }
}
4.5 Main
public class MainClass {
    public static void main(String[] args) {
        double realCost = 200;
        Context context = new Context(new ConcreteStrategyA());
        //或者是:Context context = new Context(new ConcreteStrategyB());
        realCost = context.cost(realCost);
        System.out.println("实际付款: "+ realCost);
    }
}

五、优点与缺点
5.1 优先
  • 提供了相关的算法族的办法,策略类的等级结构定义了一个算法或行为族,恰当使用继承可以把公共的代码移动到父类里面,从而避免重复的代码,例如当ConcreteStrategyA与ConcreteStrategyB有相同代码的时候,可以将其放到父类Strategy
  • 策略模式提供了可以替代继承关系的办法,继承可以处理多种算法或行为,如果不使用策略模式,那么使用算法或行为的环境类就可能会有一些子类,每一个子类提供一个不同的算法或行为,例如在Main函数中,创建A与B的时候都会需要用A类创建对象,B类创建对象,而策略模式只需要Context里面new的对象修改即可
  • 使用策略模式可以避免使用多重条件转移语句,多重转移语句不易维护
5.2 缺点
  • 客户端必须知道所有的策略类,并自行决定使用哪一个策略类,意味着客户端必须理解这些算法的区别
    Main函数中,创建A与B的时候都会需要用A类创建对象,B类创建对象,而策略模式只需要Context里面new的对象修改即可
  • 使用策略模式可以避免使用多重条件转移语句,多重转移语句不易维护
5.2 缺点
  • 客户端必须知道所有的策略类,并自行决定使用哪一个策略类,意味着客户端必须理解这些算法的区别
  • 策略模式造成很多策略类,有时候可以通过把依赖于环境的状态保存在客户端里面,而将策略类设计诚可共享的,实例便可以被不同客户端使用,例如商品打折Main中的代码可以让多个商家一起使用,即使用享元模式来减少对象的数据
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值