Sal*_*bas 6 model-view-controller controller model view mv
任何人都可以举例说明为什么使用MVC而不是简单的模型和仅查看是有利的.
注意:无论是MVC还是MVP(Model-View-Presenter),我都在谈论View接收输入的那个,然后Controller会通过将输入解释为某个动作来响应输入事件.模型.当模型更改时,View将通过响应模型中的事件来更新自身.
简单地让模型响应视图中的事件而反之亦然是不利的?
在MVC中,如果我以影响控制器的方式更改模型,那么我将不得不在控制器中进行更改.在模型视图中,如果我更改模型,我将不得不更新视图.
那么,似乎我们通过添加"控制器"部分来引入复杂性?
在 MVC 中,模型对其环境是盲目的,视图也可以如此——将其事件(盲目地)传递给控制器,控制器更了解视图和模型。因此,总而言之,控制器是系统的“不可重用”的一次性部分,因为它是最能感知上下文的组件。
如果我以影响控制器的方式更改模型......
模型应该公开简单的 CRUD 方法,以便使用这些方法的人不必了解有关传递的更新对象的任何信息,也不必了解模型内部实际发生的情况。
这意味着视图(IMO)必须通过创建传递的记录来完成一些工作,因为控制器应该是无状态的并且视图更加持久。控制器被触发并“启动”,对传递的对象进行工作,并且没有状态。
传递的数据是通过某种通用约定创建的。
让我更进一步。假设您有一个视图、一个表格网格和一个控件,其启用属性取决于网格中选择的项目 - 您可以创建一个在内部处理这些控件和此逻辑的视图,这可能是要走的路在这样一个简化的例子中。
但是您的视图越原子,它们就越可重用,因此您为每个(是的,每个)控件创建一个视图。现在您面临的情况是,视图必须相互了解才能注册自己以获取正确的通知......
这就是控制器介入的地方,因为我们希望将所有这些依赖项都粘在他身上,即长期的一次性依赖项。因此控制器管理这种类型的视图到视图通知方案。
现在你的观点是无知的,因为它们可以是独立的,因此可以重用。
You can code a view without having to know about the system, or the 'business logic' as they like to call it. You can code a model without having to know too much about your goals (though it does help to tweak the model to enable it to return the datasets you have in mind).... but controllers, they are last and you have to have the previous two firmed up before you can wire things together.
Here is another thing to think about -- just as the Model is supposed to abstract-away and provide a generic interface to the underlying implementation of the data it is managing (the client does not know if the data comes from a DB, a file, a program setting, etc) -- the view should also abstract away the control it is using.
So, ultimately this means a view should not (caveat below) have functions/properties that look like this:
public property BackgroundColor{get;set}
Run Code Online (Sandbox Code Playgroud)
Nor
public function ScrollBy(x,y){}
Run Code Online (Sandbox Code Playgroud)
But instead:
public SetProp(string name, object val){}
Run Code Online (Sandbox Code Playgroud)
And
public DoCmd(string name, object val){}
Run Code Online (Sandbox Code Playgroud)
This is a bit contrived, and remember I said ultimately... and you ask why is this a good idea?
With reusability in mind, consider that you may one day want to port things from WinForms to, say, Flex, or simple want to use a new-fangled control library that may not expose the same abilities.
I say 'port' here, but that is really not the goal, we are not concerned with porting THIS particular app, but having the underlying MVC elements generic enough to be carried across to a new flavor -- internally, leaving a consistent and ability-independent external interface intact.
If you didn't do this, then when your new flavor comes along, all your hard references to view properties in the (potentially reusable/refactorable/extendable) controllers have to be mucked with.
This is not to mean that such generic setters and cmds have to be the interface for all your views abilities, but rather they should handle 'edge case' properties as well as the normal props/cmds you can expose in the traditional hard-link way. Think of it as an 'extended properties' handler.
That way, (contrived again), suppose you are building on a framework where your buttons no longer have buttonIcon property. Thats cool because you had the foresight to create a button view interface where buttonIcon is an extended property, and inside the view your conditional code does a no-op now when it receives the set/get.
In summary, I am trying to say that the coding goals of MVC should be to give the Model and View generic interfaces to their underlying components, so when you are coding a Controller you don't have to think to hard about who you are controlling. And while the Controllers are being (seemingly unfairly) set up to be the sacrificial lamb in the long run of re-usability -- this does not mean ALL your controllers are destined for death.
它们希望很小,因为它们的很多“思维”已经被推入半智能模型和视图以及其他控制器(例如:对网格进行排序或操作 TreeView 的控制器)——因此它们很小,可以很容易地看到并有资格在您的下一个项目中重用——或者进行克隆和调整以变得合适。