20 行为型模式-策略模式

1 策略模式概述

策略模式(strategy pattern)的原始定义是:定义一系列算法,将每一个算法封装起来,并使它们可以相互替换。策略模式让算法可以独立于使用它的客户端而变化。
在这里插入图片描述
在这里插入图片描述

2 策略模式原理

在这里插入图片描述

3 策略模式实现

策略模式的本质是通过Context类来作为中心控制单元,对不同的策略进行调度分配。

//抽象策略类
public interface Strategy {
	void algorithm();
}
/**
 * 具体策略类
 **/
public class ConcreteStrategyA implements Strategy {

    @Override
    public void algorithm() {
        System.out.println("执行策略A");
    }
}
public class ConcreteStrategyB implements Strategy {

    @Override
    public void algorithm() {
        System.out.println("执行策略B");
    }
}
/**
 * 上下文类: 策略模式的本质就是通过Context类作为控制单元,
 * 对不同的策略进行调度分配
 **/
public class Context {

    //维持一个抽象策略的引用
    private Strategy strategy;

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

    //调用策略类中的算法
    public void algorithm(){
        strategy.algorithm();
    }
}
public class Client {

    public static void main(String[] args) {

        Strategy strategyB= new ConcreteStrategyB();
        Context context = new Context(strategyB);

        context.algorithm();
    }
}

在这里插入图片描述

1 ) 不使用设计模式
/**
 * 回执信息
 **/
public class Receipt {

    private String message; //回执内容
    private String type; //回执类型: MT1101、MT2101、MT4101、MT8104

    public Receipt() {
    }

    public Receipt(String message, String type) {
        this.message = message;
        this.type = type;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }
}
/**
 * 回执信息
 **/
public class Receipt {

    private String message; //回执内容
    private String type; //回执类型: MT1101、MT2101、MT4101、MT8104

    public Receipt() {
    }

    public Receipt(String message, String type) {
        this.message = message;
        this.type = type;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }
}
public class Client {

    public static void main(String[] args) {

        List<Receipt> receiptList = ReceiptBuilder.getReceiptList();

        //回执类型: MT1101、MT2101、MT4101、MT8104
        for (Receipt receipt : receiptList) {
            if("MT1011".equals(receipt.getType())){
                System.out.println("接收到MT1011的回执信息");
                System.out.println("解析回执内容");
                System.out.println("执行业务逻辑A......");
            }else if("MT2101".equals(receipt.getType())){
                System.out.println("接收到MT2101的回执信息");
                System.out.println("解析回执内容");
                System.out.println("执行业务逻辑B......");
            }else if("MT4101".equals(receipt.getType())){
                System.out.println("接收到MT4101的回执信息");
                System.out.println("解析回执内容");
                System.out.println("执行业务逻辑C......");
            }else if("MT8104".equals(receipt.getType())){
                System.out.println("接收到MT8104的回执信息");
                System.out.println("解析回执内容");
                System.out.println("执行业务逻辑D......");
            }
            //.........
        }
    }
}
2 ) 使用策略模式进行优化

通过策略模式, 将所有的if-else分支的业务逻辑抽取为各种策略类,让客户端去依
赖策略接口,保证具体策略类的改变不影响客户端.

/**
 * 回执处理策略接口
 **/
public interface ReceiptHandleStrategy {
    void handleReceipt(Receipt receipt);
}

具体策略类

/**
 * 具体策略类
 **/
public class MT1101ReceiptHandleStrategy implements ReceiptHandleStrategy {

    @Override
    public void handleReceipt(Receipt receipt) {
        System.out.println("解析报文MT1101: " + receipt.getMessage());
    }
}
public class MT2101ReceiptHandleStrategy implements ReceiptHandleStrategy {

    @Override
    public void handleReceipt(Receipt receipt) {
        System.out.println("解析报文 MT2101: " + receipt.getMessage());
    }
}

策略上下文类(策略接口的持有者)

/**
 * 上下文类, 持有策略接口,决定执行哪一个具体的策略类
 **/
public class ReceiptStrategyContext {

    private ReceiptHandleStrategy receiptHandleStrategy;

    public void setReceiptHandleStrategy(ReceiptHandleStrategy receiptHandleStrategy) {
        this.receiptHandleStrategy = receiptHandleStrategy;
    }

    //调用策略类中方法
    public void handleReceipt(Receipt receipt){
        if(receipt != null){
            receiptHandleStrategy.handleReceipt(receipt);
        }
    }
}

策略工厂

/**
 * 策略工厂类
 **/
public class ReceiptHandleStrategyFactory {

    public ReceiptHandleStrategyFactory() {
    }

    //使用Map集合存储策略信息,彻底的消除if...else
    private static Map<String,ReceiptHandleStrategy> strategyMap;

    //初始化具体策略,保存到map集合
    public static void init(){
        strategyMap = new HashMap<>();
//        strategyMap.put("MT1101",new MT1101ReceiptHandleStrategy());
//        strategyMap.put("MT2101",new MT2101ReceiptHandleStrategy());
        try {
            SAXReader reader = new SAXReader();
            String file = "I:\\MSB\\msb_work\\designpattern\\msb-strategy-pattern-14\\src\\main\\resources\\config.xml";

            Document document = reader.read(file);
            Node node = document.selectSingleNode("/confing/className");
            String className = node.getText();
            Class clazz = Class.forName(className);
            ReceiptHandleStrategy strategy = (ReceiptHandleStrategy) clazz.newInstance();
            strategyMap.put("MT1101",strategy);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //根据回执类型,获取对应的策略对象
    public static ReceiptHandleStrategy getStrategy(String receiptType){
        return strategyMap.get(receiptType);
    }
}
public class Client {

    public static void main(String[] args) {

        //模拟回执
        List<Receipt> receiptList = ReceiptBuilder.getReceiptList();

        //策略上下文
        ReceiptStrategyContext context = new ReceiptStrategyContext();

        //策略模式最主要的工作: 将策略的 定义, 创建, 使用这三部分进行了解耦.
        for (Receipt receipt : receiptList) {
            //获取策略
            ReceiptHandleStrategyFactory.init();
            ReceiptHandleStrategy strategy = ReceiptHandleStrategyFactory.getStrategy(receipt.getType());
            //设置策略
            context.setReceiptHandleStrategy(strategy);
            //执行策略
            context.handleReceipt(receipt);
        }

    }
}

经过上面的改造,我们已经消除了if-else的结构,每当新来了一种回执,只需
要添加新的回执处理策略,并修改ReceiptHandleStrategyFactory中的Map
集合。如果要使得程序符合开闭原则,则需要调整ReceiptHandleStrategyFactory中处理策略的获取方式,通过反射的方式,获取指定包下的所IReceiptHandleStrategy实现类,然后放到字典Map中去.

5 策略模式总结

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
校园悬赏任务平台对字典管理、论坛管理、任务资讯任务资讯公告管理、接取用户管理、任务管理、任务咨询管理、任务收藏管理、任务评价管理、任务订单管理、发布用户管理、管理员管理等进行集中化处理。经过前面自己查阅的网络知识,加上自己在学校课堂上学习的知识,决定开发系统选择小程序模式这种高效率的模式完成系统功能开发。这种模式让操作员基于浏览器的方式进行网站访问,采用的主流的Java语言这种面向对象的语言进行校园悬赏任务平台程序的开发,在数据库的选择上面,选择功能强大的Mysql数据库进行数据的存放操作。校园悬赏任务平台的开发让用户查看任务信息变得容易,让管理员高效管理任务信息。 校园悬赏任务平台具有管理员角色,用户角色,这几个操作权限。 校园悬赏任务平台针对管理员设置的功能有:添加并管理各种类信息,管理用户账户信息,管理任务信息,管理任务资讯公告信息等内容。 校园悬赏任务平台针对用户设置的功能有:查看并修改个人信息,查看任务信息,查看任务资讯公告信息等内容。 系统登录功能是程序必不可少的功能,在登录页面必填的数据有两项,一项就是账号,另一项数据就是密码,当管理员正确填写并提交这二者数据之后,管理员就可以进入系统后台功能操作区。项目管理页面提供的功能操作有:查看任务,删除任务操作,新增任务操作,修改任务操作。任务资讯公告信息管理页面提供的功能操作有:新增任务资讯公告,修改任务资讯公告,删除任务资讯公告操作。任务资讯公告类管理页面显示所有任务资讯公告类,在此页面既可以让管理员添加新的任务资讯公告信息类,也能对已有的任务资讯公告类信息执行编辑更新,失效的任务资讯公告类信息也能让管理员快速删除。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值