美文网首页
【Java设计模式】行为型模式-策略模式

【Java设计模式】行为型模式-策略模式

作者: 灰色孤星 | 来源:发表于2018-10-28 15:51 被阅读0次

源代码:https://gitee.com/AgentXiao/BehavioralPatterns
要点:
1、条件语句和策略模式的差异
2、策略模式的本质及实现

一、场景

某个的报价策略可以简单作如下分类:
• 普通客户小批量报价
• 普通客户大批量报价
• 老客户小批量报价
• 老客户大批量报价

具体选用哪个报价策略,这需要根据实际情况来确定。
我们可以使用一下机制实现:

public double getPrice(String type, double price){
        if(type.equals("普通客户小批量")){ 
            System.out.println("不打折,原价"); 
            return price; 
        }else if(type.equals("普通客户大批量")){ 
            System.out.println("打九折"); 
            return price*0.9; 
        }else if(type.equals("老客户小批量")){ 
            System.out.println("打八五折"); 
            return price*0.85; 
        }else if(type.equals("老客户大批量")){ 
            System.out.println("打八折"); 
            return price*0.8; 
        } return price;
    }

通过if-else if-else实现起来比较容易,符合开发人员的一般思路!但是当报价策略类型比较多,同时每个类型的报价方式比较复杂时,会导致整个条件控制语句非常地长,难以维护。

我们可以使用策略模式解决这个问题。

二、策略模式

策略模式对应于解决某一个问题的一个算法族,允许用户从该算法族中任选一个算法解决某一问题,同时可以方便的更换算法或者增加新的算法。并且由客户端决定调用哪个算法。

也就是说,策略模式将每一种报价规格封装为一个类,这个类只解决这一种报价算法,在需要使用时以引用的方式注入。这就很好的解决了条件语句难以维护的难题。同时需要增加新的策略时,只需要新增一个类。

1、算法族通过一个接口将所有的具体算法聚集在一起

/**
 * @interfaceName Strategy
 * @Description 策略算法族
 * @Author xwd
 * @Date 2018/10/28 15:23
 */
public interface Strategy {
    /**
     * @MethodName getPrice
     * @Descrition 价钱的计算方法
     * @Param [price]
     * @return double
     */
    double getPrice(double price);
}

2、具体的算法按照实际情况进行确定,统一实现算法族接口

/**
 * @ClassName NewCustomerFewStrategy
 * @Description 新客户小批量
 * @Author xwd
 * @Date 2018/10/28 15:25
 */
public class NewCustomerFewStrategy implements Strategy {
    @Override
    public double getPrice(double price) {
        System.out.println("新客户小批量:不打折!");
        return price;
    }
}
/**
 * @ClassName NewCustomerFewStrategy
 * @Description 新客户大批量
 * @Author xwd
 * @Date 2018/10/28 15:25
 */
public class NewCustomerManyStrategy implements Strategy {
    @Override
    public double getPrice(double price) {
        System.out.println("新客户大批量:95折!");
        return price*0.95;
    }
}
/**
 * @ClassName NewCustomerFewStrategy
 * @Description 老客户小批量
 * @Author xwd
 * @Date 2018/10/28 15:25
 */
public class OldCustomerFewStrategy implements Strategy {
    @Override
    public double getPrice(double price) {
        System.out.println("老客户小批量:9折!");
        return price*0.9;
    }
}
/**
 * @ClassName NewCustomerFewStrategy
 * @Description 老客户大批量
 * @Author xwd
 * @Date 2018/10/28 15:25
 */
public class OldCustomerManyStrategy implements Strategy {
    @Override
    public double getPrice(double price) {
        System.out.println("老客户大批量:85折!");
        return price*0.85;
    }
}

3、需要一个管理算法族的类,作为客户和算法族之间的中间人(就像超超市的售货员),它持有算法族的引用,因此客户只需要和该中间人打交道,实现了客户和算法之间的解耦

/**
 * @ClassName Boss
 * @Description 商店老板,管理报价策略
 * @Author xwd
 * @Date 2018/10/28 15:29
 */
public class Boss {

    private Strategy strategy;//持有报价策略的引用

    public Boss(Strategy strategy) {
        this.strategy = strategy;
    }

    /**
     * @MethodName getPrice
     * @Descrition 获得价格
     * @Param [price]
     * @return void
     */
    public void getPrice(double price){
        System.out.println("报价:"+this.strategy.getPrice(price));
    }
}

4、客户,找到持有算法引用的中间人

/**
 * @ClassName Client
 * @Description 客户
 * @Author xwd
 * @Date 2018/10/28 15:32
 */
public class Client {
    public static void main(String[] args) {
        Boss boss = new Boss(new OldCustomerFewStrategy());
        boss.getPrice(500);
    }
}

5、测试结果

测试结果

三、总结

1、本质

分离算法,选择实现。

2、开发中常见的场景:

1)JAVASE中GUI编程中,布局管理
布局管理中有多种布局方式,例如流布局、边界布局等,在使用时直接指定相应的布局方式即可。
2)Spring框架中,Resource接口,资源访问策略
3)javax.servlet.http.HttpServlet#service()

相关文章

网友评论

      本文标题:【Java设计模式】行为型模式-策略模式

      本文链接:https://www.haomeiwen.com/subject/ganptqtx.html