我试图了解被动视图设计模式如何适用于简单的Web应用程序。
有人可以使用以下要求提供此模式的简单示例:
- View 是一个打印 HELLO WORLD 的 JSP!
- 数据作为"hello world"持久化在数据存储中,调用检索数据可以是存根
- 提供片段(演示者、视图等)的示例文件,并指示每个文件代表模式的哪个片段。
- 除了 jstl/el(可选)之外,不应使用任何框架/DSL
谢谢
更新1:添加我对如何构建的理解。
演示者;负责特定视图的多个"演绎"(显示、索引、编辑、摘要等)
public class HelloWorldPresenter {
private HttpServletRequest request;
private DataStore dateStore;
public HelloWorldPresenter(HttpServletRequest request) {
this.request = request;
this.dataStore = DataStoreUtil.getDataStore(request);
// Do a bunch of other inits that all getXXXModels() will use
}
public getShowModel() {
HelloWorldShowModel model = new HelloWorldShowModel();
String tmp = makeLoud(this.dataStore.getMyData()); // Stub method
model.setText(tmp);
return model;
}
private String makeLoud(String str) {
return str.toUpperCase() + "!";
}
}
视图使用的模型
public class HelloWorldShowModel {
private String text;
public getText() { return this.text };
public setText(String text) { this.text = text; }
}
//视图显示.jsp
<c:set var="model" value="new HelloWorldPresenter.getShowModel()"/>
${model.text} -> HELLO WORLD!
或
<% HelloWorldShowModel model = new HelloWorldPresenter(request).getShowModel() %>
<%= model.getText() %>
我不确定的事情是:
演示者将如何向视图 (JSP) 公开,因为视图不应知道演示者。不过,我可能会混合语义,而HelloWorldShowModel(充当某种"视图模型",是演示者不应该知道的)。
我是否应该使用HelloViewShowModel抽象,或者我应该简单地在我的演示器上
getText()
一个方法,该方法在JSP中调用以获取请求的文本。如果我确实有多个资源"视图"(例如显示、索引、编辑、摘要等),我是否应该有多个演示者?这个逻辑应该如何打破?从共享演示者继承的多个演示者?每个演示者是否应该只负责返回一个视图模型?
我已经通读了 Fowlers 的文章以及许多其他文章 - 问题(对我来说)是它们是在 .NET 应用程序的上下文中编写的,我不明白它们的所有对象是如何连接的。
我希望这能消除我对"懒惰"的担忧,并寻找"施舍"的答案:)
根据您提出的要求,我会说该模式无法实现。如果您认为视图是 JSP,则控制器无法主动设置 UI 组件的任何值。(对我来说,这是模式的核心:控制器实际上通过设置输入/输出 UI 组件的值来主动更新视图,而不是相反(视图从模型对象获取字段)。使用上述技术无法做到这一点,因为 JSP 无法以这种方式访问。
不过,它可以在基于Javascript的Web环境中实现。考虑你的视图是 DOM,你的控制器是一个 Javascript 组件。JS控制器对DOM具有直接的写入访问权限,因此可以像模式建议的那样主动更新单个字段。为了更新/获取模型,JS控制器可以与服务器端系统通信,例如通过Ajax基于REST API。
像JSP这样的普通模板解决方案不能用于将所有逻辑卸载到控制器,至少在实际情况下是这样。我认为这种事情可以用JSF来实现。
如果你想了解事情是如何完成的,我建议你看看Spring MVC。它的源代码可以教你很多东西。