我目前正在學習設計模式。在研究策略模式時,我發現了一些對我來說很陌生的事情。我尋找關於這種模式的討論,但沒有人回答我的問題......我如何實施戰略模式,讓它變得乾淨,保持封裝並使添加新戰略變得容易。在這裏解釋一下我的問題是,「規範」的戰略格局:Java策略模式 - 我可以在Context類中委託策略實例嗎?
public interface Strategy {
public void run();
}
public class stratConcrt1 implements Strategy {/*run() implementation*/}
public class stratConcrt2 implements Strategy {/*run() implementation*/}
public class Context {
private Strategy strategy;
public Context(Strategy strat) {
this.strategy = strat;
}
public void runStrategy() {
this.strategy.run()
}
}
public class Client {
public void main(Strings[] args) {
Context cx;
cx = new Context(new stratConcrt1())
cx.runStrategy();
cx = new Context(new stratConcrt2())
cx.runStrategy();
}
}
我明白是怎麼回事,但我覺得奇怪,讓客戶知道一些事可以應用不同的策略。對我來說,讓上下文實例化不同的策略而不是客戶端會更清潔,因爲上下文涉及的策略應該(至少在我的腦海裏)是唯一能夠實例化策略的策略。
我實現了使用JavaFX與上面的代碼一定的差異一個小例子:
我有一個類字段實例座標列表,這個類對列表進行排序的方法。排序座標列表的方法是有幾種策略的方法。
public class Field {
// a field contains rectangles described in a list through their coordinates
private ObservableList<Coordinate> mpv_coordinateList = FXCollections
.observableArrayList();
private Context mpv_sortContext;
// Constructor
public Field() {
//the rectangles are randomly created
Random rd = new Random();
for (int i = 0; i < 100; i++) {
mpv_coordinateList.add(new Coordinate(rd.nextInt(490), rd.nextInt(490)));
}
//a context to dynamically modify the sort algorithm
mpv_sortContext = new Context();
}
//returns the list with all rectangle
public ObservableList<Coordinate> getField() {
return this.mpv_coordinateList;
}
//sort elements (depending on different algorithms)
public ObservableList<Coordinate> sortElements(String p_sortToApply) {
return mpv_sortContext.launchSort(p_sortToApply,
this.mpv_coordinateList);
}
}
由於模型說,我創建了一個接口,讓從這個接口繼承了具體的策略:
public interface SortStrategy {
ObservableList<Coordinate> sort(ObservableList<Coordinate> p_listToSort);
}
public class EvenSort implements SortStrategy {
@Override
public ObservableList<Coordinate> sort(
ObservableList<Coordinate> p_listToSort) {
ObservableList<Coordinate> oddCoordList = FXCollections
.observableArrayList();
for (Coordinate coord : p_listToSort) {
if (coord.x % 2 == 0) {
oddCoordList.add(coord);
}
}
return oddCoordList;
}
}
public class OddSort implements SortStrategy {
@Override
public ObservableList<Coordinate> sort(
ObservableList<Coordinate> p_listToSort) {
ObservableList<Coordinate> oddCoordList = FXCollections
.observableArrayList();
for (Coordinate coord : p_listToSort) {
if (coord.x % 2 == 1) {
oddCoordList.add(coord);
}
}
return oddCoordList;
}
}
具體的類只返回一個包含所有具有偶數或奇數X座標列表座標。
,然後我創建了一個類背景:
public class Context {
//private SortStrategy mpv_sortStrategy; //never used
private EvenSort mpv_evenSort = new EvenSort();
private OddSort mpv_oddSort = new OddSort();
private StandardSort mpv_standardSort = new StandardSort();
private HashMap<String, SortStrategy> mpv_HashMapStrategies;
public Context() {
//creation of a dictionary with all possible strategies
mpv_HashMapStrategies = new HashMap<String, SortStrategy>();
mpv_HashMapStrategies.put("Even Sort", mpv_evenSort);
mpv_HashMapStrategies.put("Odd Sort", mpv_oddSort);
mpv_HashMapStrategies.put("Standard Sort", mpv_standardSort);
}
public ObservableList<Coordinate> launchSort(String p_sortToApply, ObservableList<Coordinate> p_listToSort){
return mpv_HashMapStrategies.get(p_sortToApply).sort(p_listToSort);
}
}
通過GUI用戶可以選擇他想要使用排序列表中的策略。用戶可以點擊按鈕啓動排序。通過主類(未顯示)完成呼叫到inst_field.mpv_sortContext.sortElements(a_string)
,並使用字符串作爲描述要使用的策略的參數。然後在sortElements中使用此字符串來選擇用戶想要應用的策略的實例。
在我的實現中,我一方面是客戶端,另一方是處理策略(上下文,接口和具體類)的所有代碼。如果我想添加一個新策略,我只需要在Context類中添加一個新策略的實例,並在gui中描述這個新策略,以便讓用戶知道它。
我知道,在我做的實現也不是很好,因爲上下文包含每個可能的策略的實例,因爲我不需要對接口的引用,但我發現它比讓Field和客戶知道這些類。
嗯......我完全錯了嗎?我在「規範」戰略模式中錯過了什麼? 「規範」方式是實施戰略模式的唯一途徑嗎?還是有更好的方式來實現這種模式,只有那些應該知道的類能夠意識到策略實例,並且可以輕鬆地添加新策略?
我認爲你是對的,「我陷入了誰的客戶是誰的想法」......感謝真正有趣的鏈接 – 2014-12-08 07:04:06