MVC 模式中的“Hello World”
Posted
技术标签:
【中文标题】MVC 模式中的“Hello World”【英文标题】:"Hello World" in MVC Pattern 【发布时间】:2012-01-19 20:02:36 【问题描述】:在某公司的一次面试中,有人问我这个问题。
你知道哪些设计模式...然后我被告知要基于 MVC 设计模式编写最简单的“hello world”应用程序。
我想出了一个 javascript 程序
var arr = ["a","b","c","d"]; // this is an array, same as store or model
alert(arr[0]); // this is controller
//and browser alert is a view.
后来有人告诉我,警报是一种视图。我知道的关于 MVC 的基本概念是 Model 中的任何更改都会报告给 View。并且中间有一个控制器来调用这些方法。
您能否更正我的方法,或者为 hello world MVC 应用程序提供替代解决方案。还要解释 MVC 的微妙方面。
谢谢。
【问题讨论】:
不是一个真正的问题——你采访了一些白痴。你不能“在 MVC 中”打招呼世界...... scuh 任务是愚蠢的。看看程序员 stackexchange,看看你能不能弄清楚如何驾驭不称职的 HR 无人机。 @Incognito - 欢迎来到“采访世界”。我在面试中被问到更荒谬的问题。 实际上,我不得不建议 Code Review。 @5StringRyan 我知道,我搞砸了一次采访,因为我不知道如何根据 gif 对移动点进行编程——结果证明,这是插入排序。但无论如何,请查看程序员网站。 我不这么认为。如果您可以使用 MVC 模式构建大型应用程序,为什么不使用简单的 hello world。 【参考方案1】:var M = , V = , C = ;
M.data = "hello world";
V.render = function (M) alert(M.data);
C.handleOnload = function () V.render(M);
window.onload = C.handleOnLoad;
控制器 (C
) 监听某种交互/事件流。在这种情况下,它是页面的加载事件。
模型 (M
) 是数据源的抽象。
View (V
) 知道如何从模型中渲染数据。
Controller 告诉 View 用 Model 中的某些东西做某事。
在这个例子中
View 对 Model 一无所知,除了它实现了一些接口 模型对视图和控制器一无所知 控制器知道模型和视图,并告诉视图对模型中的数据做一些事情。请注意,上面的示例出于演示目的而进行了严格的简化。对于 JS MVC 世界中的真实“hello world”示例,请查看todoMVC
【讨论】:
您在这里缺少一些抽象层来处理数据,以及标准的访问器/突变器。如果我们想将此 MVC 应用程序扩展为 Hello Universe,或者从 ajax 调用中加载怎么办? 太棒了。够简洁。无可争辩。 @Incognito 这是我能想到的最小的 MVC,而不会丢失重要的部分。 +1 表示很棒,并改变了我对这个问题的看法(这是一个值得的问题)。 nitpick:它很简洁,但 M 和 V 和 C 最终将成为同一个对象,这可能是您不想要的。 (var M=, V=, C=;
)。
@tereško 确实有一些数据:D【参考方案2】:
我认为你在这里有点忽略了这一点。
MVC 是一种用于设计应用程序的模式。我认为您至少希望能够更改模型,并看到视图中反映的更改。
你通常有一个对象来表示模型,一个不同的对象来表示“视图”(它可能会在模型和你用作视图的 html 对象之间进行调解)和一个控制器,它将从您的 HTML 对象中获取输入并更新模型。
所以你更改了一个编辑字段,编辑字段告诉控制器,控制器更新模型,模型触发控制器用来更新依赖此数据的任何其他视图组件的事件。
实现“hello world”版本需要多几行代码,但我认为这就是我从这样的面试问题中寻找的内容。
【讨论】:
【参考方案3】:MVC 是一种用于构建应用程序的设计模式。 MVC 代表模型、视图、控制。它基本上说您应该将业务逻辑(模型)与用户界面(视图)和控制逻辑分开。
例如:
你有一个用户类,从数据库加载用户,可以保存他们。这是你的模型。
您有一个使用 User 类登录用户的控制器。
控制器完成后,会显示一个包含文本“Welcome $username”的模板。
另外,Model 不应该知道 View 和 Controller,View 不应该知道 Controller,而 Controller 知道 Model 和 View。
关于 MVC 的***:http://de.wikipedia.org/wiki/Model_View_Controller
【讨论】:
【参考方案4】:更好的例子
var M = , V = , C = ;
/* Model View Controller Pattern with Form Example */
/* Controller Handles the Events */
M =
data:
userName : "Dummy Guy",
userNumber : "000000000"
,
setData : function(d)
this.data.userName = d.userName;
this.data.userNumber = d.userNumber;
,
getData : function()
return data;
V =
userName : document.querySelector("#inputUserName"),
userNumber : document.querySelector("#inputUserNumber"),
update: function(M)
this.userName.value = M.data.userName;
this.userNumber.value = M.data.userNumber;
C =
model: M,
view: V,
handler: function()
this.view.update(this.model);
document.querySelector(".submitBtn").addEventListener("click", function()
C.handler.call(C);
);
/* Model Handles the Data */
/* View Handles the Display */
【讨论】:
哇。这是甜蜜而简单的。谢谢【参考方案5】:MVC 架构
我写过一篇关于 MVC 架构的文章。这里只展示了一些代码,希望对大家有帮助。
//Modal
var modal = data: "This is data";
//View
var view = display : function ()
console.log ("////////////////////////////");
console.log ( modal.data);
console.log ("////////////////////////////");
;
//Controller
var controller = ( function ()
view.display();
)();
从上面的例子可以理解,这个设计中有三个不同的单元,每个单元都有特定的工作要执行。让我们从上面的infra结构构建MVC设计。可以有多个视图和观察者,这里只创建另一个视图。
// Modal
var modal = data: "This is data";
// View
var slashView = display : function ()
console.log ("////////////////////////////");
console.log ( modal.data);
console.log ("////////////////////////////");
;
var starView = display : function ()
console.log ("****************************");
console.log ( modal.data);
console.log ("****************************");
;
// Controller
var controller = ( function ()
slashView.display();
starView.display();
)();
这里的理解是,模式不能依赖于视图或查看器或对数据执行的操作。数据模式可以独立,但视图和控制器是必需的,因为一个需要显示数据,另一个需要操作它。因此视图和控制器是因为模态而不是相反的方式创建的。
//Modal
var modal =
data : ["JS in object based language"," JS implements prototypal inheritance"]
;
// View is created with modal
function View(m)
this.modal = m;
this.display = function ()
console.log("***********************************");
console.log(this.modal.data[0]);
console.log("***********************************");
;
function Controller(v)
this.view = v;
this.informView = function()
// update the modal
this.view.display();
;
// Test
var consoleView = new View(modal);
var controller = new Controller(consoleView);
controller.informView();
从上面可以看出,视图和控制器之间已经建立了联系。这是MVC模式的要求之一。为了演示模态的变化,让我们改变程序并观察模态状态的变化是独立完成的并反映在视图中。
//Modal
function Modal()
this.state = 0;
this.data = ["JS is object based language","JS implements prototypal inheritance"];
//
this.getState = function ()
return this.state;
;
this.changeState = function (value)
this.state = value;
;
// View is created with modal
function View(m)
this.modal = m;
this.display = function ()
console.log("***********************************");
console.log(this.modal.data[modal.getState()]);
console.log("***********************************");
;
//controller is created with the view
function Controller(v)
this.view = v;
this.updateView = function()
// update the view
this.view.display();
;
// Test
var modal = new Modal();
var consoleView = new View(modal);
var controller = new Controller(consoleView);
controller.updateView();
// change the state of the modal
modal.changeState(1);
controller.updateView();
当模态的状态改变时,控制器已经向视图发送消息以更新自身。这很好,但仍有一个主要概念有待实现,即观察者或控制器需要由 modal 标识。为了看到这种情况发生,必须在模态和控制器之间建立链接,以便任何数量的控制器都可以显示对模态的兴趣,这被认为是将观察者注册到模态。这种关系是使用观察者不存在于空中的概念来实现的。它的存在是因为对模态感兴趣,因此当它被创建时,它必须使用它需要表现出兴趣的模态来创建,或者换句话说,它可以访问模态。让我们看看下面的例子,看看这个 MVC 设计模式是如何使用 JavaScript 简单而优雅地实现的。
function Modal()
var stateChanged = false;
var state = 0;
var listeners = [];
var data = ["JS is object based language","JS implements prototypal inheritance"];
// To access the data
this.getData = function()
return data;
;
// To get the current state
this.getState = function ()
return state;
;
// For simplicity sake we have added this helper function here to show
// what happens when the state of the data is changed
this.changeState = function (value)
state = value;
stateChanged = true;
notifyAllObservers();
;
// All interested parties get notified of change
function notifyAllObservers ()
var i;
for(i = 0; i < listeners.length; i++)
listeners[i].notify();
;
// All interested parties are stored in an array of list
this.addObserver = function (listener)
listeners.push(listener);
;
// View class, View is created with modal
function View(m)
this.modal = m;
this.display = function ()
console.log("***********************************");
var data = this.modal.getData();
console.log(data[modal.getState()]);
console.log("***********************************");
;
// Controller or Observer class has access to both modal and a view
function Controller(m,v)
this.view = v;
this.modal = m;
this.modal.addObserver(this);
// update view
this.updateView = function()
this.view.display();
;
// Receives notification from the modal
this.notify = function()
// state has changed
this.updateView();
;
// Test
var modal = new Modal();
var consoleView = new View(modal);
var controller = new Controller(modal,consoleView);
// change the state of the modal
modal.changeState(1);
modal.changeState(0);
modal.changeState(1);
modal.changeState(0);
从上面可以看出,观察者已经使用模态的addObsever函数注册了自己,并建立了到模态的链接。一旦创建了所有实例。手动更改模态状态以在视图中显示效果。通常在 GUI 环境中,更改通常通过用户按下任何按钮或任何其他外部输入来完成。我们可以模拟随机发生器的外部输入并观察效果。在下面的示例中,在数据中添加了更多元素以清楚地显示效果。
function Modal()
var stateChanged = false;
var state = 0;
var listeners = [];
var data = [
"JS is object based language","JS implements prototypal inheritance",
"JS has many functional language features", "JS is loosely typed language",
"JS still dominates the Web", "JS is getting matured ","JS shares code
through prototypal inheritance","JS has many useful libraries like JQuery",
"JS is now known as ECMAScript","JS is said to rule the future of Web for
many years"];
//
this.getData = function()
return data;
;
//
this.getState = function ()
return state;
;
this.changeState = function (value)
state = value;
stateChanged = true;
notifyAllObservers();
;
function notifyAllObservers ()
var i;
for(i = 0; i < listeners.length; i++)
listeners[i].notify();
this.addObserver = function (listner)
listeners.push(listner);
;
// View is created with modal
function View(m)
this.modal = m;
this.display = function ()
console.log("****************************************************");
var data = this.modal.getData();
console.log(data[modal.getState()]);
;
//Adding external simulation of user sending input
this.pressButton = function()
var seed = 10;
var number = Math.round(Math.random() * seed) ;
// change the state of modal
this.modal.changeState(number);
;
// Controller class needs modal and view to communicate
function Controller(m,v)
this.view = v;
//console.log(this.view.display);
this.modal = m;
this.modal.addObserver(this);
this.updateView = function()
// update the view
//console.log(this.view);
this.view.display();
;
this.notify = function()
// state has changed
this.updateView();
;
// Test
var modal = new Modal();
var consoleView = new View(modal);
var controller = new Controller(modal,consoleView);
// change the state of the modal
for ( var i = 0 ; i < 10; i++)
consoleView.pressButton();
上面的示例演示了 MVC 框架的使用,其中模式保持独立于视图和控制器。代表数据的模态负责通知所有表现出兴趣并在模态中注册的相关方。一旦发生任何变化,通知就会发送给各方,并留给他们采取行动。下面的例子与上面的例子略有不同,上面只显示新添加的数据。
function Modal()
var stateChanged = false;
var listeners = [];
var data = ["JS is object based language"];
// To retrieve the data
this.getData = function()
return data;
;
// To change the data by any action
this.modifyData = function (string)
( data.length === 1 )? data.push(string): data.unshift(string);
stateChanged = true;
notifyAllObservers();
;
// Notifies all observers
function notifyAllObservers ()
var i;
for(i = 0; i < listeners.length; i++)
listeners[i].notify();
// Requires to register all observers
this.addObserver = function (listener)
listeners.push(listener);
;
// View is created with modal
function View(m)
this.modal = m;
this.display = function ()
console.log("****************************************************");
var data = this.modal.getData();
console.log(data[0]);
console.log("****************************************************");
;
//Adding external simulation of user sending input
this.pressButton = function(string)
// change the state of modal
this.modal.modifyData(string);
;
// View class
function Controller(m,v)
this.view = v;
this.modal = m;
this.modal.addObserver(this);
// Updates the view
this.updateView = function()
this.view.display();
;
// When notifies by the modal send the request of update
this.notify = function()
// state has changed
this.updateView();
;
// Test
var modal = new Modal();
var consoleView = new View(modal);
var controller = new Controller(modal,consoleView);
consoleView.pressButton();
consoleView.pressButton("JS dominates the web world");
consoleView.pressButton("JQuery is a useful library of JS");
最后一件事可能是在不需要时删除观察者。这可以通过在模态调用中添加一个名为removeObserver(object)
的方法来完成。上面的 MVC 设计模式可以通过使用 subcalsing 和在***类中存在的通用函数来更细化,使设计尽可能简单,但它留在了其他一些文章中。希望对您有所帮助。
【讨论】:
【参考方案6】:所以我做了一个简单的例子MVC,数据输出在console.log()
。
let model =
data:
text: "Hello World",
,
;
let view =
init: function ()
this.render();
,
render: function ()
console.log(model.data.text);
,
;
let controller =
init: function ()
view.init();
,
;
controller.init();
【讨论】:
以上是关于MVC 模式中的“Hello World”的主要内容,如果未能解决你的问题,请参考以下文章