﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>IT博客-农夫之子㊣-文章分类-SOA与Web Service</title><link>http://www.cnitblog.com/jsjzzm/category/3767.html</link><description /><language>zh-cn</language><lastBuildDate>Thu, 29 Sep 2011 23:56:13 GMT</lastBuildDate><pubDate>Thu, 29 Sep 2011 23:56:13 GMT</pubDate><ttl>60</ttl><item><title>活用设计模式(转贴)</title><link>http://www.cnitblog.com/jsjzzm/articles/18294.html</link><dc:creator>农夫之子㊣</dc:creator><author>农夫之子㊣</author><pubDate>Mon, 23 Oct 2006 12:52:00 GMT</pubDate><guid>http://www.cnitblog.com/jsjzzm/articles/18294.html</guid><wfw:comment>http://www.cnitblog.com/jsjzzm/comments/18294.html</wfw:comment><comments>http://www.cnitblog.com/jsjzzm/articles/18294.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/jsjzzm/comments/commentRss/18294.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/jsjzzm/services/trackbacks/18294.html</trackback:ping><description><![CDATA[
		<h5 align="center">活用设计模式</h5>
		<h5 align="center">
				<a href="http://dev.csdn.net/author/zhangyuk/959c04f3a9d24650a6aaec5931720fbc.html">http://dev.csdn.net/author/zhangyuk/959c04f3a9d24650a6aaec5931720fbc.html</a>
		</h5>
		<h5>
				<hr />
		</h5>
		<p>一、 设计模式的隐喻<br />     武功套路是习武的门径。新手要一招一式地练习套路，烂熟于心之后，熟能生巧，在实战之中即可见招拆招、运用自如——此时习武之人已从“新手”成长为“好手”。“高手”则没有套路，实战之中只有自然反应，然而一招一式浑然天成、恰到好处，似有似无、无中生有。“高手”之上还有“高高手”，他们达到的境界非我等凭借金氏武侠小说可以揣测。<br />    设计模式之于设计，好比套路之于武术。“新手”要一个接一个地学习模式，“好手”能够活用模式，“高手”则没有模式。<br />    设计模式的“内功”是面向对象的基本原则。这些原则是“神”，模式是“形”。高手拼的是“内功”，对面向对象基本原则有了深刻的领悟，才能用好设计模式，避免“走火入魔”。<br />    一般在设计模式著作的前几章都会介绍面向对象的基本原则，这几章非常重要。学通了这几章，后面的模式就不过如此了。学完了设计模式，也最好翻过头来重新看看这几章，保证会有新的领悟。</p>
		<p>二、 为什么使用设计模式<br />    对任何设计都可以凭主观（对设计很难做出客观评价）判断得出它是一个好的设计，还是一个坏的设计。使用设计模式是为了避免坏的设计。Martin叔叔在他的著作《敏捷软件开发 原则、模式与实践》中描述了拙劣设计的症状：</p>
		<ul>
				<li>
						<font size="2">僵化性（Rigidity）：设计难以改变。</font>
				</li>
				<li>
						<font size="2">脆弱性（Fragility）：设计易于遭到破坏。</font>
				</li>
				<li>
						<font size="2">牢固性（Immobility）：设计难以重用。</font>
				</li>
				<li>
						<font size="2">粘滞性（Viscosity）：难以做正确的事情。</font>
				</li>
				<li>
						<font size="2">不必要的复杂性（Needless Complexity）：过分设计。</font>
				</li>
				<li>
						<font size="2">不必要的重复（Needless Repetition）：过多的重复。</font>
				</li>
				<li>
						<font size="2">晦涩性（Opacity）：混乱的表达。</font>
				</li>
		</ul>
		<font size="2">
				<p>
						<br />
				</p>
				<p>三、 什么时候使用设计模式<br />    Martin叔叔的书中有段话：<br />　　<br />    在学习它们（设计原则和模式）的时候，请记住，敏捷开发人员不会对一个庞大的预先设计应用那些原则和模式。相反，这些原则和模式被应用在一次次的迭代中，力图使代码以及代码所表达的设计保持干净。<br />　　<br />    在这段容易被读者忽略的文字中，我体会到这样几层含义：</p>
				<ul>
						<li>代码是设计（这是Martin叔叔强调的一个观点，这个观点可以参考《敏捷软件开发 原则、模式与实践》一书的附录D）； 
</li>
						<li>设计模式是为了使设计适应变化； 
</li>
						<li>设计模式是重构的工具； 
</li>
						<li>设计一开始就要保持干净、简单，以后仍然要保持干净、简单； 
</li>
						<li>不能过度使用设计模式。 </li>
				</ul>
				<p>
						<br />    使用设计模式的目的是为了适应未来的变化，变化之所以存在是因为它的不可预知性——如果可以预知，则不能称其为变化。如何判断哪些需求可能变化，哪些需求可能不变，并且在最大程度上保持设计的干净、简单，这是些工艺问题，而不是工程问题。既然是工艺问题，那么就只能给出原则，不能给出标准。使用设计模式的大体原则可能是：对未来极有可能发生变化的问题给出最简单、修改成本最低的解。<br />　　<br />四、 避免过度使用设计模式<br />    易维护的程序首先要易理解，这一点远甚于其他。在易理解的代码上才好维护。过分地使用设计模式会增加程序的复杂性和晦涩性，让程序不易理解，从而降低了程序的易维护性。<br />    Switch语句曾经遭致诟病，许多重构的例子就是拿Switch开刀。我认为Switch语句是高效的语句，可以写出极优雅、简单的代码。在很多情况下，直接使用Switch语句比把它拆成若干个Class更“干净”。<br />    再比如，有一段四百多行的代码负责整个系统的调度，如果未来的变化仅仅是修改这四百行代码而不会大量添加代码，那么把这四百多行代码集中在一个函数里面，比将它拆分成十来个Class更加容易维护。</p>
				<p>五、 讨论几个具体的模式<br />1、 创建模式（Creational Pattern）<br />    工厂（Factory Method）模式是常用的模式。工厂模式的应用情景明确，设计思想简单。从使用多态到只用一个静态方法，工厂模式的变化形式有很多。我习惯简单地使用工厂模式，也就是使用只有静态方法的工厂模式。下面的工厂模式代码简单、干净：<br />   <br />　　MyFactory.GetClassInstance().DoFunction();<br />　　<br />    类厂并不承载业务逻辑，需求变化对类厂的影响通常很小。因此使用重量级的工厂模式往往并不划算。一组包含层次关系的重量级的工厂类，可能意味着过度设计。<br />   单例（Singleton）模式和工厂模式关系密切。从实现的角度讲，单例模式是工厂模式的一个特例，但是两个模式的应用情景不同，因此它们属于不同的模式。<br />   抽象工厂（Abstract Factory）模式是工厂模式的推广。抽象工厂模式的应用情景更加特殊和严格。在一个使用抽象工厂的设计中，如果未来发生不同产品族各自演化的情形，那么抽象工厂模式就可能崩溃了。在实际应用中，不同产品族各自演化，最终分道扬镳的情形是有的，用户提出这样的需求的确让人“触目惊心”。在使用抽象工厂模式之前，一定要保证从现在到未来都能够用一致的方式使用这些产品族。<br />   将工厂模式稍加变化可以得到建造（Builder）模式。工厂模式的“加工工艺”是隐藏的，而建造模式的“加工工艺”是暴露的。这点不同，使建造模式在更加灵活的同时也有失优雅。<br />2、 模板模式（Template Method）和策略（Strategy）模式<br />   模板模式和策略模式的应用情景类似，但实现方式不同，前者使用继承，后者使用委托。<br />   模板模式有可能是最“古老”的模式之一，在使用面向对象技术的早期，“继承”大行其道，很多设计人员可能不自觉地使用过模板模式。模板模式的缺点是把具体实现和通用算法紧密地耦合起来，使得具体实现只能被一个通用算法操纵。然而在继承关系中，父类的信息可以更多地暴露给子类，这种（违背面向对象设计原则的）微妙的沟通在一些特定应用中显得更加灵活和方便。<br />   策略模式是委托的经典用法。策略模式消除了通用算法和具体实现的耦合，使得具体实现可以被多个通用算法操纵。策略模式也增加了类层次，比模板模式复杂。<br />   模板模式和策略模式通常可以互相替换。它们都像试卷，模板模式是填空题，策略模式是选择题。<br />3、 简化问题的模式<br />    门面（Facade）模式把一组复杂的接口隐藏在一个简单且特定的接口后面。<br />    调停者（Mediator）模式把对象之间的引用关系包装在一个特定的容器里面。<br />   组合（Composite）模式描述了整体与部分的结构关系，并且允许用一致的方式处理这个结构。<br />   上面几个模式对使用者而言，都在一定程度上起到了简化问题的作用。<br />4、 扩展功能的模式<br />   访问者（Visitor）模式和装饰（Decorator）模式都可以在不改变现有类结构的基础上，动态地增加功能。<br />   访问者模式把现有类结构上的对象“分配”到一个名为访问者的类中，在访问者的相应方法中配置对象、改变对象或扩展功能。<br />   装饰模式把现有类结构上的对象“注入”一个装饰类中，在装饰类中扩展它的功能。<br />   访问者模式和装饰模式在实际效果上是不同的。访问者模式可以把对象分配到相应的方法里，从而对每个对象分别进行加工或扩展。而装饰模式只能用一致的方式对所有的被装饰对象进行加工或扩展，要想实现不同的加工或扩展，只能增加新的装饰类。<br />   过多的“装饰类”有可能使业务逻辑分散，并且使程序结构复杂。针对每一个具体的派生类，“访问类”都要有一个对应的方法，增加派生类的时候也要增加访问类的方法。扩展功能的需求是经常发生的，是否有必要使用上述模式则值得再三考虑。<br />5、 其他常用的模式<br />   桥梁（Bridge）模式。Class是封装了行为和属性的容器，然而Class的一组行为可能独立演化，这时最直接的想法是使用继承，把各不相同的行为封装在不同的子类里。桥梁模式从另外的角度解决了这个问题。桥梁模式把独立演化的行为封装在另外一个类体系里，与原来的类体系分别独立演化，两个类体系在抽象层次是“使用”关系。在很多OO教材里面用Shape类封装属性和Draw方法，在桥梁模式里，“形状”和“画笔”是两组独立演化的类体系，在抽象层次，“形状”使用“画笔”绘制自己。<br />适配器（Adapter）模式是常用模式，它比较简单，有时和其他的模式配合使用。<br />   命令（Command）模式被Martin称为“最简单、最优雅的模式之一”。命令模式的魅力在于它为每个类“培训”出了相同的技能，经过“培训”的类“柔性”更强，能够产生不可思议的能力。<br />6、 不太需要的模式<br />   观察者（Observer）模式。Java和C# 都实现了观察者模式。<br />   迭代子（Iterator）模式。在Java和C#语言里，可以用聚集类代替。<br />   备忘录（Memento）模式。可以用Class的序列化能力代替。<br />   责任链（Chain of Responsibility）模式。可以用其他的方式替代，例如观察者模式、语言本身提供的消息机制等。<br />   解释器（Interpreter）模式。个人认为，它是个算法，不是模式。<br />   代理（Proxy）模式。如果在一开始就知道某些底层策略一定会被替换掉，那么使用代理来隔离这些策略还是有必要的。否则，几乎没有使用的必要。<br />   <br />参考文献：<br />Robert C. Martin，Agile Software Development Principles,Patterns,and Practices.（中译本：《敏捷软件开发 原则、模式与实践》，邓辉译，清华大学出版社，2003年）</p>
				<p>作者：<br />张昱 曾就职于浪潮集团、联想集团，现就职于中科院电子所。超过十年的软件工作经验。对分析设计、项目管理、编程实践有着浓厚的兴趣。</p>
		</font>
<img src ="http://www.cnitblog.com/jsjzzm/aggbug/18294.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/jsjzzm/" target="_blank">农夫之子㊣</a> 2006-10-23 20:52 <a href="http://www.cnitblog.com/jsjzzm/articles/18294.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>