【问题标题】:Can a model return its own View?模型可以返回自己的视图吗?
【发布时间】:2015-04-08 18:20:39
【问题描述】:

我正在开发一个应用程序,其中列表必须显示同一接口的不同实现(例如,TextImplementation、VideoImplementation、AudioImplementation 等)。在这种情况下,让模型返回其视图是否是一个好的设计?

下面是一些代码示例,演示了我的想法。 请注意,模型实际上并不设计视图,它只是返回它的一个实例。

public interface Impl{
    public Object getQuestion();
    public String getAnswer();
    public View getListCellView();
}

public class AudioImpl implements Impl{

    private File audioFile;
    private String answer;

    public Audio getQuestion(){

        Audio a = Audio.fromFile(audioFile);
        return a;

    }

    public String getAnswer(){

        return answer;

    }

    public View getListCellView(){

        return new AudioListCellView(audioFile);
    }
}

public class AudioListCellView extends View{

    private File file;

    public AudioListCellView(File audioFile){

        this.file  = audioFile;

    }

    public View createView(){

        AudioPlayer ap = new AudioPlayer();
        ap.addOnClickListener(new OnClickListener(){

            public void onClick(ClickEvent e){

                play(this.file);

            }

        });

        this.addView(ap,Layout.CENTER);

    }

}

我考虑这个设计的原因是因为在渲染列表项时,我可以简单地写这样的东西:

class QuestionsListView extends ListView{

    private Collection<Impl> list;

    public View getCellView(int position){

        Impl anImpl = list.get(position);
        return anImpl.getListCellView();
    }

}

这种设计有缺点吗?如何改进?

【问题讨论】:

    标签: design-patterns model-view-controller


    【解决方案1】:

    这种设计有缺点吗?

    是的。

    类 MVC 模式的核心思想是关注点分离,这意味着每个三元组都可以单独使用。根据定义,视图只能访问模型的状态。但是如果你从一个模型中返回一个视图的实例,那么你就打破了 MVC 的核心原则。模型层永远不应该知道是否有一个叫做视图的东西。

    你在视图中所做的,肯定属于视图层(通常由 UI 的逻辑和模板组成)。

    所以,回答你的问题:

    模型可以返回自己的视图吗?是的,你可以这样做,但这不再是 MVC。因为模型现在知道视图并且知道如何构建它。

    在你的情况下,最好的选择是为视图创建一个特殊的工厂,它可以构建它们的实例。

    所以请记住,只要:

    • 模型是分层的,不知道视图和控制器
    • 视图由 UI 的逻辑和模板组成,可以直接访问模型
    • 控制器可以改变视图或模型的状态

    您可以将该实现称为 MVC。否则,只需实现最适合您的方法,但不要调用该 MVC。

    【讨论】:

    • 工厂是我想到的另一种选择,但我有点希望避免if(anImpl instanceof VideoImpl){} 的事情
    • 你也可以考虑使用Adapter模式。在那里你可能有几个 View 适配器(如 AudioImpl),然后按需注入它们
    • 也许你应该考虑使用复合视图模式。您的 AudioList 类不应包含 AudioImpl 集合,而应包含 AudioView 集合。
    猜你喜欢
    • 2015-10-21
    • 1970-01-01
    • 2019-04-02
    • 2014-09-08
    • 2019-08-18
    • 2011-05-06
    • 2011-01-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多