在简单工厂模式中,我们的客户端代码是这样的:
public class SimpleFactoryDemo { public static void main(String[] args) { if(args.length == 0){ System.out.println("Usage: java StrategyDemo operation num1 num2"); return; } Operation operation = OperationFactory.createOperation(args[0]); operation.setNumA(Double.parseDouble(args[1])); operation.setNumB(Double.parseDouble(args[2])); double result = operation.getResult(); System.out.println(result); } }
客户端需要知道Operation类,使用setNumA,setNumB,getResult方法,这其实让客户端与Operation类存在了某种耦合关系。
为了解除这种耦合关系,我们在简单工厂模式中结合了策略模式。
如果在一个系统里面有许多类,它们之间的区别仅在于它们的行为,那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为。
通俗的说,构造策略类时,我们传入一个对象,然后策略类调用这个对象的方法取得返回。这个对象可以是某个接口的任意子类,这样就让策略类拥有了根据对象来动态的决定方法的能力。
但是单纯的策略类有一大坏处,由于调用策略类需要先传入某个子类的对象,这就使得客户端代码与多个子类存在耦合。我们可以结合简单工厂模式使得客户端代码与多个子类代码解耦。
策略模式UML图实例:
请看代码,Operation及其子类:
public abstract class Operation { private double numA = 0; private double numB = 0; public double getNumA() { return numA; } public void setNumA(double numA) { this.numA = numA; } public double getNumB() { return numB; } public void setNumB(double numB) { this.numB = numB; } public abstract double getResult(); } public class OperationAdd extends Operation { @Override public double getResult() { return getNumA() + getNumB(); } } public class OperationSub extends Operation { @Override public double getResult() { // TODO Auto-generated method stub return getNumA() - getNumB(); } } public class OperationMul extends Operation { @Override public double getResult() { return getNumA() * getNumB(); } } public class OperationDiv extends Operation { @Override public double getResult() { // TODO Auto-generated method stub return getNumA() / getNumB(); } }
OperationContext类:
public class OperationContext { private Operation oper = null; public OperationContext(String operation) { switch (operation) { case "+": oper = new OperationAdd(); break; case "-": oper = new OperationSub(); break; case "*": oper = new OperationMul(); break; case "/": oper = new OperationDiv(); break; default: throw new IllegalArgumentException ("Unsupport operation!"); } } public double getResult(double numA, double numB) { oper.setNumA(numA); oper.setNumB(numB); return oper.getResult(); } }
客户端:
public class StrategyDemo { public static void main(String[] args) { if(args.length == 0){ System.out.println("Usage: java StrategyDemo operation num1 num2"); return; } OperationContext oc = new OperationContext(args[0]); double result = oc.getResult(Double.parseDouble(args[1]), Double.parseDouble(args[2])); System.out.println(result); } }