在簡單工廠模式中,我們的客戶端代碼是這樣的:
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); } }