我实施了以下策略模式:
public abstract class RetrievalStrategy {
public abstract List<MyObject> retrieve();
}
public class LimitRetrievalStrategy extends RetrievalStrategy {
public int limit;
public LimitRetrievalStrategy(int limit) {
this.limit = limit;
}
public List<MyObject> retrieve() {
// fill up the list and return it, limiting to 'limit' results
return new ArrayList<MyObject>(limit);
}
}
public class SpeedRetrievalStrategy extends RetrievalStrategy {
public int speed;
public SpeedRetrievalStrategy(int speed) {
this.speed = speed;
}
public List<MyObject> retrieve() {
// do something with the speed and return list again
return new ArrayList<MyObject>();
}
}
我的客户端应用程序从用户接收速度或限制(可能还有其他参数)。我想创建一个工厂类,它将根据具有值的参数和不具有值的参数返回正确的策略。我不希望客户决定应该返回哪个策略。那么工厂createStrategy(params)
方法是否应该为每个参数都有if
个语句,并且根据不同的组合(想象有其他策略类)返回Concrete Strategy类?
这样做的正确方法是什么?
答案 0 :(得分:4)
哦,RetrievalStrategyFactory
,从哪里开始?这听起来像是YAGNI的过度工程。一种方法是创建一个用于指定“set”字段的枚举,假设每个参数有一个检索策略,并将其用作工厂。
public enum FieldParameter {
LIMIT {
RetrievalStrategy getRetrivalStrategy(int value) {
return new LimitRetrievalStrategy(value);
}
},
SPEED {
RetrievalStrategy getRetrivalStrategy(int value) {
return new SpeedRetrievalStrategy(value);
}
};
abstract RetrievalStrategy getRetrivalStrategy(int value);
}
然后客户端代码没有明确指定检索策略,但是当客户端代码通知您的代码用户提供了哪个字段时,它是隐式给出的。
答案 1 :(得分:1)
不,方法签名中的返回值应该是公共接口或基类。
工厂必须有if测试来决定要返回的具体类型,但这是不可避免的,除非你可以根据封装参数组合的复合键类来创建一个返回具体实例的Map。
答案 2 :(得分:1)
如果您需要扩展工厂的能力,您需要一个抽象工厂。这是工厂的工厂。抽象工厂可以有许多插件工厂,可以遵循策略来确定使用哪个工厂。
这通常是不必要的复杂,你可以稍后添加,所以它不是你需要做的事情,以防你可能需要它。