混合模式(工厂方法模式+策略模式+门面模式)

混合模式(工厂方法模式+策略模式+门面模式)

  使用这三种模式设计一个简单的计算器程序:计算器是用于计算数值之间进行数学计算后所获得的值。它包含基本的"加减"功能。以上对以上需求进行分析可以得出计算有两种策略(+与-)。

计算策略的实现:

/*抽象策略*/
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接口,都不用枚举了,这样更灵活。

你可能感兴趣的:(混合模式)