策略 模式

策略模式

参考:

三种新姿势:帮你干掉过多的if-else (qq.com)

http://t.csdn.cn/5YeOZ

http://t.csdn.cn/HcGYw

JAVASE中GUI编程中,布局管理 ;
Spring框架中,Resource接口,资源访问;
javax.servlet.http.HttpServlet#service();
如果一个方法有大量if else语句,可通过策略模式来消除掉;
一个系统,需要动态地在几个算法中选择一种,可用策略模式实现;
系统有很多类,而他们的区别仅仅在于他们的行为不同

优点:

  • 开闭原则;
  • 避免使用多重条件转移语句;
  • 提高了算法的保密性和安全性:可使用策略模式以避免暴露复杂的,与算法相关的数据结构。

三种角色

  • 环境 (Context):持有一个策略类的引用,最终给客户端调用。
  • 抽象策略 (Strategy): 策略类,通常是一个接口或者抽象类。
  • 具体策略 (ConcreteStrategy):实现了策略类中的策略方法,封装相关的算法和行为。

在使用时,直接使用(环境)的类,通过不同状态类型,给他装配不同的实现的具体策略,以此来实现灵活装配

两个原则:

  1. 封装变化的概念。
  2. 编程中使用接口,而不是使用的是具体的实现类(面向接口编程)。

理解:

对一系列相似类型的算法逻辑进行接口封装,有调用者决定具体使用哪一套实现的逻辑算法;

针对接口编程,而不是针对实现编程,使用哪个接口的实现类就是具备这个实现类的特性

简单例子:

TreeSet进行比较时,需要指定Comparator接口类型,用户根据自己的规则升序还是降序,自定义实现接口来灵活控制

在这里插入图片描述

package com.ung.myBatisPlusTest.mode.policyMode;

/**
 * @author: wenyi
 * @create: 2022/8/30
 * @Description:
 */
public class TestStrategy {
    public static void main(String[] args) {
        String type = "普通客户小批量";
        double price = 100;
        //使用if else
//        price = getPrice(type, price);

        //使用策略模式
//        Context context = new Context();
//        context.setStrategy(new OldCustomerManyStrategy());
//        price = context.getPrice(price);

        //使用策略模式

        Context context = new Context();
        Strategy strategy = StrategyFactory.getInstance().getStrategy(type);
        context.setStrategy(strategy);
        price = context.getPrice(price);

        System.out.println(price);

    }

    /**
     * if else
     * 实现简单
     * 缺点明显,类型较多需要修改时,难以维护
     */
    public static 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;
    }
}
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;


/**
 * @author: wenyi
 * @create: 2022/8/30
 * @Description: 环境 用来装配使用策略接口
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Context {

    private Strategy strategy;

    public double getPrice(double price) {
        return strategy.getPrice(price);
    }
}
/**
 * @author: wenyi
 * @create: 2022/8/30
 * @Description: 策略类,通过不同实现类实现不同策略
 */
public interface Strategy {
    double getPrice(double price);
}
/**
 * @author: wenyi
 * @create: 2022/8/30
 * @Description:
 */
public class NewCustomerFewStrategy implements Strategy {
    @Override
    public double getPrice(double price) {
        System.out.println("不打折,原价");
        return price;
    }
}
/**
 * @author: wenyi
 * @create: 2022/8/30
 * @Description:
 */
public class NewCustomerManyStrategy implements Strategy {
    @Override
    public double getPrice( double price) {
        System.out.println("打九折");
        return price*0.9;
    }
}
package com.ung.myBatisPlusTest.mode.policyMode;

/**
 * @author: wenyi
 * @create: 2022/8/30
 * @Description:
 */
public class OldCustomerFewStrategy implements Strategy {
    @Override
    public double getPrice( double price) {
        System.out.println("打八五折");
        return price*0.85;
    }
}
package com.ung.myBatisPlusTest.mode.policyMode;

/**
 * @author: wenyi
 * @create: 2022/8/30
 * @Description:
 */
public class OldCustomerManyStrategy implements Strategy {
    @Override
    public double getPrice( double price) {
        System.out.println("打八折");
        return price*0.8;
    }
}

使用工厂+单例模式将选择权交给使用者

package com.ung.myBatisPlusTest.mode.policyMode;

import com.google.common.collect.ImmutableMap;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.security.PublicKey;
import java.util.Map;

/**
 * @author: wenyi
 * @create: 2022/8/30
 * @Description: 单例 工厂模式
 */
@Data
@NoArgsConstructor
public class StrategyFactory {
    private static Map<String, Strategy> map;

    /**
     * 维护一个map作为工厂模式
     */
    static {
        map = ImmutableMap.of(
                "普通客户小批量", new NewCustomerFewStrategy(),
                "普通客户大批量", new NewCustomerManyStrategy(),
                "老客户小批量", new OldCustomerFewStrategy(),
                "老客户大批量", new OldCustomerManyStrategy()
        );
    }

    public static class SingletonHolder {
        public static StrategyFactory strategyFactory = new StrategyFactory();
    }

    public static StrategyFactory getInstance() {
        return SingletonHolder.strategyFactory;
    }

    public Strategy getStrategy(String type) {
        return map.get(type);
    }
}

总结:

个人理解就是一个 操作类 Context ,里面有属性策略 Strategy接口

Strategy接口有不同的策略实现类,通过给Context 构造不同的Strategy实现类,来实现不同的策略使用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值