Strategy Pattern
舉個例子,今天我寫了一個壓縮軟體,這個軟體會針對不同的輸入來採用不同的壓縮方法處理。
最基本的架構就是
然後該 compress function 可能長這樣
public Object compress(Object input){
//Part 1
if(input.type == TYPE1){
// do something
}
else if (input.type == TYPE2){
// do something
}
else if (input.type == TYPE3){
// do something
}
//Part 2
if(input.getEncoding() == TYPEA){
// do something
}
else if(input.getEncoding() ==TYPEB){
// do something
}
else if(input.getEncoding() ==TYPEC || input.getEncoding() ==TYPED){
// do something
}
}
這種程式架構再維護上過於麻煩,會有下列問題
- 程式碼冗長
- 演算法邏輯部分難懂
- 維護困難
如果今天選項夠多(part更多)的話,整個程式會變得很難處理,每次要增加一個新的算法,就要到很多地方去增加對應的code, 在處理上容易出錯且維護也不易。
使用 Stragegy pattern的話,架構如下
設計ㄧ個介面Algorithm, 然後每個算法都實現這個介面,自己去完成自己的算法邏輯
當程式要處理壓縮的時候,就根據輸入物件來產生與之對應的演算法物件,然後去處理。
這樣每個算法都獨立來看,邏輯清楚明瞭,而且要新增加ㄧ個算法的話,只要再寫一個新的物件實現自共同的介面即可。
public class CompressProgram{
public void process(){
//do something
Algorithm algorithm = getAlgorithmByType(input);
Compressor compressor = new COmpressor();
Object result = compressor.doCompress(input,algorithm);
}
private Algorithm getAlgorithmByType(Object input){
if(input.type ==TYPEA){
return new AlgorithmA();
}
else if(input.type ==TYPEB){
return new AlgorithmB();
}
else if(input.type ==TYPEC){
return new AlgorithmC();
}
}
}
public class Compressor{
public Object doCompress(Object input,Algorithm algorithm){
//do something
return algorithm.compress(input);
}
}
public abstrace class Algorithm{
abstract public Object compress(Object input);
}
public class AlgorithmA extends Algorithm{
public Object compress(Object input){
// do something for TypeA
}
}
public class AlgorithmB extends Algorithm{
public Object compress(Object input){
// do something for TypeB
}
}
public class AlgorithmC extends Algorithm{
public Object compress(Object input){
// do something for TypeC
}
}