<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Mingbo</title>
	<atom:link href="http://shao.mingbo.de/feed/" rel="self" type="application/rss+xml" />
	<link>http://shao.mingbo.de</link>
	<description>包括教育技术，编程，互联网等方面的文章及随想。</description>
	<lastBuildDate>Sun, 25 Jul 2010 05:18:53 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=abc</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>洪水来袭</title>
		<link>http://shao.mingbo.de/2010/07/25/2010-flood-record/</link>
		<comments>http://shao.mingbo.de/2010/07/25/2010-flood-record/#comments</comments>
		<pubDate>Sun, 25 Jul 2010 05:17:50 +0000</pubDate>
		<dc:creator>邵 明博</dc:creator>
				<category><![CDATA[碎碎念]]></category>
		<category><![CDATA[摄影]]></category>
		<category><![CDATA[武汉]]></category>
		<category><![CDATA[洪水]]></category>
		<category><![CDATA[生活]]></category>

		<guid isPermaLink="false">http://shao.mingbo.de/?p=691</guid>
		<description><![CDATA[媒体连篇累牍的报道，让人也想跃跃欲试，看看洪水来袭的武汉究竟变成了怎样。在骆大师的点化下，我决定这个周末不再继续宅下去&#8230;我决定，顶着炎炎烈日&#8230;记录一下这个特殊日子。于是便有——

拍摄路线：汉口江滩-长江大桥-武昌
拍摄时间：2010/07/25
拍摄主题：洪水来袭后的武汉
拍摄机器：Canon 400D / EF 24-70 2.8L
拍摄伙伴：骆大师&#8230;





更多精彩照片，点这里
]]></description>
			<content:encoded><![CDATA[<p>媒体连篇累牍的<a href="https://encrypted.google.com/search?q=%E6%AD%A6%E6%B1%89+%E6%B4%AA%E6%B0%B4&amp;hl=zh-CN&amp;newwindow=1&amp;prmd=nv&amp;source=univ&amp;tbs=nws:1&amp;tbo=u&amp;ei=gcVLTLjdPIb4tQPEodjmDw&amp;sa=X&amp;oi=news_group&amp;ct=title&amp;resnum=1&amp;ved=0CCYQsQQwAA" target="_blank">报道</a>，让人也想跃跃欲试，看看洪水来袭的武汉究竟变成了怎样。在骆大师的点化下，我决定这个周末不再继续宅下去&#8230;我决定，顶着炎炎烈日&#8230;记录一下这个特殊日子。于是便有——</p>
<ul>
<li>拍摄路线：汉口江滩-长江大桥-武昌</li>
<li>拍摄时间：2010/07/25</li>
<li>拍摄主题：洪水来袭后的武汉</li>
<li>拍摄机器：Canon 400D / EF 24-70 2.8L</li>
<li>拍摄伙伴：骆大师&#8230;</li>
</ul>
<p><a href="http://shao.mingbo.de/wp-content/uploads/2010/07/1.jpg"><img class="aligncenter size-full wp-image-693" title="汉口江滩" src="http://shao.mingbo.de/wp-content/uploads/2010/07/1.jpg" alt="1 洪水来袭" width="500" height="332" /></a><a href="http://shao.mingbo.de/wp-content/uploads/2010/07/3.jpg"></a></p>
<p><a href="http://shao.mingbo.de/wp-content/uploads/2010/07/5.jpg"><img class="aligncenter size-full wp-image-696" title="长江大桥" src="http://shao.mingbo.de/wp-content/uploads/2010/07/5.jpg" alt="5 洪水来袭" width="500" height="332" /></a><br />
<a href="http://shao.mingbo.de/wp-content/uploads/2010/07/3.jpg"><img class="aligncenter size-full wp-image-695" title="日落" src="http://shao.mingbo.de/wp-content/uploads/2010/07/3.jpg" alt="3 洪水来袭" width="500" height="332" /></a></p>
<p><a href="http://shao.mingbo.de/wp-content/uploads/2010/07/2.jpg"><img class="aligncenter size-full wp-image-694" title="龟山电视塔" src="http://shao.mingbo.de/wp-content/uploads/2010/07/2.jpg" alt="2 洪水来袭" width="332" height="500" /></a><br />
更多精彩照片，<a href="http://shao.mingbo.de/record-at-2010-flood-disaster/" target="_blank">点这里</a></p>
]]></content:encoded>
			<wfw:commentRss>http://shao.mingbo.de/2010/07/25/2010-flood-record/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>如何解决“连接被重置”的现象</title>
		<link>http://shao.mingbo.de/2010/05/23/how-to-resolve-be-gwfed-when-using-google/</link>
		<comments>http://shao.mingbo.de/2010/05/23/how-to-resolve-be-gwfed-when-using-google/#comments</comments>
		<pubDate>Sun, 23 May 2010 09:52:52 +0000</pubDate>
		<dc:creator>邵 明博</dc:creator>
				<category><![CDATA[网络应用]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[加密搜索]]></category>
		<category><![CDATA[连接重置]]></category>

		<guid isPermaLink="false">http://shao.mingbo.de/?p=687</guid>
		<description><![CDATA[已经不记得从什么时候起，使用Google 老爱被连接重置。有人总结了一下，目前搜索包含“吴”、“温”、“贾”、“李”、“习”、“贺”、“周”、“胡”等字的词语，会出现上述现象。这导致一些很常用的词语，例如“学习”、“胡萝卜”、“温度计”等无法在Google 搜索。具体的原因，本文不做详解，有需要的朋友请在本文指导下解决“重置”问题之后，进行深度搜索，方可获得解答。
Google 最近启用HTTPS 加密搜索服务。Google在官方博客介绍说，普通的HTTP浏览是不安全的，用户和服务器之间的通讯会被第三方监听和干扰，对于Google来说，你在Google搜索的词语会被第三方截获，如果第三方不希望你在Google搜索这个词语，还可以通过技术手段阻止用户的搜索行为。这也就是Google发布的beta版本的SSL加密搜索的原因，在HTTPS的Google搜索中，用户搜索的信息将无法被第三方获取，也不会出现数据泄漏的问题。目前HTTPS的Google搜索覆盖了Google网页搜索的部分产品，目前还不支持图片搜索和地图搜索，而其他搜素（资讯、博客、视频、动态等）都支持。
那关键问题是如何解决标题这个问题呢？不同的浏览器有不同的解决方案，请参见月光博客的这两篇博文：
Chrome 浏览器：Google支持HTTPS加密搜索
Firefox 和 IE8 浏览器：Google SSL搜索在FireFox和IE8中的解决方案
]]></description>
			<content:encoded><![CDATA[<p>已经不记得从什么时候起，使用Google 老爱被<strong>连接重置</strong>。有人总结了一下，目前搜索包含“吴”、“温”、“贾”、“李”、“习”、“贺”、“周”、“胡”等字的词语，会出现上述现象。这导致一些很常用的词语，例如“学习”、“胡萝卜”、“温度计”等无法在Google 搜索。具体的原因，本文不做详解，有需要的朋友请在本文指导下解决“重置”问题之后，进行深度搜索，方可获得解答。</p>
<p>Google 最近启用HTTPS 加密搜索服务。Google在官方博客<a href="http://googleblog.blogspot.com/2010/05/search-more-securely-with-encrypted.html" target="_blank">介绍说</a>，普通的HTTP浏览是不安全的，用户和服务器之间的通讯会被第三方监听和干扰，对于Google来说，你在Google搜索的词语会被第三方截获，如果第三方不希望你在Google搜索这个词语，还可以通过技术手段阻止用户的搜索行为。这也就是Google发布的beta版本的<strong><span style="color: #ff0000;">SSL加密</span></strong>搜索的<strong>原因，在HTTPS的Google搜索中，用户搜索的信息将无法被第三方获取，也不会出现数据泄漏的问题</strong>。目前HTTPS的Google搜索覆盖了Google网页搜索的部分产品，目前还不支持图片搜索和地图搜索，而其他搜素（资讯、博客、视频、动态等）都支持。</p>
<p>那关键问题是如何解决标题这个问题呢？不同的浏览器有不同的解决方案，请参见月光博客的这两篇博文：</p>
<p>Chrome 浏览器：<a href="http://www.williamlong.info/archives/2186.html" target="_blank">Google支持HTTPS加密搜索</a></p>
<p>Firefox 和 IE8 浏览器：<a href="http://www.williamlong.info/archives/2187.html" target="_blank">Google SSL搜索在FireFox和IE8中的解决方案</a></p>
]]></content:encoded>
			<wfw:commentRss>http://shao.mingbo.de/2010/05/23/how-to-resolve-be-gwfed-when-using-google/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>《当幸福来敲门》观后感</title>
		<link>http://shao.mingbo.de/2010/05/16/the-pursuit-of-happiness/</link>
		<comments>http://shao.mingbo.de/2010/05/16/the-pursuit-of-happiness/#comments</comments>
		<pubDate>Sun, 16 May 2010 08:03:54 +0000</pubDate>
		<dc:creator>邵 明博</dc:creator>
				<category><![CDATA[碎碎念]]></category>
		<category><![CDATA[当幸福来敲门]]></category>
		<category><![CDATA[电影]]></category>

		<guid isPermaLink="false">http://shao.mingbo.de/?p=680</guid>
		<description><![CDATA[
From the opening scene to the end, I was so moved by the love that Chris has for his son. It makes me to rethink about the meaning of happiness:
Happiness means a temperamental predominance of courage over timidity, of the appetite for adventure over the love of ease. So, No matter how bad the surrounding [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://shao.mingbo.de/wp-content/uploads/2010/05/2007223193259.5042910.jpg"><img class="aligncenter size-full wp-image-684" title="当幸福来敲门" src="http://shao.mingbo.de/wp-content/uploads/2010/05/2007223193259.5042910.jpg" alt="当幸福来敲门" width="500" height="653" /></a></p>
<p>From the opening scene to the end, I was so moved by the love that Chris has for his son. It makes me to rethink about the meaning of happiness:</p>
<p>Happiness means a temperamental predominance of courage over timidity, of the appetite for adventure over the love of ease. So, No matter how bad the surrounding is, it won’t take our opportunity off to be happy, No matter how old we are, the process of the pursuit is endless.</p>
<p>When everything around goes against you, as it happens, the more cowardly you are, the more aggressive they will be. So, the first rule is brave. And it is just the prerequisite for you to overcome the difficulties.</p>
<p>Whether 40 or 14, there is in every human being’s heart the lure of wonder, the unfailing appetite of what’s next. At this moment, we should always make sure the balance between what we have and what we want to have. After a decision has been made, the only thing we can do, and should do, is “just go for it”.</p>
<p>The final scene shows Chris walking with his son down a street. His son is telling him a joke, when a man in a suit walks past. Chris looks back as the man continues on. The man in the suit is none other than the real Chris Gardner. Yes, another man is pursuing his happiness just as Chris does.</p>
<p>更多关于该影片的信息，<a href="http://www.mtime.com/movie/48615/" target="_blank">点击这里</a></p>
<ul>
<li><strong>国家/地区：</strong> 美国</li>
<li><strong>类型：</strong> 传记  / 	剧情</li>
<li><strong>片长：</strong>117 min</li>
<li><strong>分级：</strong> USA:PG-13</li>
<li><strong>对白语言：</strong> 英语</li>
<li><strong>发行公司：</strong> Columbia TriStar Films de Argentina</li>
<li><strong>官方网站：</strong> <a href="http://www.columbia.fr/alarecherchedubonheur/">Gaumont Columbia Tristar</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://shao.mingbo.de/2010/05/16/the-pursuit-of-happiness/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>设计模式学习总结</title>
		<link>http://shao.mingbo.de/2010/05/09/design-pattern/</link>
		<comments>http://shao.mingbo.de/2010/05/09/design-pattern/#comments</comments>
		<pubDate>Sun, 09 May 2010 11:39:22 +0000</pubDate>
		<dc:creator>邵 明博</dc:creator>
				<category><![CDATA[设计模式]]></category>
		<category><![CDATA[总结]]></category>

		<guid isPermaLink="false">http://shao.mingbo.de/?p=675</guid>
		<description><![CDATA[这段时间更新了很多篇有关设计模式的学习笔记，收获不算太多，但起码让我对面向对象编程有了一个更深刻的认识。模式与模式之间没有界限分明的三八线，也没有一个万能的模式主宰了Programmer 的编程思维。模式学习到最后，Visitor 与Strategy 的笔记也实在没有动力更新下去，只打算在这篇设计模式笔记的大总结里，稍作复习。
不要问我还记得哪些模式的哪些细节，他们无非是，1）面向接口编程；2）使用对象组合来解耦，努力避免继承；3）在易碎变化的地方进行封装。把面向的对象的精髓“封装、继承、多态”发挥到一定境界，就是模式了。
在学习设计模式之前，其实还有一点畏惧的情绪在里面。学习的过程中，发现，这样的模式，全然都是前辈们的经验。学习完之后，感觉自己还是内功不够，比如：数据结构。虽然，目前把这些模式都领略了一遍，但可以很清楚的意识到很多内在的精髓不一定内化到自己的脑袋里。今后在工程中可能还需要回过头来重新学习。这里把一个提纲式的笔记列一下：

创建模式


Singleton模式解决的是实体对象个数的问题。除了Singleton之外，其他创建型模式解决的都是new所带来的耦合关系。
Factory Method, Abstract Factory, Builder都需要一个额外的工厂类来负责实例化“易变对象”，而Prototype则是通过原型（一个特殊的工厂类）来克隆“易变对象”。



结构模式


Adapter模式注重转换接口，将不吻合的接口适配对接
Bridge模式注重分离接口与其实现，支持多维度变化
Composite模式注重统一接口，将“一对多”的关系转化为“一对一”的关系
Decorator模式注重稳定接口，在此前提下为对象扩展功能
Facade模式注重简化接口，简化组件系统与外部客户程序的依赖关系
Flyweight 模式注重保留接口，在内部使用共享技术对对象存储进行优化
Proxy 模式注重假借接口，增加间接层来实现灵活控制



行为模式


Template Method模式封装算法结构，支持算法子步骤变化
State模式注重封装与状态相关的行为，支持状态的变化
Memento模式注重封装对象状态变化，支持状态保存/恢复
Mediator模式注重封装对象间的交互，支持对象交互的变化
Chain Of Responsibility模式注重封装对象责任，支持责任的变化
Command模式注重将请求封装为对象，支持请求的变化
Interpreter模式注重封装特定领域变化，支持领域问题的频繁变化
Observer模式注重封装对象通知，支持通信对象的变化
Visitor模式注重封装对象操作变化，支持在运行时为类层次结构动态添加新的操作。
Strategy模式注重封装算法，支持算法的变化
Iterator 模式注重封装集合对象内部结构，支持集合的变化


这段时间的学习告一段落，我想，这更是一个新的起点，对于如何阅读、学习别人的代码，会有很大的提升。

]]></description>
			<content:encoded><![CDATA[<p>这段时间更新了很多篇有关<a href="http://shao.mingbo.de/category/csharp%e7%ac%94%e8%ae%b0/%e8%ae%be%e8%ae%a1%e6%a8%a1%e5%bc%8f/" target="_blank">设计模式</a>的学习笔记，收获不算太多，但起码让我对面向对象编程有了一个更深刻的认识。模式与模式之间没有界限分明的三八线，也没有一个万能的模式主宰了Programmer 的编程思维。模式学习到最后，Visitor 与Strategy 的笔记也实在没有动力更新下去，只打算在这篇设计模式笔记的大总结里，稍作复习。</p>
<p>不要问我还记得哪些模式的哪些细节，他们无非是，1）面向接口编程；2）使用对象组合来解耦，努力避免继承；3）在易碎变化的地方进行封装。把面向的对象的精髓“封装、继承、多态”发挥到一定境界，就是模式了。</p>
<p>在学习设计模式之前，其实还有一点畏惧的情绪在里面。学习的过程中，发现，这样的模式，全然都是前辈们的经验。学习完之后，感觉自己还是内功不够，比如：数据结构。虽然，目前把这些模式都领略了一遍，但可以很清楚的意识到很多内在的精髓不一定内化到自己的脑袋里。今后在工程中可能还需要回过头来重新学习。这里把一个提纲式的笔记列一下：</p>
<div id="_mcePaste">
<div id="_mcePaste"><strong>创建模式</strong></div>
<div id="_mcePaste">
<ul>
<li><a href="http://shao.mingbo.de/2010/03/15/singlton-at-the-first-sight/" target="_blank">Singleton模式</a>解决的是实体对象个数的问题。除了Singleton之外，其他创建型模式解决的都是new所带来的耦合关系。</li>
<li><a href="http://shao.mingbo.de/2010/04/16/factory-method-pattern/" target="_blank">Factory Method</a>, <a href="http://shao.mingbo.de/2010/03/18/abstract-factory-at-the-first-sight/" target="_blank">Abstract Factory</a>,<a href="http://shao.mingbo.de/2010/04/16/builder-pattern/" target="_blank"> Builder</a>都需要一个额外的工厂类来负责实例化“易变对象”，而<a href="http://shao.mingbo.de/2010/04/15/prototype-pattern/" target="_blank">Prototype</a>则是通过原型（一个特殊的工厂类）来克隆“易变对象”。</li>
</ul>
</div>
<div id="_mcePaste"></div>
<div id="_mcePaste"><strong>结构模式</strong></div>
<div id="_mcePaste">
<ul>
<li><a href="http://shao.mingbo.de/2010/04/22/adaptor-pattern/" target="_blank">Adapter模式</a>注重转换接口，将不吻合的接口适配对接</li>
<li><a href="http://shao.mingbo.de/2010/04/24/bridge-pattern/" target="_blank">Bridge模式</a>注重分离接口与其实现，支持多维度变化</li>
<li><a href="http://shao.mingbo.de/2010/04/14/composite-pattern/" target="_blank">Composite模式</a>注重统一接口，将“一对多”的关系转化为“一对一”的关系</li>
<li><a href="http://shao.mingbo.de/2010/04/24/decorator-pattern/" target="_blank">Decorator模式</a>注重稳定接口，在此前提下为对象扩展功能</li>
<li><a href="http://shao.mingbo.de/2010/04/26/facade-pattern/" target="_blank">Facade模式</a>注重简化接口，简化组件系统与外部客户程序的依赖关系</li>
<li><a href="http://shao.mingbo.de/2010/04/27/flyweight-pattern/" target="_blank">Flyweight 模式</a>注重保留接口，在内部使用共享技术对对象存储进行优化</li>
<li><a href="http://shao.mingbo.de/2010/04/27/proxy-pattern/" target="_blank">Proxy 模式</a>注重假借接口，增加间接层来实现灵活控制</li>
</ul>
</div>
<div id="_mcePaste"></div>
<div id="_mcePaste"><strong>行为模式</strong></div>
<div id="_mcePaste">
<ul>
<li><a href="http://shao.mingbo.de/2010/04/27/template-pattern/" target="_blank">Template Method模式</a>封装算法结构，支持算法子步骤变化</li>
<li><a href="http://shao.mingbo.de/2010/05/06/state-pattern/" target="_blank">State模式</a>注重封装与状态相关的行为，支持状态的变化</li>
<li><a href="http://shao.mingbo.de/2010/05/06/memento-pattern/" target="_blank">Memento模式</a>注重封装对象状态变化，支持状态保存/恢复</li>
<li><a href="http://shao.mingbo.de/2010/05/04/mediator-pattern/" target="_blank">Mediator模式</a>注重封装对象间的交互，支持对象交互的变化</li>
<li><a href="http://shao.mingbo.de/2010/05/05/chain-of-responsibility-pattern/" target="_blank">Chain Of Responsibility模式</a>注重封装对象责任，支持责任的变化</li>
<li><a href="http://shao.mingbo.de/2010/04/28/command-pattern/" target="_blank">Command模式</a>注重将请求封装为对象，支持请求的变化</li>
<li><a href="http://shao.mingbo.de/2010/05/01/interpretor-pattern/" target="_blank">Interpreter模式</a>注重封装特定领域变化，支持领域问题的频繁变化</li>
<li><a href="http://shao.mingbo.de/2010/05/04/observer-patter/" target="_blank">Observer模式</a>注重封装对象通知，支持通信对象的变化</li>
<li>Visitor模式注重封装对象操作变化，支持在运行时为类层次结构动态添加新的操作。</li>
<li>Strategy模式注重封装算法，支持算法的变化</li>
<li>Iterator 模式注重封装集合对象内部结构，支持集合的变化</li>
</ul>
</div>
<p>这段时间的学习告一段落，我想，这更是一个新的起点，对于如何阅读、学习别人的代码，会有很大的提升。</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://shao.mingbo.de/2010/05/09/design-pattern/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>初尝State 模式</title>
		<link>http://shao.mingbo.de/2010/05/06/state-pattern/</link>
		<comments>http://shao.mingbo.de/2010/05/06/state-pattern/#comments</comments>
		<pubDate>Thu, 06 May 2010 13:24:59 +0000</pubDate>
		<dc:creator>邵 明博</dc:creator>
				<category><![CDATA[设计模式]]></category>
		<category><![CDATA[state]]></category>
		<category><![CDATA[状态模式]]></category>

		<guid isPermaLink="false">http://shao.mingbo.de/?p=668</guid>
		<description><![CDATA[当对象拥有不同的状态，往往会导致行为不同。在软件构建过程中，某些对象的状态如果改变，其行为也会随之而发生变化，比如文档处于只读状态，其支持的行为和读写状态支持的行为就可能完全不同。如何在运行时根据对象的状态来透明地更改对象的行为？而不会为对象操作和状态转化之间引入紧耦合？
意图
允许一个对象在其内部状态改变时改变它的行为。从而使对象看起来似乎修改了其行为。
结构图

话说，状态的改变也能用if-else 来完成逻辑演绎，但如果系统中增添了新的状态，则耦合的代码，就显得疲惫不堪了。如果状态很多，程序员自己也很难维护。这里的state 模式，将状态改变时影响的行为抽象到一个类里，用一个个具体的子类来表达不同的状态，从而很好的封装了变化点。
代码

using System;

namespace State
{
    class Program
    {
        static void Main(string[] args)
        {
            Document doc = new Document();
       [...]]]></description>
			<content:encoded><![CDATA[<p>当对象拥有不同的状态，往往会导致行为不同。在软件构建过程中，某些对象的状态如果改变，其行为也会随之而发生变化，比如文档处于只读状态，其支持的行为和读写状态支持的行为就可能完全不同。如何在运行时根据对象的状态来透明地更改对象的行为？而不会为对象操作和状态转化之间引入紧耦合？</p>
<p><strong>意图</strong></p>
<p>允许一个对象在其内部状态改变时改变它的行为。从而使对象看起来似乎修改了其行为。</p>
<p><strong>结构图</strong></p>
<p><strong><a href="http://shao.mingbo.de/wp-content/uploads/2010/05/state-结构图.jpg"><img class="aligncenter size-full wp-image-670" title="state 结构图" src="http://shao.mingbo.de/wp-content/uploads/2010/05/state-结构图.jpg" alt="state 结构图" width="402" height="190" /></a></strong></p>
<p>话说，状态的改变也能用if-else 来完成逻辑演绎，但如果系统中增添了新的状态，则耦合的代码，就显得疲惫不堪了。如果状态很多，程序员自己也很难维护。这里的state 模式，将状态改变时影响的行为抽象到一个类里，用一个个具体的子类来表达不同的状态，从而很好的封装了变化点。</p>
<p><strong>代码</strong></p>
<pre name="code" class="csharp">
using System;

namespace State
{
    class Program
    {
        static void Main(string[] args)
        {
            Document doc = new Document();
            Editable edit = new Editable();
            Insert ins = new Insert();
            edit.NextState = ins;
            doc.SetState(edit);
            doc.Handle();
            //查看轮换后的效果
            doc.Handle();
        }
    }

    abstract class StatedWithDocument {
        StatedWithDocument nextState;

        public StatedWithDocument NextState
        {
            get { return nextState; }
            set { nextState = value; }
        }

        public abstract void Handle();

    }
    class Document {
        StatedWithDocument state;

        public void SetState(StatedWithDocument state) {
            this.state = state;
        }
        public void Handle() {
            this.state.Handle();
            //也许需要轮换
            this.state = this.state.NextState;
        }
    }
    class Editable : StatedWithDocument {
        public override void Handle() {
            Console.WriteLine("Now,I'm Editable...");
        }
    }

    class Insert : StatedWithDocument {
        public override void Handle() {
            Console.WriteLine("Now,I'm Insertable...");
        }
    }
}
</pre>
<p><strong>运行结果</strong></p>
<p><strong><a href="http://shao.mingbo.de/wp-content/uploads/2010/05/state-运行结果.jpg"><img class="aligncenter size-full wp-image-671" title="state 运行结果" src="http://shao.mingbo.de/wp-content/uploads/2010/05/state-运行结果.jpg" alt="state 运行结果 初尝State 模式" width="245" height="124" /></a><br />
</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://shao.mingbo.de/2010/05/06/state-pattern/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>初尝Memento 模式</title>
		<link>http://shao.mingbo.de/2010/05/06/memento-pattern/</link>
		<comments>http://shao.mingbo.de/2010/05/06/memento-pattern/#comments</comments>
		<pubDate>Thu, 06 May 2010 07:12:12 +0000</pubDate>
		<dc:creator>邵 明博</dc:creator>
				<category><![CDATA[设计模式]]></category>
		<category><![CDATA[memento]]></category>
		<category><![CDATA[备忘录模式]]></category>

		<guid isPermaLink="false">http://shao.mingbo.de/?p=661</guid>
		<description><![CDATA[在软件构建过程中，某些对象的状态在转换过程中，可能由于某种需要，要求程序能够回溯到对象之前处于某个点时的状态。如果使用一些公有接口来让其他对象得到对象的状态，便会暴露对象的细节实现。
如何实现对象状态的良好保存与恢复？但同时又不会因此而破坏对象本身的封装性。
意图
在不破坏封装性的前提下，捕获一个对象的内部状态，并在该对象之外保存这个状态。这样以后就可以将该对象恢复到原先保存的状态。
结构图


其实结构图中Caretaker 不一定必须实现，不难发现的是，他是对“备忘录”中保存的状态的起到一种暂存的作用。下面是一段代码：

using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

namespace Memento
{
    class Program
    {
        static void Main(string[] args)
        {
            Person A = new Person("A");
     [...]]]></description>
			<content:encoded><![CDATA[<p>在软件构建过程中，某些对象的状态在转换过程中，可能由于某种需要，要求程序能够回溯到对象之前处于某个点时的状态。如果使用一些公有接口来让其他对象得到对象的状态，便会暴露对象的细节实现。</p>
<p>如何实现对象状态的良好保存与恢复？但同时又不会因此而破坏对象本身的封装性。</p>
<p><strong>意图</strong></p>
<p>在不破坏封装性的前提下，捕获一个对象的内部状态，并在该对象之外保存这个状态。这样以后就可以将该对象恢复到原先保存的状态。</p>
<p><strong>结构图</strong></p>
<p><strong><a href="http://shao.mingbo.de/wp-content/uploads/2010/05/Memento结构图.jpg"><img class="aligncenter size-full wp-image-662" title="Memento结构图" src="http://shao.mingbo.de/wp-content/uploads/2010/05/Memento结构图.jpg" alt="Memento结构图 初尝Memento 模式" width="456" height="192" /></a><br />
</strong></p>
<p>其实结构图中Caretaker 不一定必须实现，不难发现的是，他是对“备忘录”中保存的状态的起到一种暂存的作用。下面是一段代码：</p>
<pre>
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

namespace Memento
{
    class Program
    {
        static void Main(string[] args)
        {
            Person A = new Person("A");
            Person B = new Person("B");
            Person C = new Person("C");

            HRSystem hr = new HRSystem();
            hr.Add(A);
            hr.Add(B);
            Memento m = hr.CreatMemento();
            hr.Add(C);
            Console.WriteLine("After added C, we have :");
            hr.ShowInfo();
            Console.WriteLine("But, I've made a mistake...So:");
            hr.RecoverToMemento(m);
            hr.ShowInfo();
        }
    }
    [Serializable]
    class Person {
        private string name;

        public string Name
        {
            get { return name; }
            set { name = value; }
        }
        public Person(string name) {
            this.name = name;
        }
    }
    [Serializable]
    class HRSystem {
        List<Person> list = new List<Person>();

        public void ShowInfo() {
            Console.WriteLine("-----------------");
            foreach (Person p in list) {
                Console.WriteLine("{0} is available .",p.Name);
            }
            Console.WriteLine("-----------------");
        }

        public void Add(Person p) {
            if (list != null &#038;&#038; !list.Contains(p)) {
                list.Add(p);
                Console.WriteLine("{0} has been added!", p.Name);
            }
        }

        public void Remove(Person p) {
            if (list != null &#038;&#038; list.Contains(p)) {
                Console.WriteLine("{0} has been removed!",p.Name);
            }

        }

        public void SetHRList(HRSystem hr) {
            this.list = hr.list;
        }

        public Memento CreatMemento() {
            Console.WriteLine("Now ,Saving State above ↑...");
            return new Memento().SetMemento(this);
        }

        public void RecoverToMemento(Memento m) {
            Console.WriteLine("Recovering To Memento...");
            HRSystem hr = (HRSystem)m.GetMemento();
            this.SetHRList(hr);
        }

    }

    class Memento {
        MemoryStream ms = new MemoryStream();
        BinaryFormatter bf = new BinaryFormatter();
        public Memento SetMemento(object obj) {
            bf.Serialize(ms,obj);
            return this;
        }

        public object GetMemento() {
            ms.Seek(0,SeekOrigin.Begin);
            return bf.Deserialize(ms);
        }

    }

}
</pre>
<p><strong>运行截图</strong></p>
<p><strong><a href="http://shao.mingbo.de/wp-content/uploads/2010/05/Memento运行结果.jpg"><img class="aligncenter size-full wp-image-663" title="Memento运行结果" src="http://shao.mingbo.de/wp-content/uploads/2010/05/Memento运行结果.jpg" alt="Memento运行结果 初尝Memento 模式" width="293" height="358" /></a><br />
</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://shao.mingbo.de/2010/05/06/memento-pattern/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>初尝Chain Of Responsibility</title>
		<link>http://shao.mingbo.de/2010/05/05/chain-of-responsibility-pattern/</link>
		<comments>http://shao.mingbo.de/2010/05/05/chain-of-responsibility-pattern/#comments</comments>
		<pubDate>Wed, 05 May 2010 12:38:09 +0000</pubDate>
		<dc:creator>邵 明博</dc:creator>
				<category><![CDATA[设计模式]]></category>
		<category><![CDATA[Chain Of Responsibility]]></category>
		<category><![CDATA[职责链模式]]></category>

		<guid isPermaLink="false">http://shao.mingbo.de/?p=654</guid>
		<description><![CDATA[在软件构建过程中，一个请求可能被多个对象处理，但是每个请求在运行时只能有一个接受者，如果显式指定，将必不可少地带来请求发送者与接受者的紧耦合。如何使请求的发送者不需要指定具体的接受者？让请求的接受者自己在运行时决定来处理请求，从而使两者解耦。
意图
使多个对象都有机会处理请求，从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链，并沿着这条链传递请求，直到有一个对象处理它为止。
结构图

职责链模式在其内部实现了一个自我的链式结构，采用了和Decorator 模式一样的方法，不但继承了自己，还要包含自己。下面的代码，模拟了一个公司处理订单的业务逻辑，多少金额内，什么级别的人可以处理。
代码

using System;

namespace Chain_of_Responsibility
{
    class Program
    {
        static void Main(string[] args)
        {
            Purchase p = new Purchase(2012,9678.89,"Diamond For Women");
      [...]]]></description>
			<content:encoded><![CDATA[<p>在软件构建过程中，一个请求可能被多个对象处理，但是每个请求在运行时只能有一个接受者，如果显式指定，将必不可少地带来请求发送者与接受者的紧耦合。如何使请求的发送者不需要指定具体的接受者？让请求的接受者自己在运行时决定来处理请求，从而使两者解耦。</p>
<p><strong>意图</strong></p>
<p>使多个对象都有机会处理请求，从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链，并沿着这条链传递请求，直到有一个对象处理它为止。</p>
<p><strong>结构图</strong></p>
<p><a href="http://shao.mingbo.de/wp-content/uploads/2010/05/职责链结构图.jpg"><img class="aligncenter size-full wp-image-656" title="职责链结构图" src="http://shao.mingbo.de/wp-content/uploads/2010/05/职责链结构图.jpg" alt="职责链结构图 初尝Chain Of Responsibility" width="327" height="196" /></a>
<p>职责链模式在其内部实现了一个自我的链式结构，采用了和Decorator 模式一样的方法，不但继承了自己，还要包含自己。下面的代码，模拟了一个公司处理订单的业务逻辑，多少金额内，什么级别的人可以处理。</p>
<p><strong>代码</strong></p>
<pre name="code" class="csharp">
using System;

namespace Chain_of_Responsibility
{
    class Program
    {
        static void Main(string[] args)
        {
            Purchase p = new Purchase(2012,9678.89,"Diamond For Women");
            President president = new President();
            VicePresident vicepresident = new VicePresident("Nobody-Care", president);
            Director director = new Director("Impp", vicepresident);

            director.ProcessRequest(p);
            p = new Purchase(2013, 159678.00, "Car For Women");
            director.ProcessRequest(p);
            p = new Purchase(2014, 459678.00, "House For Women");
            director.ProcessRequest(p);
        }
    }
    class Purchase {
        private int _number;

        public int Number
        {
            get { return _number; }
            set { _number = value; }
        }
        private double _amount;

        public double Amount
        {
            get { return _amount; }
            set { _amount = value; }
        }
        private string _purpose;

        public string Purpose
        {
            get { return _purpose; }
            set { _purpose = value; }
        }

        public Purchase(int number,double amount,string purpose) {
            this._amount = amount;
            this._number = number;
            this._purpose = purpose;
        }
    }

    abstract class Approver {
        protected Approver _successor;

        internal Approver Successor
        {
            get { return _successor; }
            set { _successor = value; }
        }
        private string _name;

        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }

        public Approver(string name,Approver successor) {
            this._name = name;
            this._successor = successor;
        }

        public virtual void ProcessRequest(Purchase p) {
            if (this._successor != null) {
                this._successor.ProcessRequest(p);
            }
        }

    }

    class Director : Approver {
        public Director(string name, Approver successor) : base(name, successor) { }
        public Director() : base("Director", null) { }
        public override void ProcessRequest(Purchase p)  {
            if (p.Amount < 10000) {
                Console.WriteLine("{0} approved reqest #{1}",this.GetType().Name,p.Number);
            }
            else
                base.ProcessRequest(p);
        }
    }

    class VicePresident : Approver {
        public VicePresident(string name, Approver successor) : base(name, successor) { }
        public VicePresident() : base("Director", null) { }
        public override void ProcessRequest(Purchase p) {
            if(p.Amount<200000){
                Console.WriteLine("{0} approved reqest #{1}", this.GetType().Name, p.Number);
            }
            else
                base.ProcessRequest(p);
        }
    }

    class President : Approver {
        public President(string name, Approver successor) : base(name, successor) { }
        public President() : base("Director", null) { }
        public override void ProcessRequest(Purchase p)  {
            if (p.Amount < 500000) {
                Console.WriteLine("{0} approved reqest #{1}", this.GetType().Name, p.Number);
            }
            else
                Console.WriteLine("Request #{0} needs an excutive meeting!",p.Number);
        }
    }
}
</pre>
<p><strong>运行结果</strong></p>
<p><strong><a href="http://shao.mingbo.de/wp-content/uploads/2010/05/职责链运行结果.jpg"><img class="aligncenter size-full wp-image-657" title="职责链运行结果" src="http://shao.mingbo.de/wp-content/uploads/2010/05/职责链运行结果.jpg" alt="职责链运行结果 初尝Chain Of Responsibility" width="323" height="122" /></a><br />
</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://shao.mingbo.de/2010/05/05/chain-of-responsibility-pattern/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>初尝Observer 模式</title>
		<link>http://shao.mingbo.de/2010/05/04/observer-patter/</link>
		<comments>http://shao.mingbo.de/2010/05/04/observer-patter/#comments</comments>
		<pubDate>Tue, 04 May 2010 09:42:15 +0000</pubDate>
		<dc:creator>邵 明博</dc:creator>
				<category><![CDATA[设计模式]]></category>
		<category><![CDATA[observer]]></category>
		<category><![CDATA[观察者模式]]></category>

		<guid isPermaLink="false">http://shao.mingbo.de/?p=649</guid>
		<description><![CDATA[观察者模式又叫做发布-订阅（Publish/Subscribe）模式、模型-视图（Model/View）模式、源-监听器（Source/Listener）模式或从属者（Dependents）模式。在软件构建过程中，我们需要为某些对象建立一种“通知依赖关系” ——一个对象（目标对象）的状态发生改变，所有的依赖对象（观察者对象）都将得到通知。如果这样的依赖关系过于紧密，将使软件不能很好地抵御变化。使用面向对象技术，可以将这种依赖关系弱化，并形成一种稳定的依赖关系。从而实现软件体系结构的松耦合。
意图
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时, 所有依赖于它的对象都得到通知并被自动更新。
结构图
从具体主题角色指向抽象观察者角色的合成关系，代表具体主题对象可以有任意多个对抽象观察者对象的引用。之所以使用抽象观察者而不是具体观察者，意味着主题对象不需要知道引用了哪些ConcreteObserver类型，而只知道抽象Observer类型。这就使得具体主题对象可以动态地维护一系列的对观察者对象的引用，并在需要的时候调用每一个观察者共有的Update()方法。这种做法叫做&#8221;面向接口编程&#8221;。
实际上在C#中实现Observer模式没有这么辛苦，.NET中提供了Delegate与Event机制，我们可以利用这种机制简化Observer模式。下面我会用一段代码同时演示2种模式。
代码

using System;
using System.Collections.Generic;

namespace Observer
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("------------------------------");
           [...]]]></description>
			<content:encoded><![CDATA[<p>观察者模式又叫做发布-订阅（Publish/Subscribe）模式、模型-视图（Model/View）模式、源-监听器（Source/Listener）模式或从属者（Dependents）模式。在软件构建过程中，我们需要为某些对象建立一种“通知依赖关系” ——一个对象（目标对象）的状态发生改变，所有的依赖对象（观察者对象）都将得到通知。如果这样的依赖关系过于紧密，将使软件不能很好地抵御变化。使用面向对象技术，可以将这种依赖关系弱化，并形成一种稳定的依赖关系。从而实现软件体系结构的松耦合。</p>
<p><strong>意图</strong></p>
<p>定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时, 所有依赖于它的对象都得到通知并被自动更新。</p>
<p><strong>结构图</strong></p>
<p><strong><a href="http://shao.mingbo.de/wp-content/uploads/2010/05/Observer-结构图.jpg"><img class="aligncenter size-full wp-image-650" title="Observer 结构图" src="http://shao.mingbo.de/wp-content/uploads/2010/05/Observer-结构图.jpg" alt="Observer 结构图" width="394" height="315" /></a><span style="font-weight: normal;">从具体主题角色指向抽象观察者角色的合成关系，代表具体主题对象可以有任意多个对抽象观察者对象的引用。之所以使用抽象观察者而不是具体观察者，意味着</span>主题对象不需要知道引用了哪些ConcreteObserver类型，而只知道抽象Observer类型<span style="font-weight: normal;">。这就使得具体主题对象可以动态地维护一系列的对观察者对象的引用，并在需要的时候调用每一个观察者共有的Update()方法。这种做法叫做&#8221;面向接口编程&#8221;。</span></strong></p>
<p><strong><span style="font-weight: normal;">实际上在C#中实现Observer模式没有这么辛苦，<span style="color: #ff0000;">.NET中提供了Delegate与Event机制</span>，我们可以利用这种机制简化Observer模式。下面我会用一段代码同时演示2种模式。</span></strong></p>
<p><strong>代码</strong></p>
<pre name="code" class="csharp">
using System;
using System.Collections.Generic;

namespace Observer
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("------------------------------");
            Console.WriteLine("使用观察者模式：");
            Email e = new Email();
            Mobole m = new Mobole();

            Microsoft ms = new Microsoft();
            ms.Add(e);
            ms.Add(m);
            ms.Price = 50;
            Console.WriteLine();
            Google g = new Google();
            g.Add(e); g.Add(m);
            g.Price = 220;
            Console.WriteLine("------------------------------");

            Console.WriteLine("使用Event 模式：");
            Google g2 = new Google();
            g2.priceChange += e.Update;
            g2.Price = 300;
            Microsoft m2 = new Microsoft();
            m2.priceChange += m.Update;
            m2.Price = 100;

        }
    }

    public interface IObserver {
        void Update(string symbol,decimal price);
    }

    public delegate void PriceChangeHandler(string symbol,decimal price);
    abstract class Stock {
        private string _symbol;
        private decimal _price;
        protected List<IObserver> list = new List<IObserver>();
        public event PriceChangeHandler priceChange;

        public decimal Price {
            get { return _price; }
            set {
                _price = value;
                this.Notify(this._symbol,this._price);
                this.OnChange(this._symbol, this._price);
            }
        }
        void OnChange(string symbol,decimal price) {
            if (priceChange != null)
                priceChange(symbol,price);
        }

        public Stock(string sysbol,decimal price) {
            this._price = price;
            this._symbol = sysbol;
        }

        public void Add(IObserver ob)  {
            list.Add(ob);
        }
        public void Remove(IObserver ob)  {
            list.Add(ob);
        }
        protected virtual void Notify(string symbol, decimal price)  {
            foreach (IObserver ob in list)
                ob.Update(symbol, price);
        }
    }

    class Microsoft:Stock {
        public Microsoft():base("Microsoft",120) { }
    }
    class Google : Stock {
        public Google() : base("Google", 200) { }
    }

    class Email:IObserver {
        public void Update(string symbol,decimal price) {
            Console.WriteLine("尊敬的客户，您使用Email 订阅了{0} 的股票，它的最新价格为 {1}!",symbol,price);
        }
    }
    class Mobole : IObserver {
        public void Update(string symbol, decimal price) {
            Console.WriteLine("尊敬的客户，您使用Mobile 订阅了{0} 的股票，它的最新价格为 {1}!", symbol, price);
        }
    }

}
</pre>
<p><strong>运行结果</strong></p>
<p style="text-align: center;"><strong><a href="http://shao.mingbo.de/wp-content/uploads/2010/05/Observer-运行结果.jpg"><img class="aligncenter size-full wp-image-651" title="Observer 运行结果" src="http://shao.mingbo.de/wp-content/uploads/2010/05/Observer-运行结果.jpg" alt="Observer 运行结果" width="459" height="220" /></a><br />
</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://shao.mingbo.de/2010/05/04/observer-patter/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>初尝Mediator 模式</title>
		<link>http://shao.mingbo.de/2010/05/04/mediator-pattern/</link>
		<comments>http://shao.mingbo.de/2010/05/04/mediator-pattern/#comments</comments>
		<pubDate>Tue, 04 May 2010 06:53:45 +0000</pubDate>
		<dc:creator>邵 明博</dc:creator>
				<category><![CDATA[设计模式]]></category>
		<category><![CDATA[mediator]]></category>
		<category><![CDATA[中介模式]]></category>

		<guid isPermaLink="false">http://shao.mingbo.de/?p=643</guid>
		<description><![CDATA[在日常生活中，我们经常会遇到多个事物相互之间都有联系的例子。例如：聊天室。
在软件构建过程中，经常会出现多个对象互相关联交互的情况，对象之间常常会维持一种复杂的引用关系，如果遇到一些需求的更改，这种直接的引用关系将面临不断的变化。在这种情况下，我们可使用一个“中介对象”来管理对象间的关联关系，避免相互交互的对象之间的紧耦合引用关系，从而更好地抵御变化。
意图
用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式的相互引用，从而使其耦合松散，而且可以独立地改变它们之间的交互。
结构图

在这里，我们模拟一个聊天室的程序，用户既可以对特定的对象进行发送消息，也可以向所有人say hello。我们用一个mediator 对象进行管理他们之间的联系。值得指出的是，代码中，仍有值得抽象的接口。
代码：

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Mediator
{
    class Program
    {
        static void Main(string[] args)
        {
            ChatRoom cr = new ChatRoom();
    [...]]]></description>
			<content:encoded><![CDATA[<p>在日常生活中，我们经常会遇到多个事物相互之间都有联系的例子。例如：聊天室。</p>
<p>在软件构建过程中，经常会出现多个对象互相关联交互的情况，对象之间常常会维持一种复杂的引用关系，如果遇到一些需求的更改，这种直接的引用关系将面临不断的变化。在这种情况下，我们可使用一个“中介对象”来管理对象间的关联关系，避免相互交互的对象之间的紧耦合引用关系，从而更好地抵御变化。</p>
<p><strong>意图</strong></p>
<p><strong></strong>用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式的相互引用，从而使其耦合松散，而且可以独立地改变它们之间的交互。</p>
<p><strong>结构图</strong></p>
<p><strong><a href="http://shao.mingbo.de/wp-content/uploads/2010/05/mediator-结构图.jpg"><img class="aligncenter size-full wp-image-645" title="mediator 结构图" src="http://shao.mingbo.de/wp-content/uploads/2010/05/mediator-结构图.jpg" alt="mediator 结构图" width="425" height="229" /></a></strong></p>
<p>在这里，我们模拟一个聊天室的程序，用户既可以对特定的对象进行发送消息，也可以向所有人say hello。我们用一个mediator 对象进行管理他们之间的联系。值得指出的是，代码中，仍有值得抽象的接口。</p>
<p><strong>代码：</strong></p>
<pre name="code" class="csharp">
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Mediator
{
    class Program
    {
        static void Main(string[] args)
        {
            ChatRoom cr = new ChatRoom();
            Participator p = new Participator("Shao mingbo",cr);
            Participator p2 = new Participator("YW",cr);
            Participator p3 = new Participator("ZZ",cr);
            Participator p4 = new Participator("Xiao Di",cr);
            //Say Hello to The One
            p.Send(p2,"Hello");
            Console.WriteLine("--------------");
            // Say Hi To All
            p4.Send("Hi");
        }
    }
    class Participator {
        private string _name;
        private ChatRoom cr;

        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }
        public Participator(string name,ChatRoom cr) {
            this._name = name;
            this.cr = cr;
            cr.RegistParticipator(this);
        }
        public void Receive(string from,string msg) {
            if(cr!=null)
                Console.WriteLine("{0} 收到来自 {1}的一则消息： {2}", this.Name, from, msg);
            else
                Console.WriteLine("{0} 未曾在聊天室内注册！", this._name);
        }
        public void Send(Participator p,string msg) {
            if (cr != null) {
                cr.RegistParticipator(this);
                cr.Notify(this.Name,p, msg);
            }
            else
                Console.WriteLine("{0} 未曾在聊天室内注册！",this._name);

        }

        public void Send(string msg) {
            this.Send(null,msg);
        }
    }
    class ChatRoom {
        private Dictionary<string, Participator> roomMate = new Dictionary<string, Participator>();
        public void RegistParticipator(Participator p) {
            if (!roomMate.ContainsKey(p.Name))
                roomMate.Add(p.Name,p);
        }
        public void Notify(string from,Participator p, string msg) {
            if (p != null)
            {
                p.Receive(from, msg);
            }
            else {
                foreach (var receiver in roomMate) {
                    if (receiver.Key != from) {
                        Participator r = receiver.Value;
                        r.Receive(from,msg);
                    }
                }
            }
        }
    }

}
</pre>
<p><strong>运行结果：</strong></p>
<p><strong><a href="http://shao.mingbo.de/wp-content/uploads/2010/05/mediator-运行结果.jpg"><img class="aligncenter size-full wp-image-646" title="mediator 运行结果" src="http://shao.mingbo.de/wp-content/uploads/2010/05/mediator-运行结果.jpg" alt="mediator 运行结果" width="393" height="200" /></a><br />
</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://shao.mingbo.de/2010/05/04/mediator-pattern/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>初尝Interpretor 模式</title>
		<link>http://shao.mingbo.de/2010/05/01/interpretor-pattern/</link>
		<comments>http://shao.mingbo.de/2010/05/01/interpretor-pattern/#comments</comments>
		<pubDate>Sat, 01 May 2010 10:46:04 +0000</pubDate>
		<dc:creator>邵 明博</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[设计模式]]></category>
		<category><![CDATA[Interpretor]]></category>
		<category><![CDATA[解释器模式]]></category>

		<guid isPermaLink="false">http://shao.mingbo.de/?p=631</guid>
		<description><![CDATA[这个模式，一般用的很少。通常一个解释器，都会有专门的对象或者更底层（更高效）的工具来解决相应的问题。但有通常，就会有特殊的情况。当我们需要剖析某个具有结构性的对象，而这个对象并没有那么庞大时，就可以采用Interpretor 模式。
意图：
给定一个语言，定义它的文法的一种表示，并定义一种解释器，这个解释器使用该表示来解释语言中的句子。
结构图：
 

这个模式让我纠结了几天。原因不在理解这个模式本身，而是老师在课堂举的一个解释器的例子（将汉语数字转换成阿拉伯数字。比如：九千一百二十万六千三百二十一 &#8211;&#62;91206321 )这样的计算处理，不用设计模式，也能实现。但，使用了设计模式，可以在代码复用以及一些小型的语法处理问题得到很好的效果。当然最后还是实现了，但这充分说明，自己实现一个解释器，并不容易。
在写代码的过程中，我有尝试从最高位向低位来转换，但发现后期扩展就受到了这个方向的限制。所以，我得出了一个不完全的总结，就是在使用Interpretor 模式的过程中，应该先从最小的单位单元（个位）进行，然后依次递增。
代码：

using System;
using System.Collections;
using System.Collections.Generic;

namespace DesignPattern
{
    class Program
    {
        static void Main(string[] args)
        {
            //初始化翻译数据...
      [...]]]></description>
			<content:encoded><![CDATA[<p>这个模式，一般用的很少。通常一个解释器，都会有专门的对象或者更底层（更高效）的工具来解决相应的问题。但有通常，就会有特殊的情况。当我们需要剖析某个具有结构性的对象，而这个对象并没有那么庞大时，就可以采用Interpretor 模式。</p>
<p><strong>意图：</strong><br />
给定一个语言，定义它的文法的一种表示，并定义一种解释器，这个解释器使用该表示来解释语言中的句子。</p>
<p><strong>结构图：</strong></p>
<p style="text-align: center;"><strong> </strong></p>
<p style="text-align: center;"><strong><a href="http://shao.mingbo.de/wp-content/uploads/2010/05/Interpretor-模式结构1.jpg"><img class="aligncenter size-full wp-image-633" title="Interpretor 模式结构" src="http://shao.mingbo.de/wp-content/uploads/2010/05/Interpretor-模式结构1.jpg" alt="Interpretor 模式结构" width="462" height="242" /></a></strong></p>
<p style="text-align: left;">这个模式让我纠结了几天。原因不在理解这个模式本身，而是老师在课堂举的一个解释器的例子（将汉语数字转换成阿拉伯数字。比如：九千一百二十万六千三百二十一 &#8211;&gt;91206321 )这样的计算处理，不用设计模式，也能实现。但，使用了设计模式，可以在代码复用以及一些小型的语法处理问题得到很好的效果。当然最后还是实现了，但这充分说明，自己实现一个解释器，并不容易。</p>
<p style="text-align: left;">在写代码的过程中，我有尝试从最高位向低位来转换，但发现后期扩展就受到了这个方向的限制。所以，我得出了一个不完全的总结，就是在使用Interpretor 模式的过程中，应该先从最小的单位单元（个位）进行，然后依次递增。</p>
<p style="text-align: left;"><strong>代码</strong>：</p>
<pre name="code" class="csharp">
using System;
using System.Collections;
using System.Collections.Generic;

namespace DesignPattern
{
    class Program
    {
        static void Main(string[] args)
        {
            //初始化翻译数据...
            string[] numbers = { "九千一百二十万",
                                   "九千一百二十万六千三百二十一",
                                   "六千",
                                   "六千零一",
                                   "六千零一十",
                                   "六千一",
                                   "六千一百",
                                   "六千二百一十",
                                   "六千二百一",
                                   "六千二百零一",
                                   "六千零二十一",
                                   "六千三百二十一",
                                   "一百",
                                   "一百一",
                                   "一百一十",
                                   "一百零一",
                                   "一百一十一",
                                   "二十一",
                                   "二十",
                                   "八" };
            ArrayList contextList = new ArrayList();
            for (int i = 0; i < numbers.Length; i++)
            {
                contextList.Add(new Context(numbers[i]));
            }
            //初始化编译器...
            OneExpression one = new OneExpression();
            TenExpression ten = new TenExpression();
            HundredExpression hun = new HundredExpression();
            ThousandExpression thou = new ThousandExpression();
            TenThousandExpression tenThou = new TenThousandExpression();

            ArrayList list = new ArrayList();
            list.Add(one);
            list.Add(ten);
            list.Add(hun);
            list.Add(thou);
            list.Add(tenThou);

            //开始翻译工作啦...
            foreach (Context c in contextList)
            {
                Console.Write("Input: {0}\t", c.Input);
                foreach (Expression ex in list)
                    ex.Interprete(c);
                Console.WriteLine("Output: {0}", c.Output);

            }

        }
    }
    class Context {
        private string _input;

        public string Input
        {
            get { return _input; }
            set { _input = value; }
        }
        private long _output;

        public long Output
        {
            get { return _output; }
            set { _output = value; }
        }

        public Context(string input) {
            this._input = input;
        }
    }

    abstract class Expression
    {
        protected Dictionary<string, int> charDic = new Dictionary<string, int>();
        protected Stack<string> mutiplier = new Stack<string>();
        protected int _data;
        public Expression()
        {
            charDic.Add("一", 1);
            charDic.Add("二", 2); charDic.Add("两", 2);
            charDic.Add("三", 3); charDic.Add("四", 4);
            charDic.Add("五", 5); charDic.Add("六", 6);
            charDic.Add("七", 7); charDic.Add("八", 8);
            charDic.Add("九", 9);
        }
        public abstract void Interprete(Context context);
    }

    class OneExpression : Expression
    {
        public override void Interprete(Context context)
        {
            //throw new NotImplementedException();
            if (context.Input.Length <= 0) return;
            if (context.Input.Length == 1)
            {
                if (charDic.ContainsKey(context.Input))
                {
                    this._data = charDic[context.Input];
                    context.Output += this._data;
                    context.Input = String.Empty;
                    return;
                }
            }
            string lastWord = context.Input.Substring(context.Input.Length - 1);
            string preWord = context.Input.Substring(0, context.Input.Length - 1);
            if (context.Input.Length == 2)
            {
                if (charDic.ContainsKey(lastWord))
                {
                    this._data = charDic[lastWord];
                    context.Output += this._data;
                    context.Input = context.Input.Substring(0, context.Input.Length - 1);
                }
            }
            if (context.Input.Length > 2)
            {
                if (charDic.ContainsKey(lastWord))
                {
                    if (preWord.EndsWith("十") || preWord.EndsWith("零"))
                    {
                        this._data = charDic[lastWord];
                        context.Output += this._data;
                        context.Input = context.Input.Substring(0, context.Input.Length - 2);
                    }
                }
            }
        }
    }
    class TenExpression : Expression
    {
        public override void Interprete(Context context)
        {
            if (context.Input.Length <= 0) return;
            if (context.Input.Length == 1)
            {
                if (this.charDic.ContainsKey(context.Input))
                {
                    context.Output += charDic[context.Input] * 10;
                }
                if (context.Input.Equals("十"))
                {
                    context.Output += 10;
                }
                context.Input = String.Empty;
                return;
            }
            string lastWord = context.Input.Substring(context.Input.Length - 1);
            string preWord = context.Input.Substring(0, context.Input.Length - 1);
            if (context.Input.Length == 2)
            {
                if (lastWord.Equals("十"))
                {
                    if (this.charDic.ContainsKey(preWord))
                    {
                        context.Output += this.charDic[preWord] * 10;
                        context.Input = String.Empty;
                    }
                }
            }

            if (context.Input.Length > 2)
            {
                if (lastWord.Equals("十"))
                {
                    lastWord = preWord.Substring(preWord.Length - 1);
                    preWord = preWord.Substring(0, preWord.Length - 1);
                }
                if (this.charDic.ContainsKey(lastWord))
                {
                    if (preWord.EndsWith("百") || preWord.EndsWith("零"))
                    {
                        this._data = this.charDic[lastWord];
                        context.Output += this._data * 10;
                        context.Input = preWord.Substring(0, preWord.Length - 1);
                    }
                }
            }
        }
    }
    class HundredExpression : Expression
    {
        public override void Interprete(Context context)
        {
            if (context.Input.Length == 0) return;
            if (context.Input.Length == 1)
            {
                if (this.charDic.ContainsKey(context.Input))
                {
                    this._data = this.charDic[context.Input];
                    context.Output += this._data * 100;
                }
                context.Input = String.Empty;
                return;
            }
            string lastWord = context.Input.Substring(context.Input.Length - 1);
            string preWord = context.Input.Substring(0, context.Input.Length - 1);
            if (context.Input.Length == 2)
            {
                if (lastWord.Equals("百"))
                {
                    if (this.charDic.ContainsKey(preWord))
                    {
                        context.Output += this.charDic[preWord] * 100;
                        context.Input = String.Empty;
                    }
                }
            }
            if (context.Input.Length > 2)
            {
                if (lastWord.Equals("百"))
                {
                    lastWord = preWord.Substring(preWord.Length - 1);
                    preWord = preWord.Substring(0, preWord.Length - 1);
                }
                if (this.charDic.ContainsKey(lastWord))
                {
                    if (preWord.EndsWith("千") || preWord.EndsWith("零"))
                    {
                        this._data = this.charDic[lastWord];
                        context.Output += this._data * 100;
                        context.Input = preWord.Substring(0, preWord.Length - 1);
                    }
                }
            }
        }
    }
    class ThousandExpression : Expression
    {
        public override void Interprete(Context context)
        {
            if (context.Input.Length <= 0) return;
            if (context.Input.Length == 1)
            {
                if (this.charDic.ContainsKey(context.Input))
                {
                    this._data = this.charDic[context.Input];
                    context.Output += this._data * 1000;
                }
                context.Input = String.Empty;
                return;
            }
            string lastWord = context.Input.Substring(context.Input.Length - 1);
            string preWord = context.Input.Substring(0, context.Input.Length - 1);
            if (context.Input.Length == 2)
            {
                if (lastWord.Equals("千"))
                {
                    if (this.charDic.ContainsKey(preWord))
                    {
                        context.Output += this.charDic[preWord] * 1000;
                        context.Input = String.Empty;
                    }
                }
            }
            if (context.Input.Length > 2)
            {
                if (lastWord.Equals("千"))
                {
                    lastWord = preWord.Substring(preWord.Length - 1);
                    preWord = preWord.Substring(0, preWord.Length - 1);
                }
                if (this.charDic.ContainsKey(lastWord))
                {
                    if (preWord.EndsWith("万") || preWord.EndsWith("零"))
                    {
                        this._data = this.charDic[lastWord];
                        context.Output += this._data * 1000;
                        context.Input = preWord.Substring(0, preWord.Length - 1);
                    }
                }
            }
        }
    }
    class TenThousandExpression : Expression
    {
        public override void Interprete(Context context)
        {
            if (context.Input.Length <= 0) return;
            if (context.Input.EndsWith("万"))
            {
                context.Input = context.Input.Substring(0, context.Input.Length - 1);
            }
            long temp = context.Output;
            context.Output = 0;
            OneExpression one = new OneExpression();
            TenExpression ten = new TenExpression();
            HundredExpression hun = new HundredExpression();
            ThousandExpression thou = new ThousandExpression();
            ArrayList list = new ArrayList();
            list.Add(one);
            list.Add(ten);
            list.Add(hun);
            list.Add(thou);
            foreach (Expression ex in list)
            {
                ex.Interprete(context);
            }
            context.Output *= 10000;
            context.Output += temp;

        }
    }
}
</pre>
<p style="text-align: left;"><strong>运行结果</strong>：</p>
<p style="text-align: left;"><a href="http://shao.mingbo.de/wp-content/uploads/2010/05/Interpretor-运行结果.jpg"><img class="aligncenter size-full wp-image-635" title="Interpretor 运行结果" src="http://shao.mingbo.de/wp-content/uploads/2010/05/Interpretor-运行结果.jpg" alt="Interpretor 运行结果" width="492" height="443" /></a></p>
<p>这里是测试程序，如果有bug，请联系我哟。点击下载：<a class="downloadlink" href="http://shao.mingbo.de/wp-content/plugins/download-monitor/download.php?id=6" title="Version1.1 downloaded 30 times" >Interpretor 演示代码 (30)</a></p>
]]></content:encoded>
			<wfw:commentRss>http://shao.mingbo.de/2010/05/01/interpretor-pattern/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
