我有几个实现策略模式的Java类。每个类都有不同类型的可变数字参数:
interface Strategy {
public data execute(data);
}
class StrategyA implements Strategy {
public data execute(data);
}
class StrategyB implements Strategy {
public StrategyB(int paramA, int paramB);
public data execute(data);
}
class StrategyC implements Strategy {
public StrategyC(int paramA, String paramB, double paramC);
public data execute(data);
}
现在我希望用户可以在某种UI中输入参数。应该在运行时选择UI,即策略应该独立于它。参数对话框不应该是单片的,并且应该有可能使它的行为和每个策略和UI看起来不同(例如控制台或Swing)。
你会如何解决这个问题?
答案 0 :(得分:4)
这样做的一种可能性是类似于Builder设计模式:
对于每种策略类型,您应该拥有相应的构建器(一个或多个)。构建器不能作为接收所有init参数作为方法参数的普通构建器工作;相反,它应阻止,直到收到相关输入。某些构建器将显示Swing对话框并等待,其他构建器将打印到控制台并等待输入,其他构建器可以从文件中读取等。构建器收到所有输入后,它可以创建策略实例并将其返回。
这样您就可以将数据检索逻辑与策略本身分离。 另一个好处是你可以拥有所有构建器的通用接口,因此一旦选择了特定的构建器,就可以使用相同的代码来操作它。
答案 1 :(得分:1)
此问题的解决方案主要取决于决定当前策略的策略。为简单起见,我假设所有策略的UI都是相同的。
实际上,您将制作构建器类或工厂方法。这条线上的东西:
interface StrategyPicker {
public Strategy getStrategy();
}
// Most likely used in the JFrame it is added to
class StrategyPickerUI extends JPanel implements StrategyPicker {
// initialize the panel with all the widgets
// and implement the getStrategy method. the getStrategy
// method should be called after the input is done in this
// panel (such as clicking an Ok or Apply button)
}
// You can also make one for the console app
class StrategyPickerSimple implements StrategyPicker {
// ...
}
如果你想要真正想要你创建一个简单的工厂类来删除创建它自己的类的行为:
public class StrategyFactory() {
public static Strategy createStrategyFromParameters(StrategyParams sp) {
// creates the Strategy object... doesn't need to be public static
// and if it isn't, it will help making unit tests easier
}
// This nested class could be split up to StrategyAParams,
// StrategyBParams, StrategyCParams
public class StrategyParams {
data paramA;
int paramB_A;
int paramB_B;
int paramC_A;
String paramC_B;
float paramC_C;
}
}
// in StrategyPickerUI class
public getStrategy() {
StrategyParams sp = new StrategyParams();
sp.paramB_A = myJTextFieldParamB_A.getText();
// and so on...
return StrategyFactory.createStrategyFromParameters(sp);
}
如果您希望保持UI不是单一的,那么将职责分解为他们自己的对象。希望这会有所帮助。
答案 2 :(得分:0)
如果参数类包含简单对象(Numbers,Boolean,Date,String),则可以尝试在运行时生成接口。
为组合对象和参数集合生成UI会更加困难
看看Metawidget它是一个强大的ui生成器。
答案 3 :(得分:0)
我建议首先使用谷歌搜索“参数化策略模式”。有文章可能正是您正在寻找的http://www.hillside.net/plop/2010/papers/sobajic.pdf