使用这三种模式设计一个简单的计算器程序:计算器是用于计算数值之间进行数学计算后所获得的值。它包含基本的"加减"功能。以上对以上需求进行分析可以得出计算有两种策略(+与-)。
计算策略的实现:
/*抽象策略*/public interface Strategy{ /*定义了计算策略所拥有的算法*/ public int calculate(int a,int b);}
/*加法策略的实现*/public class AddStrategy implements Strategy{ @Override public int calculate(int a, int b) { return a+b; }} /*减法策略的实现*/public class SubStrategy implements Strategy{ @Override public int calculate(int a, int b) { return a-b; }}
此时还需要一个封装策略的对象,让策略可以互换:
public class StrategyContext{ /*封装了策略对象*/ private Strategy strategy = null; public StrategyContext(Strategy strategy) { this.strategy = strategy; } /*实现了策略可以互换的功能*/ public void setStrategy(Strategy strategy) { this.strategy = strategy; } public int execute(int a,int b) { return this.strategy.calculate(a, b); }}
为了避免策略模式必须要将具体的策略暴露给高层模块的缺点,我们使用工厂来生成策略,现在高层模块只需要一个约束条件就可以获得需要的策略。
策略生成工厂的实现:
/*策略生成抽象工厂*/public interface Factory{ /*定义一个生成策略的接口,其参数还可以使用一个配置文件来实现约束条件,这里使用了枚举*/ public Strategy createStrategy(StrategyEnum strategyEnum);}
public class StrategyFactory implements Factory{ @Override public Strategy createStrategy(StrategyEnum strategyEnum) { Strategy strategy = null; try { String strategyName = strategyEnum.getStrategyName(); Class<?> clazz = Class.forName(strategyName); strategy = (Strategy)clazz.newInstance(); } catch (Exception e) { e.printStackTrace(); } return strategy; }}
每次进行计算的步骤为:获取工厂、获取策略、封装策略、计算结果。这样写比较麻烦,高层模块为了计算一个结果还需要记住执行顺序,这时候我们可以使用门面模式来屏蔽子系统的复杂性,为高层模块提供一个计算接口即可。
计算机器门面的实现:
public class FacadeContext{ /*门面模式不参与子系统的逻辑,所以对子系统进行了一次封装*/ private Factory factory = new StrategyFactory(); private StrategyContext context = new StrategyContext(null); public FacadeContext(){} public int calculate(int a,int b,StrategyEnum strategy) { this.context.setStrategy(this.factory.createStrategy(strategy)); return this.context.execute(a, b); }}
/*计算器的门面,简单的委托类,为高层提供一个反问子系统的接口,让高层模块不再依赖子系统*/public class CalculatorFacade{ private FacadeContext context = new FacadeContext(); public CalculatorFacade() {} public int calculate(int a,int b,StrategyEnum strategy) { return this.context.calculate(a, b, strategy); }}
来看看场景类:
public class Client{ public static void main(String[] args) { /*获取门面,使用其提供的接口访问子系统*/ CalculatorFacade calculatorFacade = new CalculatorFacade(); System.out.println("2+2="+calculatorFacade.calculate(2, 2, StrategyEnum.ADD)); }}
附:StrategyEnum枚举代码:
public enum StrategyEnum{ ADD("com.suxiaolei.calculator.strategy.AddStrategy"), SUB("com.suxiaolei.calculator.strategy.SubStrategy"); private String strategyName; private StrategyEnum(String strategyName) { this.strategyName = strategyName; } public String getStrategyName() { return this.strategyName; }}
以上是混合使用三种模式的一个简单例子,可以看出灵活搭配模式能让系统更健壮,灵活性更高,扩展性更强。在上述例子添加策略非常非常的容易,只需要继承Strategy接口即可,然后在枚举中增加对应的策略类名即可,高层代码一点也不用改变。其实要是使用配置文件的方式,则只需要继承Strategy接口,都不用枚举了,这样更灵活。
时间: 2024-12-17 18:04:16