策略模式(Strategy Pattern):是指定义了算法家族、分别封装起来,让它们之间可以互 相替换,此模式让算法的变化不会影响到使用算法的用户。
策略模式的应用场景
1、假如系统中有很多类,而他们的区别仅仅在于他们的行为不同。
2、一个系统需要动态地在几种算法中选择一种。
3、选择支付方式
4、选择优惠方式
设计原则 | 简称 | 解释说明 | 备注 |
开闭原则 | (OCP)Open-Closed Principle, | 对扩展开放,对修改关闭。 | |
依赖倒置原则 | (DIP)Dependence Inversion Principle | 高层模块不应该依赖底层模块,二者都应该依赖其抽象。也就是说针对接口编程,不要针对实现编程,针对接口编程包括使用接口或抽象类,这样可以使得各个模块彼此独立,降低模块间的耦合性。而且在实现类中尽量不发生直接的依赖关系,依赖关系通过接口或抽象类产生。 | |
单一职责原则 | (SRP)Single Responsibility Principle | 一个类、接口、方法只做一件事。 | |
接口隔离原则 | (ISP)Interface Segregation Principle, | 尽量保证接口的纯洁性,客户端不应该依赖不需要的接口。胖接口会导致他们的客户程序之间产生不正常的并且有害的耦合关系.当一个客户程序要求该胖接口进行一个改动时,会影响到所有其他的客户程序.因此客户程序应该仅仅依赖他们实际需要调用的方法. | |
迪米特法则 | (LoD)Law of Demeter 又叫做最少知识原则(LKP)Least Knowledge Principle, | 又叫最少知道原则,一个类对其所依赖的类知道得越少越好。就是说,如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用,如果其中的一个类需要调用另一个类的某一个方法的话,可以通过第三者转发这个调用。 | |
里氏替换原则 | (LSP)Liskov Substitution Principle, | 子类可以扩展父类的功能但不能改变父类原有的功能。一般而言,如果有两个具体类A,B有继承关系,那么一个最简单的修改方案是建立一个抽象类C,然后让类A和B成为抽象类C的子类. | |
合成复用原则 | (CARP)Composite/Aggregate Reuse Principle, | 尽量使用对象组合、聚合,而不使用继承关系达到代码复用的目的。 |
上代码
//优惠策略接口
public interface YouHuiStrategy {
public void doYouHui();
}
public class EmptyStrategy implements YouHuiStrategy {
@Override
public void doYouHui() {
System.out.println("没有优惠");
}
}
public class FanXianStrategy implements YouHuiStrategy{
@Override
public void doYouHui() {
System.out.println("支付返现优惠");
}
}
public class ManJianStrategy implements YouHuiStrategy {
@Override
public void doYouHui() {
System.out.println("满减优惠");
}
}
public class PinTuanStrategy implements YouHuiStrategy {
@Override
public void doYouHui() {
System.out.println("拼团优惠");
}
}
package Srategy;
import java.util.HashMap;
import java.util.Map;
public class YouHuiStrategyFactory {
private static Map<String,YouHuiStrategy> youHuiStrategyMap = new HashMap<>();
static {
youHuiStrategyMap.put(YouHuiType.FanXian.getType(),new FanXianStrategy());
youHuiStrategyMap.put(YouHuiType.ManJian.getType(),new ManJianStrategy());
youHuiStrategyMap.put(YouHuiType.PinTuan.getType(),new PinTuanStrategy());
youHuiStrategyMap.put(YouHuiType.Empty.getType(),new EmptyStrategy());
}
private static final YouHuiStrategy NO_YOUHUI_STRATEGY = new EmptyStrategy();
private YouHuiStrategyFactory() { }
public static YouHuiStrategy getYouHuiStrategy(String youHuiType){
YouHuiStrategy youHuiStrategy = youHuiStrategyMap.get(youHuiType);
return youHuiStrategy == null ? NO_YOUHUI_STRATEGY : youHuiStrategy;
}
}
//促销活动
public class CuXiaoActivity {
private YouHuiStrategy youHuiStrategy;
public CuXiaoActivity(YouHuiStrategy youHuiStrategy) {
this.youHuiStrategy = youHuiStrategy;
}
public void execute(){
youHuiStrategy.doYouHui();
}
}
public enum YouHuiType {
FanXian("fanXian"),
PinTuan("pinTuan"),
ManJian("manJian"),
Empty("empty");
private String type;
YouHuiType(String type) {
this.type = type;
}
public String getType() {
return type;
}
}
策略模式的优缺点
优点:
1、策略模式符合开闭原则。
2、避免使用多重条件转移语句,如 if...else...语句、switch 语句
3、使用策略模式可以提高算法的保密性和安全性。
缺点:
1、客户端必须知道所有的策略,并且自行决定使用哪一个策略类。
2、代码中会产生非常多策略类,增加维护难度。