1

假设我有一个超类,Model. 假设我也有两个子类,NumberModeland StringModel,一个存储一个数字,另一个存储一个字符串。为了实现 MVC 方案,我制作了两个视图,NumberView它们StringView可以编辑和显示模型数据。

然后我有一个Models列表。不幸的是,现在我不知道哪个Models 处理数字和字符串,所以如果我想为所有这些创建视图,我会打破面向对象的范式。

除非...

我在Model调用constructView()中创建了一个方法,该方法返回一个适当的视图并在子类中覆盖它。但是突然间,我让模型意识到了视图,这在 MVC 方案中也感觉不好。

从设计的角度来看,实现这一点的正确方法是什么?

4

2 回答 2

1

也许访问者模式/双重调度是要走的路?它有点复杂,如果你只有两个模型/视图,可能会过于复杂。这可能不是最优雅的解决方案,但这里有:

/* Adding a new model involves adding a new method to this base class. Not very 
 * elegant but that's the way the pattern works...  */
public class View {
    public void render(AModel model) { /* implement in subclass */ }    
    public void render(BModel model) { /* implement in subclass */ }
}

/* Providers provides the views with models, and serves to decouple
 * models from views */
public interface ModelProvider { 
    public void renderWith(View view); 
}

public class AModelProvider implements ModelProvider {
    private final AModel _model;
    public void renderWith(View  view) { view.render(_model); }
}

public class BModelProvider implements ModelProvider { 
    private final BModel _model;
    public void renderWith(View  view) { view.render(_model); }
}

public class AView extends View { 
    public void render(AModel model) { 
        model.doA(); 
    } 
}

public class BView extends View { 
    public void render(BModel model) { 
        model.doB(); 
    } 
}

public class Controller {
    public void renderModels(List<ModelProvider> providers, View view) {
        for (ModelProvider provider : providers) {
            // if provider is an AModelProvider and view is an AView,
            // render(AModel) will be called. If provider is a BModelProvider
            // or if view is BView, nothing will happen since the empty
            // View base class methods will be called...
            provider.renderWith(view);
        }
    }
}
于 2012-12-22T20:13:12.143 回答
0

我认为控制器应该根据模型中的值来决定使用哪个视图,这样模型就不知道要渲染哪个视图。只有控制器有知识。

于 2012-12-22T20:12:44.437 回答