常用设计模式系列(十六)—策略模式

常用设计模式系列(十六)---策略模式

第一节

前言

hello各位好,小编由于最近上了年纪,总是感觉到自己困意频繁袭击,有一点低产,不能够达到一天一更的频率,但是后期可以使用两三天一更的频率,来保证文章的质量。最近小编身边也有许多朋友因为压力大而生病,大家应该注重身体健康,毕竟身体是革命的本钱,切勿劳累过度,伤身伤财。

今天我带大家唠唠对象行为型模式第一章节---策略模式, 策略一词,可以理解为,当我们去完成一个任务时,应对不同的场景、不同的困难,可以使用自己内心准备好的应急方案,提供这个方案的这个过程,就是策略模式。

第二节

策略模式

策略模式(Strategy Pattern)概念:定义一系列算法,并且将每个算法封装起来,并让他们可以互相替换,策略模式可以让算法独立于使用它的客户而变化。

策略模式组成:

个人理解:

当去完成或者达到一个目标时,这个目标就是我们的最终结果,实现这个目标的方案(抽像名词)就是抽像策略,不管用什么方案,我要的是这个结果,方案一、方案二不同的实现方式,称之为具体策略,我们在实现这个目标的过程中遇到的突发情况去选择不同的方案(自己选择方案,即客户端选择方案),选择好以后,根据方案去完成的这个过程,就可以理解为环境类。

场景举例:

我是小杨,前段时间公司安排我去北京出差,我看了下公司的报销政策,可以自行选择出差使用的交通工具,那这些交通方式都能够达到目的地,交通方式一词它就是抽象策略。而汽车、火车、高铁、飞机就是对应的具体策略。因为小编比较穷,但是又不想花费太多时间在路上,我就选择了高铁(毕竟飞机票买不起,汽车和火车又不想坐),我打开购票软件,选择高铁后,打车去高铁站的这个过程就是环境类,当我坐上高铁,抵达北京,整个结果达成,则整个策略模式结束。

第三节

案例举例及分析:

在生活中,坐公交、坐地铁是市民通行的几种常见方式,但是针对不同的人群,办理公交卡(使用现金无折扣),拥有着不同的优惠政策

1.学生卡享受8折优惠

2.老人卡享受5折优惠

3.市民卡享受85折优惠 如果后期加入不同的优惠政策,使用策略模式则可以设计并更好的扩展优惠政策。

根据分析,可以设计出如下几个类:

1.BusTikect刷卡机类,充当环境类,用来调用不同的折扣类。

2.Discount折扣类,充当抽象策略类。

3.StudentDiscount 学生卡折扣类,充当具体策略类

4.SeniorDiscount 老人卡折扣类,充当具体策略类

5.CitizenDiscount 市民卡折扣类,充当具体策略类

UML图

代码实现

1.BusTikect刷卡机类,充当环境类,用来调用不同的折扣类。

复制代码
package com.yang.strategy;


/**
 * @ClassName BusTikect
 * @Description 刷卡机类
 * @Author IT小白架构师之路
 * @Date 2021/1/22
 * @Version 1.0
 **/
public class BusTikect {
    //票价
    private double price;
    //折扣类型
    private Discount discount;
    //构造
    public BusTikect(double price,Discount discount){
        this.price = price;
        this.discount = discount;
    }
    //折扣计算
    public double getPrice(){
        return discount.caculate(this.price);
    }




}

2.Discount折扣类,充当抽象策略类。

复制代码
package com.yang.strategy;


/**
 * @ClassName Discount
 * @Description 折扣类
 * @Author IT小白架构师之路
 * @Date 2021/1/22
 * @Version 1.0
 **/
public interface Discount {
    /**
     * 计算折扣
     * @param price
     * @return
     */
    public double caculate(double price);
}

3.StudentDiscount 学生卡折扣类,充当具体策略类

复制代码
package com.yang.strategy;


/**
 * @ClassName StudentDiscount
 * @Description 学生折扣
 * @Author IT小白架构师之路
 * @Date 2021/1/22
 * @Version 1.0
 **/
public class StudentDiscount implements Discount{
    private final double DISCOUNT = 0.8;
    @Override
    public double caculate(double price) {
        System.out.println("学生卡:");
        return this.DISCOUNT * price;
    }
}

4.SeniorDiscount 老人卡折扣类,充当具体策略类

复制代码
package com.yang.strategy;


/**
 * @ClassName SeniorDiscount
 * @Description 老人卡折扣类
 * @Author IT小白架构师之路
 * @Date 2021/1/22
 * @Version 1.0
 **/
public class SeniorDiscount implements Discount{
    private final double DISCOUNT = 0.5;
    @Override
    public double caculate(double price) {
        System.out.println("老人卡:");
        return this.DISCOUNT * price;
    }
}

5.CitizenDiscount 市民卡折扣类,充当具体策略类

复制代码
package com.yang.strategy;


/**
 * @ClassName CitizenDiscount
 * @Description 市民卡折扣类
 * @Author IT小白架构师之路
 * @Date 2021/1/22
 * @Version 1.0
 **/
public class CitizenDiscount implements Discount{
    private final double DISCOUNT = 0.85;
    @Override
    public double caculate(double price) {
        System.out.println("市民卡:");
        return this.DISCOUNT * price;
    }
}

6.编写客户端测试

复制代码
package com.yang.strategy;


/**
 * @ClassName Client
 * @Description 注释
 * @Author IT小白架构师之路
 * @Date 2021/1/22
 * @Version 1.0
 **/
public class Client {
    public static void main(String[] args) {
        //长途公交价格
        double price = 5;


        System.out.println("-------------车来了,请按顺序刷卡上车,不要拥挤---------------");
        //学生卡
        Discount discount = new StudentDiscount();
        //刷卡机
        BusTikect busTikect = new BusTikect(price,discount);
        System.out.println("折扣前价格:"+price);
        //刷卡
        double priceNew = busTikect.getPrice();
        System.out.println("折扣后价格:"+priceNew);
        System.out.println("----------------------------");


        //老人卡
        discount = new SeniorDiscount();
        //刷卡机
        busTikect = new BusTikect(price,discount);
        System.out.println("折扣前价格:"+price);
        //刷卡
        priceNew = busTikect.getPrice();
        System.out.println("折扣后价格:"+priceNew);
        System.out.println("----------------------------");




        //市民卡
        discount = new CitizenDiscount();
        //刷卡机
        busTikect = new BusTikect(price,discount);
        System.out.println("折扣前价格:"+price);
        //刷卡
        priceNew = busTikect.getPrice();
        System.out.println("折扣后价格:"+priceNew);
        System.out.println("------------车开了,请不要扶靠车门,谨防夹伤----------------");


    }
}

7.测试结果如下

复制代码
-------------车来了,请按顺序刷卡上车,不要拥挤---------------
折扣前价格:5.0
学生卡:折扣后价格:4.0
----------------------------
折扣前价格:5.0
老人卡:折扣后价格:2.5
----------------------------
折扣前价格:5.0
市民卡:折扣后价格:4.25
------------车开了,请不要扶靠车门,谨防夹伤----------------

第四节

策略模式与工厂模式的区别

当看到策略模式的组成时,大家可能会想,这不就是工厂模式吗,但是这是两个不同的模式,只是结构上很相似

1.用途不一样

(1)工厂是创建型模式,它的作用就是创建对象;

(2)策略是行为型模式,它的作用是让一个对象在许多行为中选择一种行为;

2.关注点不一样

(1)一个关注对象创建过程

(2)一个关注行为的封装

3.解决不同的问题

(1)工厂模式是创建型的设计模式,它接受指令,创建出符合要求的实例;它主要解决的是资源的统一分发,将对象的创建完全独立出来,让对象的创建和具体的使用客户无关。主要应用在多数据库选择,类库文件加载等。

(2)策略模式是为了解决的是策略的切换与扩展,更简洁的说是定义策略族,分别封装起来,让他们之间可以相互替换,策略模式让策略的变化独立于使用策略的客户。

4.工厂相当于黑盒子,策略相当于白盒子。

举例说明

有一天晚上,你跟你的室友特别想吃麻辣拌,你到附近饭店,跟老板说要一份麻辣拌,你也不关注这个过程,老板做好吃就成了,用户不需要关心过程得到麻辣拌,这就是工厂模式。

但是你的室友说,我喜欢按照自己的比例去做,然后他按照自己的要求,多加肉块,多要辣椒,土豆煮的脆一点等等要求,他关注的是这个过程,最后吃到了麻辣拌,这个过程就是策略模式,它关注过程,自主选择过程来得到结果。

第五节

优缺点及适用场景

优点

1.策略模式可以在不修改原有系统源码的基础选择新的算法或者行为,可以灵活的增加新的算法或者行为

2.策略模式解决了继承模式下:每个子类提供不同的算法,此时算法的使用和算法的声明放在了一起,此时解决了不符合单一职责的情况

3.使用策略模式可以减少多重条件选择,更易维护

4.策略模式抽象出来的代码放在了策略类中,不同的环境类都可以复用这些策略类。

缺点

1.客户端需要知道全部有多少种策略类,来去选择,对客户端的要求高一点。

2.策略模式会造成系统产生很多的具体策略类,当需求变化就要增加新的具体策略类

3.无法同时使用多个策略类,每次只能使用一个策略类,而无法使用两个策略类共同完成

适用场景

1.一个系统需要设计几种算法供开发者选择时,可以封装到一个个的具体策略类中,在某段程序使用时,使用统一的接口调用即可。

2.当系统中使用了多重条件选择语句时,代码可使用策略类进行优化,把行为转移到对应的具体策略类。

3.不希望使用方知道复杂的、与算法相关的数据结构式,在具体策略类封装相关的数据结构,提高算法的保密性和安全性。

扫描二维码

关注我吧

IT小白架构师之路

相关推荐
奈斯。zs7 小时前
java面向对象高级02——单例类(设计模式)
java·开发语言·设计模式
困鲲鲲7 小时前
设计模式:命令模式 Command
设计模式·命令模式
找不到、了10 小时前
Java设计模式之《备忘录模式》
设计模式·备忘录模式
困鲲鲲12 小时前
设计模式:责任链模式 Chain of Responsibility
设计模式·责任链模式
LoveC52113 小时前
设计模式之外观模式
设计模式·外观模式
星眠13 小时前
手写发布订阅设计模式
javascript·设计模式·面试
看星星的小王子13 小时前
Linux基础(三)——Bash基础
linux·运维·bash
源代码•宸14 小时前
深入浅出设计模式——创建型模式之单例模式 Singleton
开发语言·c++·经验分享·单例模式·设计模式
未既14 小时前
java设计模式 -【责任链模式】
java·设计模式·责任链模式