<?xml version="1.0" encoding="UTF-8"?>
  <feed xmlns="http://www.w3.org/2005/Atom">
  <title type="html"><![CDATA[木子屋 - 设计模式]]></title>
  <subtitle type="html"><![CDATA[Dnawo&#39;s BLOG]]></subtitle>
  <id>http://www.mzwu.com/</id>
  <link rel="alternate" type="text/html" href="http://www.mzwu.com/" /> 
  <link rel="self" type="application/atom+xml" href="http://www.mzwu.com/atom.asp" /> 
  <generator uri="http://www.pjhome.net/" version="2.8">PJBlog3</generator> 
  <updated>2021-09-28T00:15:18+08:00</updated>

  <entry>
	  <title type="html"><![CDATA[MVC、MVP和MVVM三种模式的优缺点和区别[转]]]></title>
	  <author>
		 <name>dnawo</name>
		 <uri>http://www.mzwu.com/</uri>
		 <email>service@mzwu.com</email>
	  </author>
	  <category term="" scheme="http://www.mzwu.com/default.asp?cateID=17" label="设计模式" /> 
	  <updated>2021-09-28T00:15:18+08:00</updated>
	  <published>2021-09-28T00:15:18+08:00</published>
		  <summary type="html"><![CDATA[<img width="630" height="262" src="http://www.mzwu.com/pic/202109/051.jpg" border="0" alt=""/><br/><br/>■ 原文：<a href="https://zhuanlan.zhihu.com/p/38108311" target="_blank" rel="external">https://zhuanlan.zhihu.com/p/38108311</a><br/>■ 作者：终端研发部<br/><br/>MVC、MVP和MVVM三种模式有什么区别，网上很多文章关于这方面的讨论比较杂乱，各种MV模式之间的区别分不清，甚至有些描述都是错误的。本文追根溯源，从最经典的Smalltalk-80 MVC模式开始逐步还原图形界面之下最真实的MV模式。<br/><br/><strong>GUI图形界面应用程序所面临的问题</strong><br/><br/>图形界面应用程序提供给用户可视化的操作界面，这个界面提供给数据和信息。用户输入行为（键盘，鼠标等）会执行一些业务逻辑，可能会导致对应用程序数据的变更，数据的变更自然需要用户界面的同步变更以提供最准确的信息。例如用户对一个电子表格重新排序的操作，应用程序需要响应用户操作，对数据进行排序，然后需要同步到界面上。<br/><br/>在开发应用程序的时候，以求更好的管理应用程序的复杂性，基于职责分离（Speration of Duties）的思想都会对应用程序进行分层。在开发图形界面应用程序的时候，会把管理用户界面的层次称为View层，管理应用数据的层次称为Model层（注意这里的Model指的是Domain Model，这个应用程序对需要解决的问题的数据抽象，不包含应用的状态，可以简单理解为对象）。Model层对应用程序的业务逻辑无知，只保存数据结构和提供数据操作的接口。<br/><br/><div align="center"><img width="630" height="377" src="http://www.mzwu.com/pic/202109/041.jpg" border="0" alt=""/></div><br/>有了View和Model的分层，那么就有了两个问题：<br/><br/>◆ 管理如何响应用户操作的业务逻辑（例如排序）？<br/>◆ View如何同步Model的变更？<br/><br/>带着这两个问题开始探索MV模式，会发现这些模式之间的差异可以归纳为对这两个问题处理的方式的不同，而几乎所有的MV模式都是经典的Smalltalk-80 MVC的修改版。<br/><br/><strong>Smalltalk-80 MVC</strong><br/><br/>早在上个世纪70年代，美国施乐公司（Xerox）的工程师研发了Smalltalk编程语言，并且开始用它编写图形界面的应用程序，而在Smalltalk-80这个版本的时候，一位叫Trygve Reenskaug的工程师设计了MVC图形应用程序的架构模式，极大地降低了图形应用程序的管理难度。但在四人组（GoF）的设计模式中并没有把MVC当做是设计模式，而仅仅是把它看成解决问题的一些类的集合。Smalltalk-80 MVC和GoF描述的MVC是最经典的MVC模式。<br/><br/>MVC除了把应用程序分成View、Model层，还额外的加了一个Controller层，它的职责就是专门管理应用程序的业务逻辑。Model、View、Controller三个层次的依赖关系为：Controller和View都依赖Model层，Controller和View可以互相依赖。在不同的资料中Controller和View之间的依赖关系可能不一样，有些是单向依赖，有些是双向依赖，这个其实关系不大，后面会看到它们的依赖关系都是为了把处理用户行为触发的业务逻辑的处理权交给Controller。<br/><br/><div align="center"><img src="http://www.mzwu.com/pic/202109/042.jpg" border="0" alt=""/></div><br/>用户对View操作以后，View捕获到这个操作，并把处理的权利交移给Controller（Pass calls），Controller接着会执行相关的业务逻辑，这些业务逻辑可能需要对Model进行相应的操作，当Model变更了以后，会通过观察者模式（Observer Pattern）通知View，View通过观察者模式收到Model变更的消息以后，会向Model请求最新的数据，然后重新更新界面，如下图：<br/><br/><div align="center"><img width="630" height="563" src="http://www.mzwu.com/pic/202109/043.jpg" border="0" alt=""/></div><br/>看似没有什么特别的地方，但是有几个需要特别关注的关键点：<br/><br/>■ View是把控制权交移给Controller，自己不执行业务逻辑；<br/>■ Controller执行业务逻辑并且操作Model，但不会直接操作View，可以说它是对View无知的；<br/>■ View和Model的同步消息是通过观察者模式进行，而同步操作是由View自己请求Model的数据然后对视图进行更新。<br/><br/>需要特别注意的是MVC模式的精髓在于第三点：Model的更新是通过观察者模式告知View的，具体表现形式可以是Pub/Sub或者是触发Events，而网上很多对于MVC的描述都没有强调这一点。通过观察者模式的好处就是：不同的MVC三角关系可能会有共同的Model，一个MVC三角中的Controller操作了Model以后，其他MVC三角的View都会接受到通知，然后更新自己，保证了依赖同一块Model的不同View显示数据的实时性和准确性。我们每天都在用的观察者模式，在几十年前就已经被大神们整合到MVC的架构当中。<br/><br/>这里有一个MVC模式的<a target="_blank" href="https://github.com/livoras/MVW-demos/tree/master/src/scri&#112;ts/mvc" rel="external">Javascri&#112;t Demo</a>，实现了一个小的TodoList应用程序。经典的Smalltalk-80 MVC不需要任何框架支持就可以实现。目前Web前端框架当中只有一个号称是严格遵循Smalltalk-80 MVC模式的：<a target="_blank" href="https://github.com/petermichaux/maria" rel="external">maria.js</a>。<br/><br/><span style="color:Brown">MVC模式的优点</span><br/><br/>■ 把业务逻辑全部分离到Controller中，模块化程度高。当业务逻辑变更的时候，不需要变更View和Model，只需要Controller换成另外一个Controller就行了（Swappable Controller）;<br/>■ 观察者模式可以做到多视图同时更新;<br/><br/><span style="color:Brown">MVC模式的缺点</span><br/><br/>■ Controller测试困难。因为视图同步操作是由View自己执行，而View只能在有UI的环境下运行。在没有UI环境下对Controller进行单元测试的时候，Controller业务逻辑的正确性是无法验证的：Controller更新Model的时候，无法对View的更新操作进行断言;<br/>■ View无法组件化。View是强依赖特定的Model的，如果需要把这个View抽出来作为一个另外一个应用程序可复用的组件就困难了，因为不同程序的的Domain Model是不一样的;<br/><br/><strong>MVC Model 2</strong><br/><br/>在Web服务端开发的时候也会接触到MVC模式，而这种MVC模式不能严格称为MVC模式。经典的MVC模式只是解决客户端图形界面应用程序的问题，而对服务端无效。服务端的MVC模式有自己特定的名字：MVC Model 2，或者叫JSP Model 2，或者直接就是Model 2 。Model 2客户端和服务端的交互模式如下：<br/><br/><div align="center"><img width="630" height="740" src="http://www.mzwu.com/pic/202109/044.jpg" border="0" alt=""/></div><br/>服务端接收到来自客户端的请求，服务端通过路由规则把这个请求交由给特定的Controller进行处理，Controller执行相应的业务逻辑，对数据库数据（Model）进行操作，然后用数据去渲染特定的模版，返回给客户端。<br/><br/>因为HTTP协议是单工协议并且是无状态的，服务器无法直接给客户端推送数据。除非客户端再次发起请求，否则服务器端的Model的变更就无法告知客户端。所以可以看到经典的Smalltalk-80 MVC中Model通过观察者模式告知View更新这一环被无情地打破，不能称为严格的MVC。<br/><br/>Model 2模式最早在1998年应用在JSP应用程序当中，JSP Model 1应用管理的混乱诱发了JSP参考了客户端MVC模式，催生了Model 2。<br/><br/><div align="center"><img width="630" height="219" src="http://www.mzwu.com/pic/202109/045.jpg" border="0" alt=""/></div><br/>后来这种模式几乎被应用在Web开发框架的所有语言中。PHP的ThinkPHP，Python的Dijango、Flask，NodeJS的Express，Ruby的RoR，基本都采纳了这种模式。平常所讲的MVC基本是这种服务端的MVC。<br/><br/><strong>MVP</strong><br/><br/>MVP模式是在上个世纪90年代，IBM旗下的子公司Taligent在用C/C++开发一个叫CommonPoint的图形界面应用系统的时候提出来的。MVP模式有两种：Passive View和Supervising Controller，我们大多数情况下讨论的都是Passive View模式。<br/><br/>MVP模式把MVC模式中的Controller换成了Presenter，MVP打破了View原来对于Model的依赖，其余的依赖关系和MVC模式一致。MVP层次之间的依赖关系如下：<br/><br/><div align="center"><img width="630" height="443" src="http://www.mzwu.com/pic/202109/046.jpg" border="0" alt=""/></div><br/>既然View对Model的依赖被打破了，那View如何同步Model的变更？看看MVP的调用关系：<br/><br/><div align="center"><img width="630" height="561" src="http://www.mzwu.com/pic/202109/047.jpg" border="0" alt=""/></div><br/>和MVC模式一样，用户对View的操作都会从View交移给Presenter。Presenter同样的会执行相应的业务逻辑，并且对Model进行相应的操作；而这时候Model也是通过观察者模式把自己变更的消息传递出去，但是是传给Presenter而不是View。Presenter获取到Model变更的消息以后，通过View提供的接口更新界面。<br/><br/>这边也有几个关键点：<br/><br/>■ View不再负责同步的逻辑，而是由Presenter负责。Presenter中既有业务逻辑也有同步逻辑；<br/>■ View需要提供操作界面的接口给Presenter进行调用；（关键）<br/><br/>对比在MVC中，Controller是不能操作View的，View也没有提供相应的接口，而在MVP当中，Presenter可以操作View，View需要提供一组对界面操作的接口给Presenter进行调用，Model仍然通过事件广播自己的变更，但由Presenter监听而不是View。<br/><br/>MVP模式，这里也提供一个用<a target="_blank" href="https://github.com/livoras/MVW-demos/tree/master/src/scri&#112;ts/mvp" rel="external">Javascri&#112;t编写的例子</a>。<br/><br/><span style="color:Brown">MVP模式的优点</span><br/><br/>■ 便于测试。Presenter对View是通过接口进行，在对Presenter进行不依赖UI环境的单元测试的时候，可以通过Mock一个View对象，这个对象只需要实现了View的接口即可，然后依赖注入到Presenter中，单元测试的时候就可以完整的测试Presenter业务逻辑的正确性。这里根据上面的例子给出了Presenter的<a target="_blank" href="https://github.com/livoras/MVW-demos/tree/master/test/mvp" rel="external">单元测试样例</a>。<br/>■ View可以进行组件化。在MVP当中，View不依赖Model，这样就可以让View从特定的业务场景中脱离出来，可以说View可以做到对业务逻辑完全无知。它只需要提供一系列接口提供给上层操作，这样就可以做高度可复用的View组件。<br/><br/><span style="color:Brown">MVP模式的缺点</span><br/><br/>■ Presenter中除了业务逻辑以外，还有大量的View-&gt;Model，Model-&gt;View的手工同步逻辑，造成Presenter比较笨重，维护起来会比较困难。<br/><br/>再说下MVP的另一种模式：Supervising Controller， Passive View模式下View非常Passive，它几乎什么都不知道，Presenter让它干什么它就干什么，而Supervising Controller模式中，Presenter会把一部分简单的同步逻辑交给View自己去做，Presenter只负责比较复杂的、高层次的UI操作，所以可以把它看成一个Supervising Controller。<br/><br/>Supervising Controller模式下的依赖和调用关系：<br/><br/><div align="center"><img width="630" height="567" src="http://www.mzwu.com/pic/202109/048.jpg" border="0" alt=""/></div><br/>因为Supervising Controller用得比较少，对它的讨论就到这里为止。<br/><br/><strong>MVVM</strong><br/><br/>MVVM模式最早是微软公司提出，并且大量使用在.NET的WPF和Sliverlight中。2005年微软工程师John Gossman在自己的<a target="_blank" href="http://www.mzwu.com/blogs.msdn.com/b/johngossman/archive/2005/10/08/478683.aspx" rel="external">博客</a>上首次公布了MVVM模式。<br/><br/>MVVM代表的是Model-View-ViewModel，这里需要解释一下什么是ViewModel。ViewModel的含义就是 &#34;Model of View&#34;，视图的模型，它的含义包含了业务对象模型（Domain Model）和视图的状态（State）。 在图形界面应用程序当中，界面所提供的信息可能不仅仅包含应用程序的业务对象模型，还可能包含一些业务对象模型不包含的视图状态，例如电子表格程序上需要显示当前排序的状态是顺序的还是逆序的，而这是Domain Model所不包含的，但也是需要显示的信息。<br/><br/>可以简单把ViewModel理解为页面上所显示内容的数据抽象，和Domain Model不一样，ViewModel更适合用来描述View。<br/><br/>MVVM的依赖关系和MVP基本一样，只不过是把P换成了VM：<br/><br/><div align="center"><img src="http://www.mzwu.com/pic/202109/049.jpg" border="0" alt=""/></div><br/>MVVM的调用关系也和MVP一样。但是，在ViewModel当中会有一个叫Binder，或者叫Data-binding engine的东西。以前全部由Presenter负责的View和Model之间数据同步的操作交由给Binder处理。你只需要在View的模版语法当中，指令式地声明View上的显示的内容是和Model的哪一块数据绑定的。当ViewModel对进行Model更新的时候，Binder会自动把数据更新到View上去，当用户对View进行操作（例如表单输入）时，Binder也会自动把数据更新到Model上去。这种方式称为：Two-way data-binding，双向数据绑定。可以简单而不恰当地理解为一个模版引擎，但是会根据数据变更实时渲染。<br/><br/><div align="center"><img width="630" height="572" src="http://www.mzwu.com/pic/202109/050.jpg" border="0" alt=""/></div><br/>也就是说，MVVM把View和Model的手工同步逻辑自动化了。以前Presenter负责的View和Model同步不再手工地进行操作，而是交由框架所提供的Binder进行负责。只需要告诉Binder，View显示的数据对应的是Model哪一部分即可。<br/><br/>这里有一个<a target="_blank" href="http://www.mzwu.com/github.com/livoras/MVW-demos/tree/master/src/scri&#112;ts/mvvm.js" rel="external">Javascri&#112;t MVVM的例子</a>，因为MVVM需要Binder引擎。所以例子中使用了一个MVVM的库：<a target="_blank" href="http://www.mzwu.com/&lt;br/&gt;&lt;a href="http://vuejs.org/" target="_blank" rel="external"&gt;http://vuejs.org/&lt;/a&gt;" rel="external">Vue.js</a>。<br/><br/><span style="color:Brown">MVVM模式的优点</span><br/><br/>■ 提高可维护性。解决了MVP大量的手动View和Model同步的问题，提供双向绑定机制。提高了代码的可维护性；<br/>■ 简化测试。因为同步逻辑是交由Binder做的，View跟着Model同时变更，所以只需要保证Model的正确性，View就正确。大大减少了对View同步更新的测试；<br/><br/><span style="color:Brown">MVVM模式的缺点</span><br/><br/>■ 过于简单的图形界面不适用，或说牛刀杀鸡；<br/>■ 对于大型的图形应用程序，视图状态较多，ViewModel的构建和维护的成本都会比较高；<br/>■ 数据绑定的声明是指令式地写在View的模版当中的，这些内容是没办法去打断点debug的；<br/><br/><strong>结语</strong><br/><br/>可以看到，从MVC-&gt;MVP-&gt;MVVM，就像一个打怪升级的过程，后者解决了前者遗留的问题，把前者的缺点优化成了优点。同样的Demo功能，代码从最开始的一堆文件，优化成了最后只需要20几行代码就完成。MV*模式之间的区分还是蛮清晰的，希望可以给对这些模式理解比较模糊的同学带来一些参考和思路。<br/><br/><strong>延伸阅读</strong><br/><br/>[1].MVC、MVP、MVVM的区别和联系：<a href="http://c.biancheng.net/view/7743.html" target="_blank" rel="external">http://c.biancheng.net/view/7743.html</a>]]></summary>
	  <link rel="alternate" type="text/html" href="http://www.mzwu.com/article.asp?id=4868" /> 
	  <id>http://www.mzwu.com/default.asp?id=4868</id>
  </entry>	
		
  <entry>
	  <title type="html"><![CDATA[C#设计模式-原型模式]]></title>
	  <author>
		 <name>dnawo</name>
		 <uri>http://www.mzwu.com/</uri>
		 <email>service@mzwu.com</email>
	  </author>
	  <category term="" scheme="http://www.mzwu.com/default.asp?cateID=17" label="设计模式" /> 
	  <updated>2010-03-15T16:03:41+08:00</updated>
	  <published>2010-03-15T16:03:41+08:00</published>
		  <summary type="html"><![CDATA[<span style="color:Brown">1.定义</span><br/><br/>用原型实例指定创建对象的种类，并且通过拷贝这个原型来创建新的对象。<br/><br/><span style="color:Brown">2.UML图</span><br/><br/><img src="http://www.mzwu.com/pic/201003/035.gif" border="0" alt=""/><br/><br/><span style="color:Brown">3.代码</span><br/><br/><div class="UBBPanel codePanel"><div class="UBBTitle"><a onClick="copycode(code13764);" style="float:right;cursor: pointer;font-weight: normal; font-style: normal">复制内容到剪贴板</a><img src="http://www.mzwu.com/images/code.gif" style="margin:0px 2px -3px 0px;" alt="程序代码"/> 程序代码</div><div class="UBBContent" id=code13764>using System;<br/><br/>namespace ConsoleApplication1<br/>{<br/>&nbsp;&nbsp;&nbsp;&nbsp;class Program<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;static void Main(string[] args)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Prototype p1 = new ConcretePrototype1();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Prototype p2 = p1.Clone();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Prototype p3 = p1.Clone();<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Console.ReadKey();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;summary&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;/// 原型类<br/>&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;/summary&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;abstract class Prototype<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public abstract Prototype Clone();<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;summary&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;/// 具体原型类<br/>&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;/summary&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;class ConcretePrototype1 : Prototype<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public override Prototype Clone()<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Console.WriteLine(&#34;复制了一份&#34; + this.GetType().Name);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return (Prototype)this.MemberwiseClone();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>}</div></div>]]></summary>
	  <link rel="alternate" type="text/html" href="http://www.mzwu.com/article.asp?id=2397" /> 
	  <id>http://www.mzwu.com/default.asp?id=2397</id>
  </entry>	
		
  <entry>
	  <title type="html"><![CDATA[C#设计模式-建造者模式]]></title>
	  <author>
		 <name>dnawo</name>
		 <uri>http://www.mzwu.com/</uri>
		 <email>service@mzwu.com</email>
	  </author>
	  <category term="" scheme="http://www.mzwu.com/default.asp?cateID=17" label="设计模式" /> 
	  <updated>2010-03-09T18:58:27+08:00</updated>
	  <published>2010-03-09T18:58:27+08:00</published>
		  <summary type="html"><![CDATA[<span style="color:Brown">1.定义</span><br/><br/>将一个复杂对象的构建与它的表示分离，使得同样的构建过程可以创建不同的表示。<br/><br/><span style="color:Brown">2.UML图</span><br/><br/><img src="http://www.mzwu.com/pic/201003/028.gif" border="0" alt=""/><br/><br/><span style="color:Brown">3.代码</span><br/><br/><div class="UBBPanel codePanel"><div class="UBBTitle"><a onClick="copycode(code25804);" style="float:right;cursor: pointer;font-weight: normal; font-style: normal">复制内容到剪贴板</a><img src="http://www.mzwu.com/images/code.gif" style="margin:0px 2px -3px 0px;" alt="程序代码"/> 程序代码</div><div class="UBBContent" id=code25804>using System;<br/><br/>namespace ConsoleApplication1<br/>{<br/>&nbsp;&nbsp;&nbsp;&nbsp;class Program<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;static void Main(string[] args)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Builder builder = new ConcreteBuilder();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Director director = new Director(builder);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Product product = builder.GetResult();<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Console.ReadKey();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;summary&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;/// 指挥者<br/>&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;/summary&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;class Director<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public Director(Builder builder)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;builder.BuildPartA();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;builder.BuildPartB();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Console.WriteLine(&#34;组装Product对象！&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;summary&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;/// 抽象建造者类<br/>&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;/summary&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;abstract class Builder<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public abstract void BuildPartA();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public abstract void BuildPartB();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public abstract Product GetResult();<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;summary&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;/// 具体建造者<br/>&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;/summary&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;class ConcreteBuilder : Builder<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Product product = new Product();<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public override void BuildPartA()<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//组装Product对象<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public override void BuildPartB()<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//组装Product对象<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public override Product GetResult()<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Console.WriteLine(&#34;返回Product对象！&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return product;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;summary&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;/// 产品父类<br/>&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;/summary&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;class Product<br/>&nbsp;&nbsp;&nbsp;&nbsp;{ }<br/>}</div></div>]]></summary>
	  <link rel="alternate" type="text/html" href="http://www.mzwu.com/article.asp?id=2394" /> 
	  <id>http://www.mzwu.com/default.asp?id=2394</id>
  </entry>	
		
  <entry>
	  <title type="html"><![CDATA[C#设计模式-抽象工厂模式 ]]></title>
	  <author>
		 <name>dnawo</name>
		 <uri>http://www.mzwu.com/</uri>
		 <email>service@mzwu.com</email>
	  </author>
	  <category term="" scheme="http://www.mzwu.com/default.asp?cateID=17" label="设计模式" /> 
	  <updated>2010-03-09T17:45:18+08:00</updated>
	  <published>2010-03-09T17:45:18+08:00</published>
		  <summary type="html"><![CDATA[<span style="color:Brown">1.定义</span><br/><br/>提供一个创建一系列相关或相互依赖对象的接口，而无需指定它们具体的类。<br/><br/><span style="color:Brown">2.UML图</span><br/><br/><img src="http://www.mzwu.com/pic/201003/027.gif" border="0" alt=""/><br/><br/><span style="color:Brown">3.代码</span><br/><br/><div class="UBBPanel codePanel"><div class="UBBTitle"><a onClick="copycode(code22473);" style="float:right;cursor: pointer;font-weight: normal; font-style: normal">复制内容到剪贴板</a><img src="http://www.mzwu.com/images/code.gif" style="margin:0px 2px -3px 0px;" alt="程序代码"/> 程序代码</div><div class="UBBContent" id=code22473>using System;<br/><br/>namespace ConsoleApplication1<br/>{<br/>&nbsp;&nbsp;&nbsp;&nbsp;class Program<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;static void Main(string[] args)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AbstractProductA pa;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AbstractProductB pb;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AbstractFactory f1 = new ConcreteFactory1();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pa = f1.Cr&#101;ateProductA();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pb = f1.Cr&#101;ateProductB();<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AbstractFactory f2 = new ConcreteFactory2();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pa = f2.Cr&#101;ateProductA();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pb = f2.Cr&#101;ateProductB();<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Console.ReadKey();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;summary&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;/// 抽象工厂<br/>&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;/summary&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;abstract class AbstractFactory<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public abstract AbstractProductA Cr&#101;ateProductA();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public abstract AbstractProductB Cr&#101;ateProductB();<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;summary&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;/// 具体工厂<br/>&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;/summary&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;class ConcreteFactory1 : AbstractFactory<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public override AbstractProductA Cr&#101;ateProductA()<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Console.WriteLine(&#34;创建并返回ProductA1实例！&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return new ProductA1();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public override AbstractProductB Cr&#101;ateProductB()<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Console.WriteLine(&#34;创建并返回ProductB1实例！&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return new ProductB1();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;summary&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;/// 具体工厂<br/>&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;/summary&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;class ConcreteFactory2 : AbstractFactory<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public override AbstractProductA Cr&#101;ateProductA()<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Console.WriteLine(&#34;创建并返回ProductA2实例！&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return new ProductA2();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public override AbstractProductB Cr&#101;ateProductB()<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Console.WriteLine(&#34;创建并返回ProductB2实例！&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return new ProductB2();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;summary&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;/// 抽象产品<br/>&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;/summary&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;class AbstractProductA<br/>&nbsp;&nbsp;&nbsp;&nbsp;{ }<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;summary&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;/// 具体产品<br/>&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;/summary&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;class ProductA1 : AbstractProductA<br/>&nbsp;&nbsp;&nbsp;&nbsp;{ }<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;summary&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;/// 具体产品<br/>&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;/summary&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;class ProductA2 : AbstractProductA<br/>&nbsp;&nbsp;&nbsp;&nbsp;{ }<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;summary&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;/// 抽象产品<br/>&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;/summary&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;class AbstractProductB<br/>&nbsp;&nbsp;&nbsp;&nbsp;{ }<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;summary&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;/// 具体产品<br/>&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;/summary&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;class ProductB1 : AbstractProductB<br/>&nbsp;&nbsp;&nbsp;&nbsp;{ }<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;summary&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;/// 具体产品<br/>&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;/summary&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;class ProductB2 : AbstractProductB<br/>&nbsp;&nbsp;&nbsp;&nbsp;{ }<br/>}</div></div>]]></summary>
	  <link rel="alternate" type="text/html" href="http://www.mzwu.com/article.asp?id=2393" /> 
	  <id>http://www.mzwu.com/default.asp?id=2393</id>
  </entry>	
		
  <entry>
	  <title type="html"><![CDATA[C#设计模式-工厂方法模式]]></title>
	  <author>
		 <name>dnawo</name>
		 <uri>http://www.mzwu.com/</uri>
		 <email>service@mzwu.com</email>
	  </author>
	  <category term="" scheme="http://www.mzwu.com/default.asp?cateID=17" label="设计模式" /> 
	  <updated>2010-03-09T17:31:43+08:00</updated>
	  <published>2010-03-09T17:31:43+08:00</published>
		  <summary type="html"><![CDATA[<span style="color:Brown">1.定义</span><br/><br/>定义一个用于创建对象的接口，让子类决定将哪一个类实例化。它使一个类的实例化延迟到其子类。<br/><br/><span style="color:Brown">2.UML图</span><br/><br/><img src="http://www.mzwu.com/pic/201003/026.gif" border="0" alt=""/><br/><br/><span style="color:Brown">3.代码</span><br/><br/><div class="UBBPanel codePanel"><div class="UBBTitle"><a onClick="copycode(code61994);" style="float:right;cursor: pointer;font-weight: normal; font-style: normal">复制内容到剪贴板</a><img src="http://www.mzwu.com/images/code.gif" style="margin:0px 2px -3px 0px;" alt="程序代码"/> 程序代码</div><div class="UBBContent" id=code61994>using System;<br/><br/>namespace ConsoleApplication1<br/>{<br/>&nbsp;&nbsp;&nbsp;&nbsp;class Program<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;static void Main(string[] args)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Factory c1 = new ConcreteFactory1();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Product p1 = c1.Cr&#101;ate();<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Factory c2 = new ConcreteFactory2();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Product p2 = c2.Cr&#101;ate();<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Console.ReadKey();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;summary&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;/// 抽象工厂<br/>&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;/summary&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;abstract class Factory<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public abstract Product Cr&#101;ate();<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;summary&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;/// 具体工厂<br/>&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;/summary&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;class ConcreteFactory1 : Factory<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public override Product Cr&#101;ate()<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Console.WriteLine(&#34;创建并返回ConcreteProduct1实例！&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return new ConcreteProduct1();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;summary&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;/// 具体工厂<br/>&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;/summary&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;class ConcreteFactory2 : Factory<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public override Product Cr&#101;ate()<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Console.WriteLine(&#34;创建并返回ConcreteProduct2实例！&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return new ConcreteProduct2();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;summary&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;/// 产品父类<br/>&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;/summary&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;class Product<br/>&nbsp;&nbsp;&nbsp;&nbsp;{ }<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;summary&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;/// 具体产品<br/>&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;/summary&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;class ConcreteProduct1 : Product<br/>&nbsp;&nbsp;&nbsp;&nbsp;{ }<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;summary&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;/// 具体产品<br/>&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;/summary&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;class ConcreteProduct2 : Product<br/>&nbsp;&nbsp;&nbsp;&nbsp;{ }<br/>}</div></div>]]></summary>
	  <link rel="alternate" type="text/html" href="http://www.mzwu.com/article.asp?id=2392" /> 
	  <id>http://www.mzwu.com/default.asp?id=2392</id>
  </entry>	
		
  <entry>
	  <title type="html"><![CDATA[C#设计模式-简单工厂模式]]></title>
	  <author>
		 <name>dnawo</name>
		 <uri>http://www.mzwu.com/</uri>
		 <email>service@mzwu.com</email>
	  </author>
	  <category term="" scheme="http://www.mzwu.com/default.asp?cateID=17" label="设计模式" /> 
	  <updated>2010-03-09T17:29:31+08:00</updated>
	  <published>2010-03-09T17:29:31+08:00</published>
		  <summary type="html"><![CDATA[<span style="color:Brown">1.定义</span><br/><br/>根据提供给它的数据，返回几个可能类中的一个类的实例。<br/><br/><span style="color:Brown">2.UML图</span><br/><br/><img src="http://www.mzwu.com/pic/201003/025.gif" border="0" alt=""/><br/><br/><span style="color:Brown">3.代码</span><br/><br/><div class="UBBPanel codePanel"><div class="UBBTitle"><a onClick="copycode(code10642);" style="float:right;cursor: pointer;font-weight: normal; font-style: normal">复制内容到剪贴板</a><img src="http://www.mzwu.com/images/code.gif" style="margin:0px 2px -3px 0px;" alt="程序代码"/> 程序代码</div><div class="UBBContent" id=code10642>using System;<br/><br/>namespace ConsoleApplication1<br/>{<br/>&nbsp;&nbsp;&nbsp;&nbsp;class Program<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;static void Main(string[] args)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Product p;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p = Factory.Cr&#101;ate(&#34;product1&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p = Factory.Cr&#101;ate(&#34;product2&#34;);<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Console.ReadKey();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;summary&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;/// 工厂类<br/>&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;/summary&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;class Factory<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public static Product Cr&#101;ate(string type)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (type == &#34;product1&#34;)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Console.WriteLine(&#34;创建并返回ConcreteProduct1实例！&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return new ConcreteProduct1();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else if (type == &#34;product2&#34;)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Console.WriteLine(&#34;创建并返回ConcreteProduct2实例！&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return new ConcreteProduct2();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return null;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;summary&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;/// 产品父类<br/>&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;/summary&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;class Product<br/>&nbsp;&nbsp;&nbsp;&nbsp;{ }<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;summary&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;/// 具体产品<br/>&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;/summary&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;class ConcreteProduct1 : Product<br/>&nbsp;&nbsp;&nbsp;&nbsp;{ }<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;summary&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;/// 具体产品<br/>&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;/summary&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;class ConcreteProduct2 : Product<br/>&nbsp;&nbsp;&nbsp;&nbsp;{ }<br/>}</div></div>]]></summary>
	  <link rel="alternate" type="text/html" href="http://www.mzwu.com/article.asp?id=2391" /> 
	  <id>http://www.mzwu.com/default.asp?id=2391</id>
  </entry>	
		
  <entry>
	  <title type="html"><![CDATA[戏说23种设计模式]]></title>
	  <author>
		 <name>dnawo</name>
		 <uri>http://www.mzwu.com/</uri>
		 <email>service@mzwu.com</email>
	  </author>
	  <category term="" scheme="http://www.mzwu.com/default.asp?cateID=17" label="设计模式" /> 
	  <updated>2010-03-08T18:57:41+08:00</updated>
	  <published>2010-03-08T18:57:41+08:00</published>
		  <summary type="html"><![CDATA[<span style="color:Brown">工厂方法模式：</span>定义一个用于创建对象的接口，让子类决定将哪一个类实例化。它使一个类的实例化延迟到其子类。<br/><span style="color:Brown">抽象工厂模式：</span>提供一个创建一系列相关或相互依赖对象的接口，而无需指定它们具体的类。 <br/><span style="color:Brown">建造模式：</span>将一个复杂对象的构建与它的表示分离，使得同样的构建过程可以创建不同的表示。<br/><span style="color:Brown">原型模式：</span>用原型实例指定创建对象的种类，并且通过拷贝这个原型来创建新的对象。 <br/><span style="color:Brown">单例模式：</span>保证一个类仅有一个实例，并提供一个访问它的全局访问点。<br/><span style="color:Brown">适配器模式：</span>将一个类的接口转换成客户希望的另外一个接口。它使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。<br/><span style="color:Brown">桥接模式：</span>将抽象部分与它的实现部分分离，使它们都可以独立地变化。<br/><span style="color:Brown">组合模式：</span>将对象组合成树形结构以表示“部分-整体”的层次结构。它使得客户对单个对象和复合对象的使用具有一致性。 <br/><span style="color:Brown">装饰模式：</span>动态地给一个对象添加一些额外的职责。就扩展功能而言，它比生成子类方式更为灵活。 <br/><span style="color:Brown">外观模式：</span>为子系统中的一组接口提供一个一致的界面， 它定义了一个高层接口，这个接口使得这一子系统更加容易使用。 <br/><span style="color:Brown">享元模式：</span>运用共享技术有效地支持大量细粒度的对象。 <br/><span style="color:Brown">代理模式：</span>为其他对象提供一个代理以控制对这个对象的访问。<br/><span style="color:Brown">观察者模式：</span>定义对象间的一种一对多的依赖关系，以便当一个对象的状态发生改变时，所有依赖于它的对象都得到通知并自动更新。<br/><span style="color:Brown">模板方法模式：</span>定义一个操作中的算法的骨架，而将一些步骤延迟到子类中。它使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。 <br/><span style="color:Brown">命令模式：</span>将一个请求封装为一个对象，从而使你可用不同的请求对客户进行参数化；对请求排队或记录请求日志，以及支持可取消的操作。 <br/><span style="color:Brown">状态模式：</span>允许一个对象在其内部状态改变时改变它的行为，让对象看起来似乎修改了它所属的类。<br/><span style="color:Brown">职责链模式：</span>为解除请求的发送者和接收者之间耦合，而使多个对象都有机会处理这个请求。将这些对象连成一条链，并沿着这条链传递该请求，直到有一个对象处理它。 <br/><span style="color:Brown">解释器模式：</span>给定一个语言， 定义它的文法的一种表示，并定义一个解释器， 该解释器使用该表示来解释语言中的句子。<br/><span style="color:Brown">中介模式：</span>用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用，从而使其耦合松散，而且可以独立地改变它们之间的交互。<br/><span style="color:Brown">访问者模式：</span>表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。 <br/><span style="color:Brown">策略模式：</span>定义一系列的算法，把它们一个个封装起来， 并且使它们可相互替换。本模式使得算法的变化可独立于使用它的客户。<br/><span style="color:Brown">备忘录模式：</span>在不破坏封装性的前提下，捕获一个对象的内部状态，并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。 <br/><span style="color:Brown">迭代器模式：</span>提供一种方法顺序访问一个聚合对象中各个元素， 而又不需暴露该对象的内部表示。<br/><br/><strong>从追MM中看设计模式：</strong><br/><br/><span style="color:Brown">简单工厂模式：</span>追MM少不了请吃饭了，麦当劳的鸡翅和肯德基的鸡翅都是MM爱吃的东西，虽然口味有所不同，但不管你带MM去麦当劳或肯德基，只管向服务员说“来四个鸡翅”就行了。麦当劳和肯德基就是生产鸡翅的Factory。<br/><span style="color:Brown">工厂方法模式：</span>请MM去麦当劳吃汉堡，不同的MM有不同的口味，要每个都记住是一件烦人的事情，我一般采用工厂方法模式，带着MM到服务员那儿，说“要一个汉堡”，具体要什么样的汉堡呢，让MM直接跟服务员说就行了。<br/><span style="color:Brown">建造模式：</span>MM最爱听的就是“我爱你”这句话了，见到不同地方的MM，要能够用她们的方言跟她说这句话哦，我有一个多种语言翻译机，上面每种语言都有一个按键，见到MM我只要按对应的键，它就能够用相应的语言说出“我爱你”这句话了，国外的MM也可以轻松搞掂，这就是我的“我爱你”builder(这一定比美军在伊拉克用的翻译机好卖)。<br/><span style="color:Brown">原型模式：</span>跟MM用QQ聊天，一定要说些深情的话语了，我搜集了好多肉麻的情话，需要时只要copy出来放到QQ里面就行了，这就是我的情话prototype了(100块钱一份，你要不要)。<br/><span style="color:Brown">单例模式：</span>俺有6个漂亮的老婆，她们的老公都是我，我就是我们家里的老公Sigleton，她们只要说道“老公”，都是指的同一个人，那就是我(刚才做了个梦啦，哪有这么好的事)。<br/><span style="color:Brown">适配器模式：</span>在朋友聚会上碰到了一个美女Sarah，从香港来的，可我不会说粤语，她不会说普通话，只好求助于我的朋友kent了，他作为我和Sarah之间的Adapter，让我和Sarah可以相互交谈了(也不知道他会不会耍我)。<br/><span style="color:Brown">桥接模式：</span>早上碰到MM，要说早上好，晚上碰到MM，要说晚上好；碰到MM穿了件新衣服，要说你的衣服好漂亮哦，碰到MM新做的发型，要说你的头发好漂亮哦。不要问我“早上碰到MM新做了个发型怎么说”这种问题，自己用BRIDGE组合一下不就行了。<br/><span style="color:Brown">组合模式：</span>Mary今天过生日。“我过生日，你要送我一件礼物。”“嗯，好吧，去商店，你自己挑。”“这件T恤挺漂亮，买，这条裙子好看，买，这个包也不错，买。”“喂，买了三件了呀，我只答应送一件礼物的哦。”“什么呀，T恤加裙子加包包，正好配成一套呀，小姐，麻烦你包起来。”“……”，MM都会用Composite模式了，你会了没有？<br/><span style="color:Brown">装饰模式：</span>Mary过完轮到Sarly过生日，还是不要叫她自己挑了，不然这个月伙食费肯定玩完，拿出我去年在华山顶上照的照片，在背面写上“最好的的礼物，就是爱你的Fita”，再到街上礼品店买了个像框(卖礼品的MM也很漂亮哦)，再找隔壁搞美术设计的Mike设计了一个漂亮的盒子装起来……，我们都是Decorator，最终都在修饰我这个人呀，怎么样，看懂了吗？<br/><span style="color:Brown">外观模式：</span>我有一个专业的Nikon相机，我就喜欢自己手动调光圈、快门，这样照出来的照片才专业，但MM可不懂这些，教了半天也不会。幸好相机有Facade设计模式，把相机调整到自动档，只要对准目标按快门就行了，一切由相机自动调整，这样MM也可以用这个相机给我拍张照片了。<br/><span style="color:Brown">享元模式：</span>每天跟MM发短信，手指都累死了，最近买了个新手机，可以把一些常用的句子存在手机里，要用的时候，直接拿出来，在前面加上MM的名字就可以发送了，再不用一个字一个字敲了。共享的句子就是Flyweight，MM的名字就是提取出来的外部特征，根据上下文情况使用。<br/><span style="color:Brown">代理模式：</span>跟MM在网上聊天，一开头总是“hi,你好”,“你从哪儿来呀？”“你多大了？”“身高多少呀？”这些话，真烦人，写个程序做为我的Proxy吧，凡是接收到这些话都设置好了自己的回答，接收到其他的话时再通知我回答，怎么样，酷吧。<br/><span style="color:Brown">观察者模式：</span>想知道咱们公司最新MM情报吗？加入公司的MM情报邮件组就行了，tom负责搜集情报，他发现的新情报不用一个一个通知我们，直接发布给邮件组，我们作为订阅者(观察者)就可以及时收到情报啦。 <br/><span style="color:Brown">模板方法模式：</span>看过《如何说服女生上床》这部经典文章吗？女生从认识到上床的不变的步骤分为巧遇、打破僵局、展开追求、接吻、前戏、动手、爱抚、进去八大步骤(Template method)，但每个步骤针对不同的情况，都有不一样的做法，这就要看你随机应变啦(具体实现)。<br/><span style="color:Brown">命令模式：</span>俺有一个MM家里管得特别严，没法见面，只好借助于她弟弟在我们俩之间传送信息，她对我有什么指示，就写一张纸条让她弟弟带给我。这不，她弟弟又传送过来一个COMMAND，为了感谢他，我请他吃了碗杂酱面，哪知道他说：“我同时给我姐姐三个男朋友送COMMAND，就数你最小气，才请我吃面”。<br/><span style="color:Brown">状态模式：</span>跟MM交往时，一定要注意她的状态哦，在不同的状态时她的行为会有不同，比如你约她今天晚上去看电影，对你没兴趣的MM就会说“有事情啦”，对你不讨厌但还没喜欢上的MM就会说“好啊，不过可以带上我同事么？”，已经喜欢上你的MM就会说“几点钟？看完电影再去泡吧怎么样？”，当然你看电影过程中表现良好的话，也可以把MM的状态从不讨厌不喜欢变成喜欢哦。<br/><span style="color:Brown">职责链模式：</span>晚上去上英语课，为了好开溜坐到了最后一排，哇，前面坐了好几个漂亮的MM哎，找张纸条，写上“Hi,可以做我的女朋友吗？如果不愿意请向前传”，纸条就一个接一个的传上去了，糟糕，传到第一排的MM把纸条传给老师了，听说是个老处女呀，快跑!<br/><span style="color:Brown">解释器模式：</span>俺有一个《泡MM真经》，上面有各种泡MM的攻略，比如说去吃西餐的步骤、去看电影的方法等等，跟MM约会时，只要做一个Interpreter，照着上面的脚本执行就可以了。<br/><span style="color:Brown">中介模式：</span>四个MM打麻将，相互之间谁应该给谁多少钱算不清楚了，幸亏当时我在旁边，按照各自的筹码数算钱，赚了钱的从我这里拿，赔了钱的也付给我，一切就OK啦，俺得到了四个MM的电话。<br/><span style="color:Brown">访问者模式：</span>情人节到了，要给每个MM送一束鲜花和一张卡片，可是每个MM送的花都要针对她个人的特点，每张卡片也要根据个人的特点来挑，我一个人哪搞得清楚，还是找花店老板和礼品店老板做一下Visitor，让花店老板根据MM的特点选一束花，让礼品店老板也根据每个人特点选一张卡，这样就轻松多了。<br/><span style="color:Brown">策略模式：</span>跟不同类型的MM约会，要用不同的策略，有的请电影比较好，有的则去吃小吃效果不错，有的去海边浪漫最合适，单目的都是为了得到MM的芳心，我的追MM锦囊中有好多Strategy哦。<br/><span style="color:Brown">备忘录模式：</span>同时跟几个MM聊天时，一定要记清楚刚才跟MM说了些什么话，不然MM发现了会不高兴的哦，幸亏我有个备忘录，刚才与哪个MM说了什么话我都拷贝一份放到备忘录里面保存，这样可以随时察看以前的记录啦。<br/><span style="color:Brown">迭代器模式：</span>我爱上了Mary，不顾一切的向她求婚。&nbsp;&nbsp; Mary：“想要我跟你结婚，得答应我的条件”&nbsp;&nbsp; 我：“什么条件我都答应，你说吧”&nbsp;&nbsp; Mary：“我看上了那个一克拉的钻石”&nbsp;&nbsp; 我：“我买，我买，还有吗？”&nbsp;&nbsp; Mary：“我看上了湖边的那栋别墅”&nbsp;&nbsp; 我：“我买，我买，还有吗？”&nbsp;&nbsp; Mary：“我看上那辆法拉利跑车”&nbsp;&nbsp; 我脑袋嗡的一声，坐在椅子上，一咬牙：“我买，我买，还有吗？”&nbsp;&nbsp; ……]]></summary>
	  <link rel="alternate" type="text/html" href="http://www.mzwu.com/article.asp?id=2390" /> 
	  <id>http://www.mzwu.com/default.asp?id=2390</id>
  </entry>	
		
</feed>
