我目前正在学习设计模式。在研究策略模式时,我发现了一些对我来说很陌生的事情。我寻找关于这种模式的讨论,但没有人回答我的问题......我如何实施战略模式,让它变得干净,保持封装并使添加新战略变得容易。在这里解释一下我的问题是,“规范”的战略格局: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