设计模式Java实现-策略模式

✨这里是第七人格的博客✨小七,欢迎您的到来~✨

🍅系列专栏:设计模式🍅

✈️本篇内容: 策略模式✈️

🍱本篇收录完整代码地址:gitee.com/diqirenge/d... 🍱

楔子

策略模式是一种行为型设计模式,其主要目标是根据运行时的需求选择对应的算法,而无需对客户端代码进行修改。这种模式将各种算法封装在抽象策略和具体策略类中,使得用户可以根据不同的需求选择具体的实现算法。例如,在一个支付系统中,可能会存在多种付款方式,如信用卡、借记卡和电子钱包等。在这种情况下,程序可以在运行时根据用户的选择来执行相应的支付操作。

策略模式的主要优点是提高了代码的复用性和可维护性,同时降低了系统的耦合度。通过使用策略模式,我们能够消除复杂的多重条件语句(说人话就是,可以使用策略类来消除大量的if-else)从而提高代码的可读性。然而,每个策略都需要一个单独的类,这可能会导致系统的类数量增加。

需求背景

我们现在有个活动,需要给用户发放福利,发放的福利可以是券、积分或者图文。现在让你来设计这个功能,你应该怎么设计呢?

分析设计

根据需求一把梭,我们可以创建一个名为Welfare的类,接着再创建一个枚举类型Type,用于表示福利的类型(券、积分或图文)。然后,我们可以在Welfare类中添加一个方法sendWelfare,该方法接受一个用户对象和一个福利类型作为参数,并根据福利类型执行相应的操作。这样虽然很快的完成了任务,但是对代码以后的拓展维护埋下了隐患。

所以我们尝试着优化它,首先,我们需要创建一个名为WelfareStrategy的接口,该接口包含一个名为sendWelfare的方法,用于发送福利。然后,我们可以为每种福利类型创建一个实现WelfareStrategy接口的具体策略类。接下来,我们需要创建一个名为WelfareContext的类,该类包含一个名为setStrategy的方法,用于设置当前的策略。在sendWelfare方法中,我们将调用当前策略的sendWelfare方法。

为了让客户端不用主动选择调用哪个策略,我们还可以创建一个名为WelfareFactory的工厂类,该类包含一个名为createWelfare的方法,用于创建不同类型的福利对象。然后,我们可以在WelfareContext类中使用WelfareFactory来创建福利对象。

UML图

根据分析设计,我们可以先画一个简单的UML图,后面通过UML图编码

模块名称

strategy

模块地址

gitee.com/diqirenge/d...

模块描述

策略模式代码示例

代码实现

一、代码一把梭

1、定义公共类

java 复制代码
/**
 * 定义福利类型枚举
 * 关注公众号【奔跑的码畜】,一起进步不迷路
 *
 * @author 第七人格
 * @date 2023/12/25
 */
public enum Type {
    COUPON, POINTS, IMAGE_TEXT
}
java 复制代码
/**
 * 用户类
 * 关注公众号【奔跑的码畜】,一起进步不迷路
 *
 * @author 第七人格
 * @date 2023/12/25
 */
public class User {
    private String name;

    public User(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}

2、编写福利类,并提供不同福利的发送方法

java 复制代码
/**
 * 根据需求一把梭
 * 关注公众号【奔跑的码畜】,一起进步不迷路
 *
 * @author 第七人格
 * @date 2023/12/25
 */
public class Welfare {

    // 发放福利的方法
    public void sendWelfare(User user, Type type) {
        switch (type) {
            case COUPON:
                sendCoupon(user);
                break;
            case POINTS:
                sendPoints(user);
                break;
            case IMAGE_TEXT:
                sendImageText(user);
                break;
            default:
                throw new IllegalArgumentException("Invalid welfare type");
        }
    }

    // 发放券的方法
    private void sendCoupon(User user) {
        // 在这里实现发放券的逻辑
        System.out.println("Sending coupon to " + user.getName());
    }

    // 发放积分的方法
    private void sendPoints(User user) {
        // 在这里实现发放积分的逻辑
        System.out.println("Sending points to " + user.getName());
    }

    // 发放图文的方法
    private void sendImageText(User user) {
        // 在这里实现发放图文的逻辑
        System.out.println("Sending image text to " + user.getName());
    }
}

3、编写测试类

java 复制代码
/**
 * 测试策略模式
 * 关注公众号【奔跑的码畜】,一起进步不迷路
 *
 * @author 第七人格
 * @date 2023/12/25
 */
public class StrategyTest {

    @Test
    public void testDemo01() {

        Welfare welfare = new Welfare();
        User user = new User("张三");

        welfare.sendWelfare(user, Type.COUPON);
        welfare.sendWelfare(user, Type.POINTS);
        welfare.sendWelfare(user, Type.IMAGE_TEXT);
    }

}

4、测试结果

Sending coupon to 张三

Sending points to 张三

Sending image text to 张三

二、使用策略模式优化代码

1、抽象福利策略接口

java 复制代码
/**
 * 策略模式 - 福利策略接口
 * 关注公众号【奔跑的码畜】,一起进步不迷路
 *
 * @author 第七人格
 * @date 2023/12/25
 */
public interface WelfareStrategy {
    void sendWelfare(User user);
}

2、编写具体实现类

java 复制代码
/**
 * 策略模式 - 发放券策略类
 * 关注公众号【奔跑的码畜】,一起进步不迷路
 *
 * @author 第七人格
 * @date 2023/12/25
 */
public class CouponStrategy implements WelfareStrategy {
    @Override
    public void sendWelfare(User user) {
        System.out.println("Sending coupon to " + user.getName());
    }
}
java 复制代码
/**
 * 策略模式 - 发放图文策略类
 * 关注公众号【奔跑的码畜】,一起进步不迷路
 *
 * @author 第七人格
 * @date 2023/12/25
 */
public class ImageTextStrategy implements WelfareStrategy {
    @Override
    public void sendWelfare(User user) {
        System.out.println("Sending image text to " + user.getName());
    }
}
java 复制代码
/**
 * 策略模式 - 发放积分策略类
 * 关注公众号【奔跑的码畜】,一起进步不迷路
 *
 * @author 第七人格
 * @date 2023/12/25
 */
public class PointsStrategy implements WelfareStrategy {
    @Override
    public void sendWelfare(User user) {
        System.out.println("Sending points to " + user.getName());
    }
}

3、编写福利类

java 复制代码
/**
 * 策略模式 - 福利上下文类
 * 关注公众号【奔跑的码畜】,一起进步不迷路
 *
 * @author 第七人格
 * @date 2023/12/25
 */
public class WelfareContext {
    private WelfareStrategy strategy;

    public void setStrategy(WelfareStrategy strategy) {
        this.strategy = strategy;
    }

    public void sendWelfare(User user) {
        strategy.sendWelfare(user);
    }
}

4、编写测试方法

java 复制代码
@Test
public void testDemo02() {

    com.run2code.design.behavioral.strategy.demo02.WelfareContext welfareContext = new com.run2code.design.behavioral.strategy.demo02.WelfareContext();
    User user = new User("李四");

    // 使用发放券策略
    welfareContext.setStrategy(new CouponStrategy());
    welfareContext.sendWelfare(user);

    // 使用发放积分策略
    welfareContext.setStrategy(new PointsStrategy());
    welfareContext.sendWelfare(user);

    // 使用发放图文策略
    welfareContext.setStrategy(new ImageTextStrategy());
    welfareContext.sendWelfare(user);
}

5、测试结果

Sending coupon to 李四

Sending points to 李四

Sending image text to 李四

三、使用工厂模式优化代码

1、通过工厂类,组织具体的创建策略的逻辑即可

java 复制代码
/**
 * 策略模式 - 福利工厂类
 * 关注公众号【奔跑的码畜】,一起进步不迷路
 *
 * @author 第七人格
 * @date 2023/12/25
 */
public class WelfareFactory {
    public static WelfareStrategy createWelfare(String type) {
        if (type == null) {
            return null;
        }
        if (type.equalsIgnoreCase("COUPON")) {
            return new CouponStrategy();
        } else if (type.equalsIgnoreCase("POINTS")) {
            return new PointsStrategy();
        } else if (type.equalsIgnoreCase("IMAGE_TEXT")) {
            return new ImageTextStrategy();
        }
        return null;
    }
}

2、编写测试方法

java 复制代码
@Test
public void testDemo03() {

    com.run2code.design.behavioral.strategy.demo03.WelfareContext welfareContext = new com.run2code.design.behavioral.strategy.demo03.WelfareContext();
    User user = new User("王五");

    // 使用工厂方法创建发放券策略对象
    WelfareStrategy couponStrategy = WelfareFactory.createWelfare(Type.COUPON.name());
    welfareContext.setStrategy(couponStrategy);
    welfareContext.sendWelfare(user);

    // 使用工厂方法创建发放积分策略对象
    WelfareStrategy pointsStrategy = WelfareFactory.createWelfare(Type.POINTS.name());
    welfareContext.setStrategy(pointsStrategy);
    welfareContext.sendWelfare(user);

    // 使用工厂方法创建发放图文策略对象
    WelfareStrategy imageTextStrategy = WelfareFactory.createWelfare(Type.IMAGE_TEXT.name());
    welfareContext.setStrategy(imageTextStrategy);
    welfareContext.sendWelfare(user);

}

3、测试结果

Sending coupon to 王五

Sending points to 王五

Sending image text to 王五

实现要点

策略模式实现要点如下:

1、定义一个公共接口或抽象类,声明所有支持的方法。例子中为:WelfareStrategy

2、创建一系列实现了该接口或继承了该抽象类的类,这些类就是具体的算法。例子中为:CouponStrategy、ImageTextStrategy、PointsStrategy

3、在客户端代码中使用上下文对象来调用具体算法。上下文对象负责将算法的具体实现委托给相应的具体算法类。例子中为:WelfareContext

总结

策略模式是一种行为设计模式,它定义了一系列算法,并将每个算法封装在一个具有共同接口的独立类中,使得它们可以相互替换。策略模式让算法的变化独立于使用它们的客户端。至于如何创建策略,我们一般可以考虑引入工厂模式等其他设计模式。为了抽象得更合理,还经常搭配模版模式使用,等后面讲到模版模式的时候再细说。

相关推荐
葫芦和十三6 小时前
图解 MongoDB 21|选举与 failover:Primary 是怎么选出来的
后端·mongodb·agent
GetcharZp7 小时前
26k Star 开源内网穿透神器 NetBird,一分钟实现全球设备互联!
后端
考虑考虑7 小时前
Mybatis实现批量插入
java·后端·mybatis
咖啡八杯8 小时前
GoF设计模式——中介者模式
java·后端·spring·设计模式
lizhongxuan10 小时前
多Agent之间的区别
后端
青石路12 小时前
记一次多JDK版本问题的排查,一坑套一坑,差点没爬上来
java
杨充13 小时前
1.面向对象设计思想
后端
IT_陈寒13 小时前
Java的Date类又坑了我一次,改用时间戳真香
前端·人工智能·后端
systemPro13 小时前
2.6亿条设备数据,历史查询从超时到50ms,我做了什么
后端
要阿尔卑斯吗14 小时前
提示词优化启示:为什么“按顺序输出“比“关键度评分“更有效
后端