<?xml version="1.0" encoding="GB2312" ?>
<?xml-stylesheet type="text/xsl" href="../../article.xsl" ?>

<article>

<title>关于MVC的一点启示</title>

<author>晨光（Morning）</author>

<keywords>
  <keyword>MVC</keyword>
  <keyword>耦合</keyword>
  <keyword>文档／视</keyword>
</keywords>

<from type="原作"/>
<copyright/>

<paragraph>
MVC作为一种模型，通常用于分布式应用系统（比如：大型商业网站，企业管理系统等）的设计和分析，以及确定系统各部分间的组织关系。但这种分析方法，其实同样适用于其他领域。它本身并不含有某一特定领域的特有性质。
</paragraph>

<paragraph>
笔者认为，就MVC结构的本质而言，它是一种解决耦合系统问题的方法。在一个具有耦合特征的系统内部，各组成部分之间通过一定方式彼此关联。当某一部分的状态发生变动时，它会通过自身和外界的关联，影响其周边部分的状态，而周边部分的状态发生改变的结果，进而又会通过类似的关联影响其他部分的状态。这种变动就像连锁反应一样会从源端通过某种形式传播开去，所谓"牵一发而动全身"。极端情况下，系统各部分之间彼此孤立，即没有任何关联，则不会发生如上所述的现象。而通常，如果系统的耦合程度越大，即各部分之间的关系越密切，这种效应就会越明显。就一个软件而言，它属于具有耦合特征的系统，上述现象的直接体现就是软件的维护过程。软件各部分间的关联越密切，其维护的难度就越大。
</paragraph>

<paragraph>
解决这一问题的方法，可以从两个方面来考虑。首先，应该尽可能减少系统各部分的关联程度，这是显而易见的。因此需要系统设计者明确系统各部分的职责，避免出现功能交叉的情况。这样便可以简化各部分之间的关联（可以称作系统级关联），而将某些关联作为各部分内部的关联（可以称作模块级关联）被隐藏起来。从系统的层面看，经过这样的处理，系统结构将会更清晰，关联会相对减少。其次，在此基础上，可以将这些关联进行集中处理，即将各部分之间关联出现的位置尽可能集中在某几处，而不是散布在系统的所有角落。这样，当系统某些部分发生变化时，系统维护者可以较快地找到需要修改的位置。这种处理方法带来的好处是，在系统变更时，维护者可以将主要注意力集中于模块内部的更改，以及相关模块的变更。同时减少了因处理系统各部分间的关联问题所消耗的工作量以及为寻找这些关联所消耗的工作量。
</paragraph>

<paragraph>
此外，很多系统都不是简单的两层结构（即系统级和模块级），可能是具有某种树状形式的多层结构。因此，上述方法不仅可以用于系统整体设计，还可以用于局部设计。即将某一模块看作是一个子系统，对之进行同样的处理。如果模块中还有子模块，也进行类似处理。如此循环，直至遍历这棵"系统树"的所有部分。
</paragraph>

<paragraph>
MVC结构体现了上述内容。这种思考方法是很值得借鉴的。事实上，还有很多类似的结构。MFC中的文档/视结构（Document/View Architecture）和MVC很类似，它是对具体业务处理进行抽象之后所提出的一个结构。其思想是：将系统按功能划分为两个明确的部分，文档负责数据的处理和维护，而视作为用户接口，负责实现数据的表现，同时接受用户的反馈并传给文档进行处理。文档和视之间的关联，一部分由系统预先作了约定，通过一些固定的方式体现，这些往往是对多数应用场合都适用的部分。而另一些关联则需要针对不同的应用由设计者自己定义。这种结构通常用于Visual C++的程序设计中（因为，它本身就是基于MFC的并由MFC很好的体现了出来），但其思路也是具有普遍意义的。但具体而言，和MVC相比，文档/视结构还是显得有些简单和粗糙。如果粗略地看，事实上它将MVC中的模型和控制器的功能都交由文档来实现了，而这种方式可能会导致文档内部的耦合程度过大。MVC大概可以看作是对文档/视结构的一种细化，即对文档作了进一步的划分。其中，控制器定义了抽象的业务逻辑，用于控制业务流程；模块负责实现具体的业务并管理和维护数据。
</paragraph>

</article>