设计模式(3)策略模式

一.策略模式概述

针对一组算法,将每一个算法封装到具有共同接口的独立类中,从而使他们可以相互替换。
目的:使算法在不影响客户端的情况下发生改变

二. 策略模式角色

1.抽象策略角色(strategy):是一个抽象的角色,通常由一个接口或抽象类实现
2.具体策略角色(concreteStrategy):包装了相关的算法或行为
3.环境角色(context):持有一个stategy的引用。

三.策略模式例子

某商场推出会员模式,根据不同的历史消费记录分为普通用户,会员,超级会员,黄金会员,根据会员类型的不同,打折的力度也不同。

解决方案1:使用继承

使用继承可能是最容易想到的,就是在打折系统的服务端程序中实现各种打折方案,然后客户端继承服务端,作为子类去调用父类中的代码,从而实现了代码的复用。但要考虑到,这个系统可能不是为一个商场用的,不同的商场可能有不同的打折方案,这样客户端直接继承服务端的方案明显是不可行的

解决方案2:使用策略模式

由于不同商场可能有不同的打折方案,这样我们可以把不同的打折方案分离出来,独立成类,实现打折接口,客户端可以直接决定使用哪个策略完成支付,在Context类中提供一个计算最终价格的统一接口,客户端只需要调用这个Context类的计算最终结果的方法就可以实现功能

(1)策略接口

public interface CalPrice {
    //根据原价返回一个最终的价格
    Double calPrice(Double orgnicPrice);
}

(2)策略实现

public class Orgnic implements CalPrice {

    @Override
    public Double calPrice(Double orgnicPrice) {
        return orgnicPrice;
    }
}
public class Vip implements CalPrice {
    @Override
    public Double calPrice(Double orgnicPrice) {
        return orgnicPrice * 0.9;
    }
}
public class SuperVip implements CalPrice {
    @Override
    public Double calPrice(Double orgnicPrice) {
        return orgnicPrice * 0.8;
    }
}
public class GoldVip implements CalPrice {
    @Override
    public Double calPrice(Double orgnicPrice) {
        return orgnicPrice * 0.7;
    }
}

(3)环境

public class Price {
    //持有一个具体的策略对象
    private CalPrice calprice;
    
    //构造函数
    public Price(CalPrice calPrice){
        this.calPrice = calPrice;
    }

    //计算客户最终要付的钱
    public Double calLastAmount(amount) {
        return calPrice.calPrice(amount);
    }
}

(4)客户端

public class Client {
    public static void main(String[] args) {
   //1.客户端决定要使用的策略
    private Double totalAmount = 0D;//客户在消费的总额
    private Double amount = 0D;//客户单次消费金额
    private CalPrice stategy= new Orgnic();//默认初始为普通用户
     //客户购买,就会增加它的总额 并选出要使用的策略
    public void buy(Double amount) {
        this.amount = amount;
        totalAmount += amount;
        if (totalAmount > 30000) {//30000则改为金牌会员计算方式
            calPrice = new GoldVip();
        } else if (totalAmount > 20000) {//类似
            calPrice = new SuperVip();
        } else if (totalAmount > 10000) {//类似
            calPrice = new Vip();
        }
    }
    //2.创建环境
    Price price = new Price(stategy);
    //3.计算价格
    double quote = price. calLastAmount(300);
    
}

四.优缺点

优点:增强了可扩展性,提供了一个管理算法族的办法,新增加的算法并不会影响到其它的算法
缺点:客户端必须知道所有的策略类并且自行决定使用哪个策略类(可以使用工厂方法模式改进,传送:)

你可能感兴趣的:(设计模式,策略模式)