我编写了一个同时具有高级模式和初学者模式的程序,以允许用户在实际使用之前获取程序的挂起。高级模式几乎与初学者模式相同,除了一个或两个需要被另一个方法替换的方法,因此我决定为高级模式和初学者模式类创建一个通用的模式类,而不仅仅是应对代码:这里如果我的解释不是很清楚,那就是类结构:
假设General Mode类具有以下代码:
public class GeneralMode {
private int range;
private String id;
public GeneralMode() {
}
public int getRange() {
return range;
}
public String getID() {
return id;
}
public void doStuff() {
}
}
GeneralMode类是程序完成所有工作的地方。现在,我想这样做,以便Advanced Mode类可以从GUI类获取输入并以与GeneralMode类相同的方式使用它。
感谢您的帮助!
答案 0 :(得分:8)
使用抽象方法创建'GeneralMode'类,这是一个必须由具体的'高级'和'初学者'类实现的抽象方法。 两种模式共有的功能可以在'GeneralMode'类中实现。
然后,在GUI类中,实例化正确的具体类,并将其放在“GeneralMode”变量中。然后,您可以使用它,而无需知道您的程序是以初学者模式还是以高级模式运行。
伪代码:
GeneralMode mode = (UseAdvancedMode == true)? new AdvancedMode() : new BeginnerMode();
答案 1 :(得分:3)
使GeneralMode
成为一个抽象类肯定是直接获得polimorphic行为的方法(正如Frederik Gheysels正确解释的那样)。
另一个重要的OO范例是
赞成组合优于继承(Item 14, 'Effective Java' by Josh Bloch)
如果您的项目符号列表代表您当前的继承层次结构(如果不是,则忽略我的评论...),我强烈建议您更改它,以便GUI Class
组成 模式(而不是模式是它的扩展 - 经典的“是” vs “有一个”问题) 。将任何GUI设置提取到参数对象中,然后将其传递给模式以进行工作,这将进一步减少耦合。
答案 2 :(得分:2)
为了补充Frederik的答案,GeneralMode也可以是实现此接口的BeginnerMode和AdvancedMode的接口。
如果要在所有子类之间共享逻辑,如果所有类都具有相同的getId实现和任何其他相同的方法,则使用抽象类。
如果您希望将这些方法的实现保留到实现类,请使用接口。
答案 3 :(得分:1)
另一种可能性是使用策略模式。在你的情况下我更喜欢那个,因为我看到更多的灵活性,例如在运行时更改模式时。在这种情况下,您不需要更改整个模型实例(模式对象),而只需要通过加载不同的策略来改变它的行为。因此,您不会通过切换模式来丢失上下文的状态。
public class GeneralContext //was GeneralMode in your Code-Example
{
...
public void doStuff()
{
myMode.doStuff()
}
public void changeStrategy(int mode)
{
switch(mode)
{
case EXPERT_MODE: myMode= new ExpertMode(); break;
....
default: throw NoSuchMode();
}
}
....
private interface Mode
{
void doStuff();
}
private class ExpertMode implements Mode
{
void doStuff()
{
....
}
}
private class BeginnerMode implements Mode
{
void doStuff()
{
....
}
}
}
进一步阅读:GoF-Book(see wikipedia),第315页ff。
答案 4 :(得分:0)
你是正确的方式。您只需修改doStuff()
方法即可从GUI获取所需的输入参数。然后,GUI可以在它拥有的mode
对象上调用此方法,并将相应的参数传递给它。