﻿<?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>C++博客-只有面对现实，你才能超越现实-随笔分类-Design Pattern</title><link>http://www.cppblog.com/wanghaiguang/category/19607.html</link><description>不要浪费你的生命，在你一定会后悔的地方上。
逆水行舟，不进则退</description><language>zh-cn</language><lastBuildDate>Tue, 17 Jul 2012 07:56:40 GMT</lastBuildDate><pubDate>Tue, 17 Jul 2012 07:56:40 GMT</pubDate><ttl>60</ttl><item><title>设计模式之strategy</title><link>http://www.cppblog.com/wanghaiguang/archive/2012/07/17/183830.html</link><dc:creator>王海光</dc:creator><author>王海光</author><pubDate>Tue, 17 Jul 2012 00:11:00 GMT</pubDate><guid>http://www.cppblog.com/wanghaiguang/archive/2012/07/17/183830.html</guid><wfw:comment>http://www.cppblog.com/wanghaiguang/comments/183830.html</wfw:comment><comments>http://www.cppblog.com/wanghaiguang/archive/2012/07/17/183830.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/wanghaiguang/comments/commentRss/183830.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/wanghaiguang/services/trackbacks/183830.html</trackback:ping><description><![CDATA[<span style="font-size: 12pt">一、概述</span><br /><span style="font-size: 12pt">Strategy（策略）模式又称Policy模式，用于定义一系列的算法，把它们一个个封装起来，并且使它们可相互替换。这里的算法并非狭义的数据结构或算法理论中所讨论的KMP、shell&nbsp;sort等算法，而是指应用程序设计中不同的处理逻辑，前面所说的狭义的算法只是其中的一部分。Strategy模式使得算法与算法的使用者相分离，减少了二者间的耦合度，使得算法可独立于使用它的客户而变化；同时，由于设计粒度的减小，程序的复用性也得到了进一步提高，分离出来的算法可以更好地适应复用的需要。</span><br /><br /><span style="font-size: 12pt">二、结构</span><br /><span style="font-size: 12pt">Strategy模式的结构如下图所示：</span><br /><br />&nbsp;<img border="0" alt="" src="http://www.cppblog.com/images/cppblog_com/wanghaiguang/image/设计模式/Strategy.jpg" width="672" height="308" /><br /><span style="font-size: 12pt">从结构上看，Strategy模式与State模式有几分相似，但二者所讨论的Context（情景）具有显著的差异：</span><br /><span style="font-size: 12pt">State模式在于将其状态信息分离出来保存到一个独立的对象中，以便状态信息的获取或状态的转换；Strategy模式在于将可能的算法分离出来，根据需要进行适当的选择。此外，二者的区别还在于，Strategy模式中各个Strategy（算法、策略）往往用于解决相同的问题，即只是解决同一问题的不同&#8220;策略&#8221;、&#8220;途径&#8221;，而且，一次只能有一个Strategy为上次应用提供服务；而State模式中的各个State本身往往具有一定的差异，但他们之间存在明显的相互转换的关系，而且这种转换往往会在程序运行过程中经常性地发生，同时存在一个以上State也是可能的。</span><br /><br /><span style="font-size: 12pt">区别参考：二者的应用场合不同。状态模式用于处理对象有不同状态（状态机）的场合，策略模式用于随不同外部环境采取不同行为的场合。在状态模式中，状态的变迁是由对象的内部条件决定，外界只需关心其接口，不必关心其状态对象的创建和转化；而策略模式里，采取何种策略由外部条件决定。所以，有人说&#8220;状态模式是完全封装且自修改的策略模式&#8221;。至于Bridge，在结构上与前两者都不一样了。要说相似之处，就是三者都有具有对外接口统一的类，展现出多态性而已。</span><br /><br /><span style="font-size: 12pt">三、应用</span><br /><span style="font-size: 12pt">当存在以下情况时可考虑使用Strategy模式：</span><font color="#996600"><br /><span style="font-size: 12pt">1.</span></font><span style="font-size: 12pt">许多相关的类仅仅是行为有异。&#8220;策略&#8221;提供了一种用多个行为中的一个行为来配置一个类的方法。</span><font color="#996600"><br /><span style="font-size: 12pt">2.</span></font><span style="font-size: 12pt">需要使用一个算法的不同变体。例如，你可能会定义一些反映不同的空间</span><strong><font color="#663300"><span style="font-size: 12pt">/</span></font></strong><span style="font-size: 12pt">时间权衡的算法，当这些变体实现为一个算法的类层次时，可以使用策略模式。</span><font color="#996600"><br /><span style="font-size: 12pt">3.</span></font><span style="font-size: 12pt">算法使用客户不应该知道的数据。可使用策略模式以避免暴露复杂的、与算法相关的数据结构。</span><font color="#996600"><br /><span style="font-size: 12pt">4.</span></font><span style="font-size: 12pt">一个类定义了多种行为，并且这些行为在这个类的操作中以多个条件语句的形式出现。将相关的条件分支移入它们各自的Strategy类中以代替这些条件语句。</span><br /><span style="font-size: 12pt">更具体的应用实例包括：</span><font color="#996600"><br /><span style="font-size: 12pt">1.</span></font><span style="font-size: 12pt">以不同的格式保存文件；</span><font color="#996600"><br /><span style="font-size: 12pt">2.</span></font><span style="font-size: 12pt">以不同的方式对文件进行压缩或其他处理；</span><font color="#996600"><br /><span style="font-size: 12pt">3.</span></font><span style="font-size: 12pt">以不同的方式绘制</span><strong><font color="#663300"><span style="font-size: 12pt">/</span></font></strong><span style="font-size: 12pt">处理相同的图形数据；</span><br /><span style="font-size: 12pt">等等。</span><br /><br /><span style="font-size: 12pt">四、举例</span><br /><span style="font-size: 12pt">下面是一个应用Strategy模式对vector进行排序的例子，为了简化问题，其中的排序Strategy实际上调用的是STL的排序算法：sort和stable_sort。</span>
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080; font-size: 12pt">&nbsp;&nbsp;1</span>&nbsp;<span style="color: #000000; font-size: 12pt">#include&nbsp;</span><span style="color: #000000; font-size: 12pt">&lt;</span><span style="color: #000000; font-size: 12pt">iostream</span><span style="color: #000000; font-size: 12pt">&gt;</span><span style="color: #000000"><br /></span><span style="color: #008080; font-size: 12pt">&nbsp;&nbsp;2</span>&nbsp;<span style="color: #000000; font-size: 12pt">#include&nbsp;</span><span style="color: #000000; font-size: 12pt">&lt;</span><span style="color: #000000; font-size: 12pt">vector</span><span style="color: #000000; font-size: 12pt">&gt;</span><span style="color: #000000"><br /></span><span style="color: #008080; font-size: 12pt">&nbsp;&nbsp;3</span>&nbsp;<span style="color: #000000; font-size: 12pt">#include&nbsp;</span><span style="color: #000000; font-size: 12pt">&lt;</span><span style="color: #000000; font-size: 12pt">algorithm</span><span style="color: #000000; font-size: 12pt">&gt;</span><span style="color: #000000"><br /></span><span style="color: #008080; font-size: 12pt">&nbsp;&nbsp;4</span>&nbsp;<span style="color: #000000; font-size: 12pt">#include&nbsp;</span><span style="color: #000000; font-size: 12pt">&lt;</span><span style="color: #000000; font-size: 12pt">time.h</span><span style="color: #000000; font-size: 12pt">&gt;</span><span style="color: #000000"><br /></span><span style="color: #008080; font-size: 12pt">&nbsp;&nbsp;5</span>&nbsp;<span style="color: #000000"></span><span style="color: #0000ff; font-size: 12pt">using</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff; font-size: 12pt">namespace</span><span style="color: #000000; font-size: 12pt">&nbsp;std;<br /></span><span style="color: #008080; font-size: 12pt">&nbsp;&nbsp;6</span>&nbsp;<span style="color: #000000"><br /></span><span style="color: #008080; font-size: 12pt">&nbsp;&nbsp;7</span>&nbsp;<span style="color: #000000; font-size: 12pt">template&nbsp;</span><span style="color: #000000; font-size: 12pt">&lt;</span><span style="color: #000000; font-size: 12pt">typename&nbsp;T</span><span style="color: #000000; font-size: 12pt">&gt;</span><span style="color: #000000"><br /></span><span style="color: #008080; font-size: 12pt">&nbsp;&nbsp;8</span>&nbsp;<span style="color: #000000"></span><span style="color: #0000ff; font-size: 12pt">class</span><span style="color: #000000; font-size: 12pt">&nbsp;SortStrategy&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; font-size: 12pt">//</span><span style="color: #008000; font-size: 12pt">&nbsp;Strategy</span><span style="color: #008000"><br /></span><span style="color: #008080; font-size: 12pt">&nbsp;&nbsp;9</span>&nbsp;<span style="color: #008000"></span><span style="color: #000000; font-size: 12pt">{<br /></span><span style="color: #008080; font-size: 12pt">&nbsp;10</span>&nbsp;<span style="color: #000000"></span><span style="color: #0000ff; font-size: 12pt">public</span><span style="color: #000000; font-size: 12pt">:<br /></span><span style="color: #008080; font-size: 12pt">&nbsp;11</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff; font-size: 12pt">virtual</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff; font-size: 12pt">void</span><span style="color: #000000; font-size: 12pt">&nbsp;Sort(&nbsp;vector</span><span style="color: #000000; font-size: 12pt">&lt;</span><span style="color: #000000; font-size: 12pt">T</span><span style="color: #000000; font-size: 12pt">&gt;&amp;</span><span style="color: #000000; font-size: 12pt">&nbsp;v_t&nbsp;)&nbsp;</span><span style="color: #000000; font-size: 12pt">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000; font-size: 12pt">0</span><span style="color: #000000; font-size: 12pt">;<br /></span><span style="color: #008080; font-size: 12pt">&nbsp;12</span>&nbsp;<span style="color: #000000; font-size: 12pt">};<br /></span><span style="color: #008080; font-size: 12pt">&nbsp;13</span>&nbsp;<span style="color: #000000"><br /></span><span style="color: #008080; font-size: 12pt">&nbsp;14</span>&nbsp;<span style="color: #000000; font-size: 12pt">template&nbsp;</span><span style="color: #000000; font-size: 12pt">&lt;</span><span style="color: #000000; font-size: 12pt">typename&nbsp;T</span><span style="color: #000000; font-size: 12pt">&gt;</span><span style="color: #000000"><br /></span><span style="color: #008080; font-size: 12pt">&nbsp;15</span>&nbsp;<span style="color: #000000"></span><span style="color: #0000ff; font-size: 12pt">class</span><span style="color: #000000; font-size: 12pt">&nbsp;SortQuick&nbsp;:&nbsp;</span><span style="color: #0000ff; font-size: 12pt">public</span><span style="color: #000000; font-size: 12pt">&nbsp;SortStrategy</span><span style="color: #000000; font-size: 12pt">&lt;</span><span style="color: #000000; font-size: 12pt">T</span><span style="color: #000000; font-size: 12pt">&gt;</span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; font-size: 12pt">//</span><span style="color: #008000; font-size: 12pt">&nbsp;ConcreateStrategy1</span><span style="color: #008000"><br /></span><span style="color: #008080; font-size: 12pt">&nbsp;16</span>&nbsp;<span style="color: #008000"></span><span style="color: #000000; font-size: 12pt">{<br /></span><span style="color: #008080; font-size: 12pt">&nbsp;17</span>&nbsp;<span style="color: #000000"></span><span style="color: #0000ff; font-size: 12pt">public</span><span style="color: #000000; font-size: 12pt">:<br /></span><span style="color: #008080; font-size: 12pt">&nbsp;18</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff; font-size: 12pt">void</span><span style="color: #000000; font-size: 12pt">&nbsp;Sort(&nbsp;vector</span><span style="color: #000000; font-size: 12pt">&lt;</span><span style="color: #000000; font-size: 12pt">T</span><span style="color: #000000; font-size: 12pt">&gt;&amp;</span><span style="color: #000000; font-size: 12pt">&nbsp;v_t&nbsp;)&nbsp;{&nbsp;std::sort(&nbsp;v_t.begin(),&nbsp;v_t.end()&nbsp;);&nbsp;}<br /></span><span style="color: #008080; font-size: 12pt">&nbsp;19</span>&nbsp;<span style="color: #000000; font-size: 12pt">};<br /></span><span style="color: #008080; font-size: 12pt">&nbsp;20</span>&nbsp;<span style="color: #000000"><br /></span><span style="color: #008080; font-size: 12pt">&nbsp;21</span>&nbsp;<span style="color: #000000; font-size: 12pt">template&nbsp;</span><span style="color: #000000; font-size: 12pt">&lt;</span><span style="color: #000000; font-size: 12pt">typename&nbsp;T</span><span style="color: #000000; font-size: 12pt">&gt;</span><span style="color: #000000"><br /></span><span style="color: #008080; font-size: 12pt">&nbsp;22</span>&nbsp;<span style="color: #000000"></span><span style="color: #0000ff; font-size: 12pt">class</span><span style="color: #000000; font-size: 12pt">&nbsp;SortStable&nbsp;:&nbsp;</span><span style="color: #0000ff; font-size: 12pt">public</span><span style="color: #000000; font-size: 12pt">&nbsp;SortStrategy</span><span style="color: #000000; font-size: 12pt">&lt;</span><span style="color: #000000; font-size: 12pt">T</span><span style="color: #000000; font-size: 12pt">&gt;</span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; font-size: 12pt">//</span><span style="color: #008000; font-size: 12pt">&nbsp;ConcreateStrategy1</span><span style="color: #008000"><br /></span><span style="color: #008080; font-size: 12pt">&nbsp;23</span>&nbsp;<span style="color: #008000"></span><span style="color: #000000; font-size: 12pt">{<br /></span><span style="color: #008080; font-size: 12pt">&nbsp;24</span>&nbsp;<span style="color: #000000"></span><span style="color: #0000ff; font-size: 12pt">public</span><span style="color: #000000; font-size: 12pt">:<br /></span><span style="color: #008080; font-size: 12pt">&nbsp;25</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff; font-size: 12pt">void</span><span style="color: #000000; font-size: 12pt">&nbsp;Sort(&nbsp;vector</span><span style="color: #000000; font-size: 12pt">&lt;</span><span style="color: #000000; font-size: 12pt">T</span><span style="color: #000000; font-size: 12pt">&gt;&amp;</span><span style="color: #000000; font-size: 12pt">&nbsp;v_t&nbsp;)&nbsp;{&nbsp;std::stable_sort(v_t.begin(),&nbsp;v_t.end());&nbsp;}<br /></span><span style="color: #008080; font-size: 12pt">&nbsp;26</span>&nbsp;<span style="color: #000000; font-size: 12pt">};<br /></span><span style="color: #008080; font-size: 12pt">&nbsp;27</span>&nbsp;<span style="color: #000000"><br /></span><span style="color: #008080; font-size: 12pt">&nbsp;28</span>&nbsp;<span style="color: #000000; font-size: 12pt">template&nbsp;</span><span style="color: #000000; font-size: 12pt">&lt;</span><span style="color: #000000; font-size: 12pt">typename&nbsp;T</span><span style="color: #000000; font-size: 12pt">&gt;</span><span style="color: #000000"><br /></span><span style="color: #008080; font-size: 12pt">&nbsp;29</span>&nbsp;<span style="color: #000000"></span><span style="color: #0000ff; font-size: 12pt">class</span><span style="color: #000000; font-size: 12pt">&nbsp;Context&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; font-size: 12pt">//</span><span style="color: #008000; font-size: 12pt">&nbsp;Context,&nbsp;who&nbsp;or&nbsp;whose&nbsp;client&nbsp;takes&nbsp;charge&nbsp;of&nbsp;which&nbsp;strategy&nbsp;will&nbsp;be&nbsp;selected</span><span style="color: #008000"><br /></span><span style="color: #008080; font-size: 12pt">&nbsp;30</span>&nbsp;<span style="color: #008000"></span><span style="color: #0000ff; font-size: 12pt">public</span><span style="color: #000000; font-size: 12pt">:<br /></span><span style="color: #008080; font-size: 12pt">&nbsp;31</span>&nbsp;<span style="color: #000000; font-size: 12pt">&nbsp;&nbsp;&nbsp;&nbsp;Context()&nbsp;{&nbsp;m_pStrategy&nbsp;</span><span style="color: #000000; font-size: 12pt">=</span><span style="color: #000000; font-size: 12pt">&nbsp;NULL;&nbsp;}<br /></span><span style="color: #008080; font-size: 12pt">&nbsp;32</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff; font-size: 12pt">virtual</span><span style="color: #000000">&nbsp;</span><span style="color: #000000; font-size: 12pt">~</span><span style="color: #000000; font-size: 12pt">Context()&nbsp;{&nbsp;</span><span style="color: #0000ff; font-size: 12pt">if</span><span style="color: #000000; font-size: 12pt">&nbsp;(m_pStrategy&nbsp;</span><span style="color: #000000; font-size: 12pt">!=</span><span style="color: #000000; font-size: 12pt">&nbsp;NULL)&nbsp;delete&nbsp;m_pStrategy;&nbsp;}<br /></span><span style="color: #008080; font-size: 12pt">&nbsp;33</span>&nbsp;<span style="color: #000000"><br /></span><span style="color: #008080; font-size: 12pt">&nbsp;34</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff; font-size: 12pt">void</span><span style="color: #000000; font-size: 12pt">&nbsp;SetStrategy(SortStrategy</span><span style="color: #000000; font-size: 12pt">&lt;</span><span style="color: #000000; font-size: 12pt">T</span><span style="color: #000000; font-size: 12pt">&gt;*</span><span style="color: #000000; font-size: 12pt">&nbsp;pStrategy);&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; font-size: 12pt">//</span><span style="color: #008000; font-size: 12pt">&nbsp;select&nbsp;a&nbsp;strategy</span><span style="color: #008000"><br /></span><span style="color: #008080; font-size: 12pt">&nbsp;35</span>&nbsp;<span style="color: #008000"></span><span style="color: #000000"><br /></span><span style="color: #008080; font-size: 12pt">&nbsp;36</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff; font-size: 12pt">void</span><span style="color: #000000; font-size: 12pt">&nbsp;ReadVector(&nbsp;vector</span><span style="color: #000000; font-size: 12pt">&lt;</span><span style="color: #000000; font-size: 12pt">T</span><span style="color: #000000; font-size: 12pt">&gt;&amp;</span><span style="color: #000000; font-size: 12pt">&nbsp;v_t);<br /></span><span style="color: #008080; font-size: 12pt">&nbsp;37</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff; font-size: 12pt">bool</span><span style="color: #000000; font-size: 12pt">&nbsp;SortVector();<br /></span><span style="color: #008080; font-size: 12pt">&nbsp;38</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff; font-size: 12pt">void</span><span style="color: #000000; font-size: 12pt">&nbsp;OutputVector();<br /></span><span style="color: #008080; font-size: 12pt">&nbsp;39</span>&nbsp;<span style="color: #000000"></span><span style="color: #0000ff; font-size: 12pt">private</span><span style="color: #000000; font-size: 12pt">:<br /></span><span style="color: #008080; font-size: 12pt">&nbsp;40</span>&nbsp;<span style="color: #000000; font-size: 12pt">&nbsp;&nbsp;&nbsp;&nbsp;vector</span><span style="color: #000000; font-size: 12pt">&lt;</span><span style="color: #000000; font-size: 12pt">T</span><span style="color: #000000; font-size: 12pt">&gt;</span><span style="color: #000000; font-size: 12pt">&nbsp;m_vt;<br /></span><span style="color: #008080; font-size: 12pt">&nbsp;41</span>&nbsp;<span style="color: #000000; font-size: 12pt">&nbsp;&nbsp;&nbsp;&nbsp;SortStrategy</span><span style="color: #000000; font-size: 12pt">&lt;</span><span style="color: #000000; font-size: 12pt">T</span><span style="color: #000000; font-size: 12pt">&gt;*</span><span style="color: #000000; font-size: 12pt">&nbsp;&nbsp;m_pStrategy;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; font-size: 12pt">//</span><span style="color: #008000; font-size: 12pt">&nbsp;a&nbsp;pointer&nbsp;to&nbsp;current&nbsp;strategy</span><span style="color: #008000"><br /></span><span style="color: #008080; font-size: 12pt">&nbsp;42</span>&nbsp;<span style="color: #008000"></span><span style="color: #000000; font-size: 12pt">};<br /></span><span style="color: #008080; font-size: 12pt">&nbsp;43</span>&nbsp;<span style="color: #000000"><br /></span><span style="color: #008080; font-size: 12pt">&nbsp;44</span>&nbsp;<span style="color: #000000; font-size: 12pt">template&nbsp;</span><span style="color: #000000; font-size: 12pt">&lt;</span><span style="color: #000000; font-size: 12pt">typename&nbsp;T</span><span style="color: #000000; font-size: 12pt">&gt;</span><span style="color: #000000"><br /></span><span style="color: #008080; font-size: 12pt">&nbsp;45</span>&nbsp;<span style="color: #000000"></span><span style="color: #0000ff; font-size: 12pt">void</span><span style="color: #000000; font-size: 12pt">&nbsp;Context</span><span style="color: #000000; font-size: 12pt">&lt;</span><span style="color: #000000; font-size: 12pt">T</span><span style="color: #000000; font-size: 12pt">&gt;</span><span style="color: #000000; font-size: 12pt">::SetStrategy(&nbsp;SortStrategy</span><span style="color: #000000; font-size: 12pt">&lt;</span><span style="color: #000000; font-size: 12pt">T</span><span style="color: #000000; font-size: 12pt">&gt;*</span><span style="color: #000000; font-size: 12pt">&nbsp;pStrategy&nbsp;)<br /></span><span style="color: #008080; font-size: 12pt">&nbsp;46</span>&nbsp;<span style="color: #000000; font-size: 12pt">{<br /></span><span style="color: #008080; font-size: 12pt">&nbsp;47</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff; font-size: 12pt">if</span><span style="color: #000000; font-size: 12pt">&nbsp;(&nbsp;NULL&nbsp;</span><span style="color: #000000; font-size: 12pt">!=</span><span style="color: #000000; font-size: 12pt">&nbsp;m_pStrategy&nbsp;)<br /></span><span style="color: #008080; font-size: 12pt">&nbsp;48</span>&nbsp;<span style="color: #000000; font-size: 12pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delete&nbsp;m_pStrategy;<br /></span><span style="color: #008080; font-size: 12pt">&nbsp;49</span>&nbsp;<span style="color: #000000"><br /></span><span style="color: #008080; font-size: 12pt">&nbsp;50</span>&nbsp;<span style="color: #000000; font-size: 12pt">&nbsp;&nbsp;&nbsp;&nbsp;m_pStrategy&nbsp;</span><span style="color: #000000; font-size: 12pt">=</span><span style="color: #000000; font-size: 12pt">&nbsp;pStrategy;<br /></span><span style="color: #008080; font-size: 12pt">&nbsp;51</span>&nbsp;<span style="color: #000000; font-size: 12pt">}<br /></span><span style="color: #008080; font-size: 12pt">&nbsp;52</span>&nbsp;<span style="color: #000000"><br /></span><span style="color: #008080; font-size: 12pt">&nbsp;53</span>&nbsp;<span style="color: #000000; font-size: 12pt">template&nbsp;</span><span style="color: #000000; font-size: 12pt">&lt;</span><span style="color: #000000; font-size: 12pt">typename&nbsp;T</span><span style="color: #000000; font-size: 12pt">&gt;</span><span style="color: #000000"><br /></span><span style="color: #008080; font-size: 12pt">&nbsp;54</span>&nbsp;<span style="color: #000000"></span><span style="color: #0000ff; font-size: 12pt">void</span><span style="color: #000000; font-size: 12pt">&nbsp;Context</span><span style="color: #000000; font-size: 12pt">&lt;</span><span style="color: #000000; font-size: 12pt">T</span><span style="color: #000000; font-size: 12pt">&gt;</span><span style="color: #000000; font-size: 12pt">::ReadVector(&nbsp;vector</span><span style="color: #000000; font-size: 12pt">&lt;</span><span style="color: #000000; font-size: 12pt">T</span><span style="color: #000000; font-size: 12pt">&gt;&amp;</span><span style="color: #000000; font-size: 12pt">&nbsp;v_t)<br /></span><span style="color: #008080; font-size: 12pt">&nbsp;55</span>&nbsp;<span style="color: #000000; font-size: 12pt">{<br /></span><span style="color: #008080; font-size: 12pt">&nbsp;56</span>&nbsp;<span style="color: #000000; font-size: 12pt">&nbsp;&nbsp;&nbsp;&nbsp;m_vt.clear();<br /></span><span style="color: #008080; font-size: 12pt">&nbsp;57</span>&nbsp;<span style="color: #000000; font-size: 12pt">&nbsp;&nbsp;&nbsp;&nbsp;copy(&nbsp;v_t.begin(),&nbsp;v_t.end(),&nbsp;back_inserter(&nbsp;m_vt&nbsp;)&nbsp;);<br /></span><span style="color: #008080; font-size: 12pt">&nbsp;58</span>&nbsp;<span style="color: #000000; font-size: 12pt">}<br /></span><span style="color: #008080; font-size: 12pt">&nbsp;59</span>&nbsp;<span style="color: #000000"><br /></span><span style="color: #008080; font-size: 12pt">&nbsp;60</span>&nbsp;<span style="color: #000000; font-size: 12pt">template&nbsp;</span><span style="color: #000000; font-size: 12pt">&lt;</span><span style="color: #000000; font-size: 12pt">typename&nbsp;T</span><span style="color: #000000; font-size: 12pt">&gt;</span><span style="color: #000000"><br /></span><span style="color: #008080; font-size: 12pt">&nbsp;61</span>&nbsp;<span style="color: #000000"></span><span style="color: #0000ff; font-size: 12pt">bool</span><span style="color: #000000; font-size: 12pt">&nbsp;Context</span><span style="color: #000000; font-size: 12pt">&lt;</span><span style="color: #000000; font-size: 12pt">T</span><span style="color: #000000; font-size: 12pt">&gt;</span><span style="color: #000000; font-size: 12pt">::SortVector()<br /></span><span style="color: #008080; font-size: 12pt">&nbsp;62</span>&nbsp;<span style="color: #000000; font-size: 12pt">{<br /></span><span style="color: #008080; font-size: 12pt">&nbsp;63</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff; font-size: 12pt">if</span><span style="color: #000000; font-size: 12pt">&nbsp;(&nbsp;NULL&nbsp;</span><span style="color: #000000; font-size: 12pt">==</span><span style="color: #000000; font-size: 12pt">&nbsp;m_pStrategy&nbsp;)<br /></span><span style="color: #008080; font-size: 12pt">&nbsp;64</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff; font-size: 12pt">return</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff; font-size: 12pt">false</span><span style="color: #000000; font-size: 12pt">;<br /></span><span style="color: #008080; font-size: 12pt">&nbsp;65</span>&nbsp;<span style="color: #000000"><br /></span><span style="color: #008080; font-size: 12pt">&nbsp;66</span>&nbsp;<span style="color: #000000; font-size: 12pt">&nbsp;&nbsp;&nbsp;&nbsp;m_pStrategy</span><span style="color: #000000; font-size: 12pt">-&gt;</span><span style="color: #000000; font-size: 12pt">Sort(&nbsp;m_vt&nbsp;);<br /></span><span style="color: #008080; font-size: 12pt">&nbsp;67</span>&nbsp;<span style="color: #000000"><br /></span><span style="color: #008080; font-size: 12pt">&nbsp;68</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff; font-size: 12pt">return</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff; font-size: 12pt">true</span><span style="color: #000000; font-size: 12pt">;<br /></span><span style="color: #008080; font-size: 12pt">&nbsp;69</span>&nbsp;<span style="color: #000000; font-size: 12pt">}<br /></span><span style="color: #008080; font-size: 12pt">&nbsp;70</span>&nbsp;<span style="color: #000000"><br /></span><span style="color: #008080; font-size: 12pt">&nbsp;71</span>&nbsp;<span style="color: #000000; font-size: 12pt">template&nbsp;</span><span style="color: #000000; font-size: 12pt">&lt;</span><span style="color: #000000; font-size: 12pt">typename&nbsp;T</span><span style="color: #000000; font-size: 12pt">&gt;</span><span style="color: #000000"><br /></span><span style="color: #008080; font-size: 12pt">&nbsp;72</span>&nbsp;<span style="color: #000000"></span><span style="color: #0000ff; font-size: 12pt">void</span><span style="color: #000000; font-size: 12pt">&nbsp;Context</span><span style="color: #000000; font-size: 12pt">&lt;</span><span style="color: #000000; font-size: 12pt">T</span><span style="color: #000000; font-size: 12pt">&gt;</span><span style="color: #000000; font-size: 12pt">::OutputVector()<br /></span><span style="color: #008080; font-size: 12pt">&nbsp;73</span>&nbsp;<span style="color: #000000; font-size: 12pt">{<br /></span><span style="color: #008080; font-size: 12pt">&nbsp;74</span>&nbsp;<span style="color: #000000; font-size: 12pt">&nbsp;&nbsp;&nbsp;&nbsp;copy(&nbsp;m_vt.begin(),&nbsp;m_vt.end(),&nbsp;ostream_iterator</span><span style="color: #000000; font-size: 12pt">&lt;</span><span style="color: #000000; font-size: 12pt">T</span><span style="color: #000000; font-size: 12pt">&gt;</span><span style="color: #000000; font-size: 12pt">(&nbsp;cout,&nbsp;</span><span style="color: #000000; font-size: 12pt">"</span><span style="color: #000000">&nbsp;</span><span style="color: #000000; font-size: 12pt">"</span><span style="color: #000000; font-size: 12pt">&nbsp;)&nbsp;);<br /></span><span style="color: #008080; font-size: 12pt">&nbsp;75</span>&nbsp;<span style="color: #000000; font-size: 12pt">}<br /></span><span style="color: #008080; font-size: 12pt">&nbsp;76</span>&nbsp;<span style="color: #000000"><br /></span><span style="color: #008080; font-size: 12pt">&nbsp;77</span>&nbsp;<span style="color: #000000"></span><span style="color: #008000; font-size: 12pt">//</span><span style="color: #008000; font-size: 12pt">&nbsp;a&nbsp;functor&nbsp;to&nbsp;generate&nbsp;random&nbsp;int</span><span style="color: #008000"><br /></span><span style="color: #008080; font-size: 12pt">&nbsp;78</span>&nbsp;<span style="color: #008000"></span><span style="color: #0000ff; font-size: 12pt">struct</span><span style="color: #000000; font-size: 12pt">&nbsp;RandGen<br /></span><span style="color: #008080; font-size: 12pt">&nbsp;79</span>&nbsp;<span style="color: #000000; font-size: 12pt">{<br /></span><span style="color: #008080; font-size: 12pt">&nbsp;80</span>&nbsp;<span style="color: #000000; font-size: 12pt">&nbsp;&nbsp;&nbsp;&nbsp;RandGen(</span><span style="color: #0000ff; font-size: 12pt">int</span><span style="color: #000000; font-size: 12pt">&nbsp;ratio)&nbsp;{&nbsp;m_ratio&nbsp;</span><span style="color: #000000; font-size: 12pt">=</span><span style="color: #000000; font-size: 12pt">&nbsp;ratio;&nbsp;}<br /></span><span style="color: #008080; font-size: 12pt">&nbsp;81</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff; font-size: 12pt">int</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff; font-size: 12pt">operator</span><span style="color: #000000; font-size: 12pt">()&nbsp;()&nbsp;{&nbsp;</span><span style="color: #0000ff; font-size: 12pt">return</span><span style="color: #000000; font-size: 12pt">&nbsp;rand()&nbsp;</span><span style="color: #000000; font-size: 12pt">%</span><span style="color: #000000; font-size: 12pt">&nbsp;m_ratio&nbsp;</span><span style="color: #000000; font-size: 12pt">+</span><span style="color: #000000">&nbsp;</span><span style="color: #000000; font-size: 12pt">1</span><span style="color: #000000; font-size: 12pt">;&nbsp;}<br /></span><span style="color: #008080; font-size: 12pt">&nbsp;82</span>&nbsp;<span style="color: #000000"></span><span style="color: #0000ff; font-size: 12pt">private</span><span style="color: #000000; font-size: 12pt">:<br /></span><span style="color: #008080; font-size: 12pt">&nbsp;83</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff; font-size: 12pt">int</span><span style="color: #000000; font-size: 12pt">&nbsp;m_ratio;<br /></span><span style="color: #008080; font-size: 12pt">&nbsp;84</span>&nbsp;<span style="color: #000000; font-size: 12pt">};<br /></span><span style="color: #008080; font-size: 12pt">&nbsp;85</span>&nbsp;<span style="color: #000000"><br /></span><span style="color: #008080; font-size: 12pt">&nbsp;86</span>&nbsp;<span style="color: #000000"></span><span style="color: #0000ff; font-size: 12pt">int</span><span style="color: #000000; font-size: 12pt">&nbsp;main()<br /></span><span style="color: #008080; font-size: 12pt">&nbsp;87</span>&nbsp;<span style="color: #000000; font-size: 12pt">{<br /></span><span style="color: #008080; font-size: 12pt">&nbsp;88</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff; font-size: 12pt">const</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff; font-size: 12pt">int</span><span style="color: #000000; font-size: 12pt">&nbsp;NUM&nbsp;</span><span style="color: #000000; font-size: 12pt">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000; font-size: 12pt">9</span><span style="color: #000000; font-size: 12pt">;<br /></span><span style="color: #008080; font-size: 12pt">&nbsp;89</span>&nbsp;<span style="color: #000000; font-size: 12pt">&nbsp;&nbsp;&nbsp;&nbsp;vector</span><span style="color: #000000; font-size: 12pt">&lt;</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff; font-size: 12pt">int</span><span style="color: #000000">&nbsp;</span><span style="color: #000000; font-size: 12pt">&gt;</span><span style="color: #000000; font-size: 12pt">&nbsp;vi;<br /></span><span style="color: #008080; font-size: 12pt">&nbsp;90</span>&nbsp;<span style="color: #000000; font-size: 12pt">&nbsp;&nbsp;&nbsp;&nbsp;time_t&nbsp;t;<br /></span><span style="color: #008080; font-size: 12pt">&nbsp;91</span>&nbsp;<span style="color: #000000; font-size: 12pt">&nbsp;&nbsp;&nbsp;&nbsp;srand(&nbsp;(unsigned)&nbsp;time(</span><span style="color: #000000; font-size: 12pt">&amp;</span><span style="color: #000000; font-size: 12pt">t)&nbsp;);<br /></span><span style="color: #008080; font-size: 12pt">&nbsp;92</span>&nbsp;<span style="color: #000000"><br /></span><span style="color: #008080; font-size: 12pt">&nbsp;93</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; font-size: 12pt">//</span><span style="color: #008000; font-size: 12pt">&nbsp;create&nbsp;a&nbsp;vector&nbsp;with&nbsp;random&nbsp;information</span><span style="color: #008000"><br /></span><span style="color: #008080; font-size: 12pt">&nbsp;94</span>&nbsp;<span style="color: #008000"></span><span style="color: #000000; font-size: 12pt">&nbsp;&nbsp;&nbsp;&nbsp;vi.reserve(NUM&nbsp;</span><span style="color: #000000; font-size: 12pt">+</span><span style="color: #000000">&nbsp;</span><span style="color: #000000; font-size: 12pt">1</span><span style="color: #000000; font-size: 12pt">);<br /></span><span style="color: #008080; font-size: 12pt">&nbsp;95</span>&nbsp;<span style="color: #000000; font-size: 12pt">&nbsp;&nbsp;&nbsp;&nbsp;generate_n(back_inserter(vi),&nbsp;NUM,&nbsp;RandGen(NUM));<br /></span><span style="color: #008080; font-size: 12pt">&nbsp;96</span>&nbsp;<span style="color: #000000"><br /></span><span style="color: #008080; font-size: 12pt">&nbsp;97</span>&nbsp;<span style="color: #000000; font-size: 12pt">&nbsp;&nbsp;&nbsp;&nbsp;Context</span><span style="color: #000000; font-size: 12pt">&lt;</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff; font-size: 12pt">int</span><span style="color: #000000">&nbsp;</span><span style="color: #000000; font-size: 12pt">&gt;</span><span style="color: #000000; font-size: 12pt">&nbsp;&nbsp;con;<br /></span><span style="color: #008080; font-size: 12pt">&nbsp;98</span>&nbsp;<span style="color: #000000; font-size: 12pt">&nbsp;&nbsp;&nbsp;&nbsp;con.SetStrategy(&nbsp;</span><span style="color: #0000ff; font-size: 12pt">new</span><span style="color: #000000; font-size: 12pt">&nbsp;SortQuick</span><span style="color: #000000; font-size: 12pt">&lt;</span><span style="color: #0000ff; font-size: 12pt">int</span><span style="color: #000000; font-size: 12pt">&gt;</span><span style="color: #000000; font-size: 12pt">()&nbsp;);<br /></span><span style="color: #008080; font-size: 12pt">&nbsp;99</span>&nbsp;<span style="color: #000000; font-size: 12pt">&nbsp;&nbsp;&nbsp;&nbsp;con.ReadVector(&nbsp;vi&nbsp;);<br /></span><span style="color: #008080; font-size: 12pt">100</span>&nbsp;<span style="color: #000000; font-size: 12pt">&nbsp;&nbsp;&nbsp;&nbsp;con.OutputVector();<br /></span><span style="color: #008080; font-size: 12pt">101</span>&nbsp;<span style="color: #000000"><br /></span><span style="color: #008080; font-size: 12pt">102</span>&nbsp;<span style="color: #000000; font-size: 12pt">&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;</span><span style="color: #000000; font-size: 12pt">&lt;&lt;</span><span style="color: #000000; font-size: 12pt">&nbsp;endl;<br /></span><span style="color: #008080; font-size: 12pt">103</span>&nbsp;<span style="color: #000000"><br /></span><span style="color: #008080; font-size: 12pt">104</span>&nbsp;<span style="color: #000000; font-size: 12pt">&nbsp;&nbsp;&nbsp;&nbsp;con.SortVector();<br /></span><span style="color: #008080; font-size: 12pt">105</span>&nbsp;<span style="color: #000000; font-size: 12pt">&nbsp;&nbsp;&nbsp;&nbsp;con.OutputVector();<br /></span><span style="color: #008080; font-size: 12pt">106</span>&nbsp;<span style="color: #000000"><br /></span><span style="color: #008080; font-size: 12pt">107</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff; font-size: 12pt">return</span><span style="color: #000000">&nbsp;</span><span style="color: #000000; font-size: 12pt">0</span><span style="color: #000000; font-size: 12pt">;<br /></span><span style="color: #008080; font-size: 12pt">108</span>&nbsp;<span style="color: #000000; font-size: 12pt">}</span></div><font color="#000099"><br /></font><span style="font-size: 12pt">本文转自：</span><a href="http://blog.csdn.net/haiyan0106/article/details/1651797"><span style="font-size: 12pt">http://blog.csdn.net/haiyan0106/article/details/1651797</span></a><img src ="http://www.cppblog.com/wanghaiguang/aggbug/183830.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/wanghaiguang/" target="_blank">王海光</a> 2012-07-17 08:11 <a href="http://www.cppblog.com/wanghaiguang/archive/2012/07/17/183830.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++设计模式-Iterator </title><link>http://www.cppblog.com/wanghaiguang/archive/2012/07/16/183667.html</link><dc:creator>王海光</dc:creator><author>王海光</author><pubDate>Mon, 16 Jul 2012 00:11:00 GMT</pubDate><guid>http://www.cppblog.com/wanghaiguang/archive/2012/07/16/183667.html</guid><wfw:comment>http://www.cppblog.com/wanghaiguang/comments/183667.html</wfw:comment><comments>http://www.cppblog.com/wanghaiguang/archive/2012/07/16/183667.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/wanghaiguang/comments/commentRss/183667.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/wanghaiguang/services/trackbacks/183667.html</trackback:ping><description><![CDATA[<div id="cnblogs_post_body"><span style="font-size: 12pt">一、概述<br /></span><span style="font-size: 12pt">Iterator（迭代器）模式又称Cursor（游标）模式，用于提供一种方法顺序访问一个聚合对象中各个元素<strong><font color="#663300"><span style="font-size: 12pt">,</span></font></strong></span><span style="font-size: 12pt"> 而又不需暴露该对象的内部表示。或者这样说可能更容易理解：Iterator模式是运用于聚合对象的一种模式，通过运用该模式，使得我们可以在不知道对象内部表示的情况下，按照一定顺序（由iterator提供的方法）访问聚合对象中的各个元素。<br /></span><span style="font-size: 12pt">由于Iterator模式的以上特性：与聚合对象耦合，在一定程度上限制了它的广泛运用，一般仅用于底层聚合支持类，如STL的list、vector、stack等容器类及ostream_iterator等扩展iterator。<br /></span><span style="font-size: 12pt">根据STL中的分类，iterator包括：<br /></span><span style="font-size: 12pt">Input Iterator：只能单步向前迭代元素，不允许修改由该类迭代器引用的元素。<br /></span><span style="font-size: 12pt">Output Iterator：该类迭代器和Input Iterator极其相似，也只能单步向前迭代元素，不同的是该类迭代器对元素只有写的权力。<br /></span><span style="font-size: 12pt">Forward Iterator：该类迭代器可以在一个正确的区间中进行读写操作，它拥有Input Iterator的所有特性，和Output Iterator的部分特性，以及单步向前迭代元素的能力。<br /></span><span style="font-size: 12pt">Bidirectional Iterator：该类迭代器是在Forward Iterator的基础上提供了单步向后迭代元素的能力。<br /></span><span style="font-size: 12pt">Random Access Iterator：该类迭代器能完成上面所有迭代器的工作，它自己独有的特性就是可以像指针那样进行算术计算，而不是仅仅只有单步向前或向后迭代。<br /></span><span style="font-size: 12pt">这五类迭代器的从属关系，如下图所示，其中箭头A&#8594;B表示，A是B的强化类型，这也说明了如果一个算法要求B，那么A也可以应用于其中。<br /><br /></span><span style="font-size: 12pt">图<font color="#999900"><span style="font-size: 12pt">1</span></font></span><span style="font-size: 12pt">、五种迭代器之间的关系<br /></span><span style="font-size: 12pt">vector 和deque提供的是RandomAccessIterator，list提供的是BidirectionalIterator，set和map提供的 iterators是 ForwardIterator，关于STL中iterator的更多信息。<br /></span><span style="font-size: 12pt">二、结构<br /></span><span style="font-size: 12pt">Iterator模式的UML结构如下图所示：<br /><img border="0" alt="" src="http://www.cppblog.com/images/cppblog_com/wanghaiguang/image/设计模式/gof32.jpg" width="555" height="267" /><br /></span><span style="font-size: 12pt">三、应用<br /></span><span style="font-size: 12pt">Iterator模式有三个重要的作用：<font color="#999900"><br /><span style="font-size: 12pt">1</span></font></span><span style="font-size: 12pt">）它支持以不同的方式遍历一个聚合 复杂的聚合可用多种方式进行遍历，如二叉树的遍历，可以采用前序、中序或后序遍历。迭代器模式使得改变遍历算法变得很容易<strong><font color="#663300"><span style="font-size: 12pt">:</span></font></strong></span><span style="font-size: 12pt"> 仅需用一个不同的迭代器的实例代替原先的实例即可，你也可以自己定义迭代器的子类以支持新的遍历，或者可以在遍历中增加一些逻辑，如有条件的遍历等。<font color="#999900"><br /><span style="font-size: 12pt">2</span></font></span><span style="font-size: 12pt">）迭代器简化了聚合的接口 有了迭代器的遍历接口，聚合本身就不再需要类似的遍历接口了，这样就简化了聚合的接口。<font color="#999900"><br /><span style="font-size: 12pt">3</span></font></span><span style="font-size: 12pt">）在同一个聚合上可以有多个遍历 每个迭代器保持它自己的遍历状态，因此你可以同时进行多个遍历。<font color="#999900"><br /><span style="font-size: 12pt">4</span></font></span><span style="font-size: 12pt">）此外，Iterator模式可以为遍历不同的聚合结构（需拥有相同的基类）提供一个统一的接口，即支持多态迭代。<br /></span><span style="font-size: 12pt">简 单说来，迭代器模式也是Delegate原则的一个应用，它将对集合进行遍历的功能封装成独立的Iterator，不但简化了集合的接口，也使得修改、增 加遍历方式变得简单。从这一点讲，该模式与Bridge模式、Strategy模式有一定的相似性，但Iterator模式所讨论的问题与集合密切相关， 造成在Iterator在实现上具有一定的特殊性，具体将在示例部分进行讨论。<br /><br /></span><span style="font-size: 12pt">四、优缺点<br /></span><span style="font-size: 12pt">正如前面所说，与集合密切相关，限制了 Iterator模式的广泛使用，就个人而言，我不大认同将Iterator作为模式提出的观点，但它又确实符合模式&#8220;经常出现的特定问题的解决方案&#8221;的 特质，以至于我又不得不承认它是个模式。在一般的底层集合支持类中，我们往往不愿&#8220;避轻就重&#8221;将集合设计成集合<strong><font color="#663300"><span style="font-size: 12pt"> +</span></font></strong></span><span style="font-size: 12pt"> Iterator 的形式，而是将遍历的功能直接交由集合完成，以免犯了&#8220;过度设计&#8221;的诟病，但是，如果我们的集合类确实需要支持多种遍历方式（仅此一点仍不一定需要考虑 Iterator模式，直接交由集合完成往往更方便），或者，为了与系统提供或使用的其它机制，如STL算法，保持一致时，Iterator模式才值得考 虑。<br /><br /></span><span style="font-size: 12pt">五、举例<br /></span><span style="font-size: 12pt">可以考虑使用两种方式来实现Iterator模式：内嵌类或者友元类。通常迭代类需访问集合类中的内部数据结构，为此，可在集合类中设置迭代类为<font color="#990000"><span style="font-size: 12pt">friend class</span></font></span><span style="font-size: 12pt">，但这不利于添加新的迭代类，因为需要修改集合类，添加<font color="#990000"><span style="font-size: 12pt">friend class</span></font></span><span style="font-size: 12pt">语句。也可以在抽象迭代类中定义<font color="#990000"><span style="font-size: 12pt">protected</span></font></span><span style="font-size: 12pt">型的存取集合类内部数据的函数，这样迭代子类就可以访问集合类数据了，这种方式比较容易添加新的迭代方式，但这种方式也存在明显的缺点：这些函数只能用于特定聚合类，并且，不可避免造成代码更加复杂。<br /><br /></span><span style="font-size: 12pt">STL的list<strong><font color="#663300"><span style="font-size: 12pt">::</span></font></strong></span><span style="font-size: 12pt">iterator、deque<strong><font color="#663300"><span style="font-size: 12pt">::</span></font></strong></span><span style="font-size: 12pt">iterator、rbtree<strong><font color="#663300"><span style="font-size: 12pt">::</span></font></strong></span><span style="font-size: 12pt">iterator等采用的都是外部Iterator类的形式，虽然STL的集合类的iterator分散在各个集合类中，但由于各Iterator类具有相同的基类，保持了相同的对外的接口（包括一些traits及tags等，感兴趣者请认真阅读参考<font color="#999900"><span style="font-size: 12pt">1</span></font></span><span style="font-size: 12pt">、<font color="#999900"><span style="font-size: 12pt">2</span></font></span><span style="font-size: 12pt">），从而使得它们看起来仍然像一个整体，同时也使得应用algorithm成为可能。我们如果要扩展STL的iterator，也需要注意这一点，否则，我们扩展的iterator将可能无法应用于各algorithm。<br /><br /></span><span style="font-size: 12pt">以下是一个遍历二叉树的Iterator的例子，为了方便支持多种遍历方式，并便于遍历方式的扩展，其中还使用了Strategy模式（见笔记<font color="#999900"><span style="font-size: 12pt">21</span></font></span><span style="font-size: 12pt">）：<br /></span><span style="font-size: 12pt">（注：<font color="#999900"><span style="font-size: 12pt">1</span></font></span><span style="font-size: 12pt">、虽然下面这个示例是本系列所有示例中花费我时间最多的一个，但我不得不承认，它非常不完善，感兴趣的朋友，可以考虑参考下面的参考材料将其补充完善，或提出宝贵改进意见。<font color="#999900"><span style="font-size: 12pt">2</span></font></span><span style="font-size: 12pt">、 我本想考虑将其封装成与STL风格一致的形式，使得我们遍历二叉树必须通过Iterator来进行，但由于二叉树在结构上较线性存储结构复杂，使访问必须 通过Iterator来进行，但这不可避免使得BinaryTree的访问变得异常麻烦，在具体应用中还需要认真考虑。<font color="#999900"><span style="font-size: 12pt">3</span></font></span><span style="font-size: 12pt">、以下只提供了Inorder<strong><font color="#663300"><span style="font-size: 12pt">&lt;</span></font></strong></span><span style="font-size: 12pt">中序<strong><font color="#663300"><span style="font-size: 12pt">&gt;</span></font></strong></span><span style="font-size: 12pt">遍历iterator的实现。）</span><br />
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080; font-size: 12pt">&nbsp;1</span>&nbsp;<span style="color: #000000; font-size: 12pt">#include&nbsp;</span><span style="color: #000000; font-size: 12pt">&lt;</span><span style="color: #000000; font-size: 12pt">assert.h</span><span style="color: #000000; font-size: 12pt">&gt;</span><span style="color: #000000"><br /></span><span style="color: #008080; font-size: 12pt">&nbsp;2</span>&nbsp;<span style="color: #000000"><br /></span><span style="color: #008080; font-size: 12pt">&nbsp;3</span>&nbsp;<span style="color: #000000; font-size: 12pt">#include&nbsp;</span><span style="color: #000000; font-size: 12pt">&lt;</span><span style="color: #000000; font-size: 12pt">iostream</span><span style="color: #000000; font-size: 12pt">&gt;</span><span style="color: #000000"><br /></span><span style="color: #008080; font-size: 12pt">&nbsp;4</span>&nbsp;<span style="color: #000000; font-size: 12pt">#include&nbsp;</span><span style="color: #000000; font-size: 12pt">&lt;</span><span style="color: #000000; font-size: 12pt">xutility</span><span style="color: #000000; font-size: 12pt">&gt;</span><span style="color: #000000"><br /></span><span style="color: #008080; font-size: 12pt">&nbsp;5</span>&nbsp;<span style="color: #000000; font-size: 12pt">#include&nbsp;</span><span style="color: #000000; font-size: 12pt">&lt;</span><span style="color: #000000; font-size: 12pt">iterator</span><span style="color: #000000; font-size: 12pt">&gt;</span><span style="color: #000000"><br /></span><span style="color: #008080; font-size: 12pt">&nbsp;6</span>&nbsp;<span style="color: #000000; font-size: 12pt">#include&nbsp;</span><span style="color: #000000; font-size: 12pt">&lt;</span><span style="color: #000000; font-size: 12pt">algorithm</span><span style="color: #000000; font-size: 12pt">&gt;</span><span style="color: #000000"><br /></span><span style="color: #008080; font-size: 12pt">&nbsp;7</span>&nbsp;<span style="color: #000000"></span><span style="color: #0000ff; font-size: 12pt">using</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff; font-size: 12pt">namespace</span><span style="color: #000000; font-size: 12pt">&nbsp;std;<br /></span><span style="color: #008080; font-size: 12pt">&nbsp;8</span>&nbsp;<span style="color: #000000"><br /></span><span style="color: #008080; font-size: 12pt">&nbsp;9</span>&nbsp;<span style="color: #000000; font-size: 12pt">template&nbsp;</span><span style="color: #000000; font-size: 12pt">&lt;</span><span style="color: #000000; font-size: 12pt">typename&nbsp;T</span><span style="color: #000000; font-size: 12pt">&gt;</span><span style="color: #000000"><br /></span><span style="color: #008080; font-size: 12pt">10</span>&nbsp;<span style="color: #000000"></span><span style="color: #0000ff; font-size: 12pt">class</span><span style="color: #000000; font-size: 12pt">&nbsp;BinaryTree;<br /></span><span style="color: #008080; font-size: 12pt">11</span>&nbsp;<span style="color: #000000; font-size: 12pt">template&nbsp;</span><span style="color: #000000; font-size: 12pt">&lt;</span><span style="color: #000000; font-size: 12pt">typename&nbsp;T</span><span style="color: #000000; font-size: 12pt">&gt;</span><span style="color: #000000"><br /></span><span style="color: #008080; font-size: 12pt">12</span>&nbsp;<span style="color: #000000"></span><span style="color: #0000ff; font-size: 12pt">class</span><span style="color: #000000; font-size: 12pt">&nbsp;Iterator;<br /></span><span style="color: #008080; font-size: 12pt">13</span>&nbsp;<span style="color: #000000"><br /></span><span style="color: #008080; font-size: 12pt">14</span>&nbsp;<span style="color: #000000; font-size: 12pt">template&nbsp;</span><span style="color: #000000; font-size: 12pt">&lt;</span><span style="color: #000000; font-size: 12pt">typename&nbsp;T</span><span style="color: #000000; font-size: 12pt">&gt;</span><span style="color: #000000"><br /></span><span style="color: #008080; font-size: 12pt">15</span>&nbsp;<span style="color: #000000"></span><span style="color: #0000ff; font-size: 12pt">class</span><span style="color: #000000; font-size: 12pt">&nbsp;BinaryTreeNode<br /></span><span style="color: #008080; font-size: 12pt">16</span>&nbsp;<span style="color: #000000; font-size: 12pt">{<br /></span><span style="color: #008080; font-size: 12pt">17</span>&nbsp;<span style="color: #000000"></span><span style="color: #0000ff; font-size: 12pt">public</span><span style="color: #000000; font-size: 12pt">:<br /></span><span style="color: #008080; font-size: 12pt">18</span>&nbsp;<span style="color: #000000; font-size: 12pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;BinaryTreeNode</span><span style="color: #000000; font-size: 12pt">&lt;</span><span style="color: #000000; font-size: 12pt">T</span><span style="color: #000000; font-size: 12pt">&gt;</span><span style="color: #000000; font-size: 12pt">&nbsp;NODE;<br /></span><span style="color: #008080; font-size: 12pt">19</span>&nbsp;<span style="color: #000000; font-size: 12pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;BinaryTreeNode</span><span style="color: #000000; font-size: 12pt">&lt;</span><span style="color: #000000; font-size: 12pt">T</span><span style="color: #000000; font-size: 12pt">&gt;*</span><span style="color: #000000; font-size: 12pt">&nbsp;NODE_PTR;<br /></span><span style="color: #008080; font-size: 12pt">20</span>&nbsp;<span style="color: #000000"><br /></span><span style="color: #008080; font-size: 12pt">21</span>&nbsp;<span style="color: #000000; font-size: 12pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BinaryTreeNode(</span><span style="color: #0000ff; font-size: 12pt">const</span><span style="color: #000000; font-size: 12pt">&nbsp;T</span><span style="color: #000000; font-size: 12pt">&amp;</span><span style="color: #000000; font-size: 12pt">&nbsp;element)&nbsp;:&nbsp;data(element),&nbsp;leftChild(NULL),&nbsp;rightChild(NULL),&nbsp;parent(NULL)&nbsp;{&nbsp;}<br /></span><span style="color: #008080; font-size: 12pt">22</span>&nbsp;<span style="color: #000000; font-size: 12pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BinaryTreeNode(</span><span style="color: #0000ff; font-size: 12pt">const</span><span style="color: #000000; font-size: 12pt">&nbsp;T</span><span style="color: #000000; font-size: 12pt">&amp;</span><span style="color: #000000; font-size: 12pt">&nbsp;element,&nbsp;NODE_PTR&nbsp;leftChild,&nbsp;NODE_PTR&nbsp;rightChild)<br /></span><span style="color: #008080; font-size: 12pt">23</span>&nbsp;<span style="color: #000000; font-size: 12pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:data(element),&nbsp;leftChild(leftChild),&nbsp;rightChild(rightChild),&nbsp;parent(NULL)<br /></span><span style="color: #008080; font-size: 12pt">24</span>&nbsp;<span style="color: #000000; font-size: 12pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br /></span><span style="color: #008080; font-size: 12pt">25</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff; font-size: 12pt">if</span><span style="color: #000000; font-size: 12pt">&nbsp;(leftChild)<br /></span><span style="color: #008080; font-size: 12pt">26</span>&nbsp;<span style="color: #000000; font-size: 12pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;leftChild</span><span style="color: #000000; font-size: 12pt">-&gt;</span><span style="color: #000000; font-size: 12pt">setParent(</span><span style="color: #0000ff; font-size: 12pt">this</span><span style="color: #000000; font-size: 12pt">);<br /></span><span style="color: #008080; font-size: 12pt">27</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff; font-size: 12pt">if</span><span style="color: #000000; font-size: 12pt">&nbsp;(rightChild)<br /></span><span style="color: #008080; font-size: 12pt">28</span>&nbsp;<span style="color: #000000; font-size: 12pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rightChild</span><span style="color: #000000; font-size: 12pt">-&gt;</span><span style="color: #000000; font-size: 12pt">setParent(</span><span style="color: #0000ff; font-size: 12pt">this</span><span style="color: #000000; font-size: 12pt">);<br /></span><span style="color: #008080; font-size: 12pt">29</span>&nbsp;<span style="color: #000000; font-size: 12pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /></span><span style="color: #008080; font-size: 12pt">30</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;<br /></span><span style="color: #008080; font-size: 12pt">31</span>&nbsp;<span style="color: #000000; font-size: 12pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;T&nbsp;getData(</span><span style="color: #0000ff; font-size: 12pt">void</span><span style="color: #000000; font-size: 12pt">)&nbsp;</span><span style="color: #0000ff; font-size: 12pt">const</span><span style="color: #000000; font-size: 12pt">&nbsp;{&nbsp;</span><span style="color: #0000ff; font-size: 12pt">return</span><span style="color: #000000; font-size: 12pt">&nbsp;data;&nbsp;}<br /></span><span style="color: #008080; font-size: 12pt">32</span>&nbsp;<span style="color: #000000; font-size: 12pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NODE_PTR&nbsp;getLeft(</span><span style="color: #0000ff; font-size: 12pt">void</span><span style="color: #000000; font-size: 12pt">)&nbsp;</span><span style="color: #0000ff; font-size: 12pt">const</span><span style="color: #000000; font-size: 12pt">&nbsp;{&nbsp;</span><span style="color: #0000ff; font-size: 12pt">return</span><span style="color: #000000; font-size: 12pt">&nbsp;leftChild;&nbsp;}<br /></span><span style="color: #008080; font-size: 12pt">33</span>&nbsp;<span style="color: #000000; font-size: 12pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NODE_PTR&nbsp;getRight(</span><span style="color: #0000ff; font-size: 12pt">void</span><span style="color: #000000; font-size: 12pt">)&nbsp;</span><span style="color: #0000ff; font-size: 12pt">const</span><span style="color: #000000; font-size: 12pt">&nbsp;{&nbsp;</span><span style="color: #0000ff; font-size: 12pt">return</span><span style="color: #000000; font-size: 12pt">&nbsp;rightChild;&nbsp;}<br /></span><span style="color: #008080; font-size: 12pt">34</span>&nbsp;<span style="color: #000000; font-size: 12pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NODE_PTR&nbsp;getParent(</span><span style="color: #0000ff; font-size: 12pt">void</span><span style="color: #000000; font-size: 12pt">)&nbsp;</span><span style="color: #0000ff; font-size: 12pt">const</span><span style="color: #000000; font-size: 12pt">&nbsp;{&nbsp;</span><span style="color: #0000ff; font-size: 12pt">return</span><span style="color: #000000; font-size: 12pt">&nbsp;parent;&nbsp;}<br /></span><span style="color: #008080; font-size: 12pt">35</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff; font-size: 12pt">void</span><span style="color: #000000; font-size: 12pt">&nbsp;SetData(</span><span style="color: #0000ff; font-size: 12pt">const</span><span style="color: #000000; font-size: 12pt">&nbsp;T</span><span style="color: #000000; font-size: 12pt">&amp;</span><span style="color: #000000; font-size: 12pt">&nbsp;data)&nbsp;{&nbsp;</span><span style="color: #0000ff; font-size: 12pt">this</span><span style="color: #000000; font-size: 12pt">-&gt;</span><span style="color: #000000; font-size: 12pt">data&nbsp;</span><span style="color: #000000; font-size: 12pt">=</span><span style="color: #000000; font-size: 12pt">&nbsp;item;&nbsp;}<br /></span><span style="color: #008080; font-size: 12pt">36</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff; font-size: 12pt">void</span><span style="color: #000000; font-size: 12pt">&nbsp;setLeft(NODE_PTR&nbsp;ptr)&nbsp;{&nbsp;leftChild&nbsp;</span><span style="color: #000000; font-size: 12pt">=</span><span style="color: #000000; font-size: 12pt">&nbsp;ptr;&nbsp;ptr</span><span style="color: #000000; font-size: 12pt">-&gt;</span><span style="color: #000000; font-size: 12pt">setParent(</span><span style="color: #0000ff; font-size: 12pt">this</span><span style="color: #000000; font-size: 12pt">);&nbsp;}<br /></span><span style="color: #008080; font-size: 12pt">37</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff; font-size: 12pt">void</span><span style="color: #000000; font-size: 12pt">&nbsp;setRight(NODE_PTR&nbsp;ptr)&nbsp;{&nbsp;rightChild&nbsp;</span><span style="color: #000000; font-size: 12pt">=</span><span style="color: #000000; font-size: 12pt">&nbsp;ptr;&nbsp;ptr</span><span style="color: #000000; font-size: 12pt">-&gt;</span><span style="color: #000000; font-size: 12pt">setParent(</span><span style="color: #0000ff; font-size: 12pt">this</span><span style="color: #000000; font-size: 12pt">);&nbsp;}<br /></span><span style="color: #008080; font-size: 12pt">38</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff; font-size: 12pt">void</span><span style="color: #000000; font-size: 12pt">&nbsp;setParent(NODE_PTR&nbsp;ptr)&nbsp;{&nbsp;parent&nbsp;</span><span style="color: #000000; font-size: 12pt">=</span><span style="color: #000000; font-size: 12pt">&nbsp;ptr;&nbsp;}<br /></span><span style="color: #008080; font-size: 12pt">39</span>&nbsp;<span style="color: #000000"></span><span style="color: #0000ff; font-size: 12pt">private</span><span style="color: #000000; font-size: 12pt">:<br /></span><span style="color: #008080; font-size: 12pt">40</span>&nbsp;<span style="color: #000000; font-size: 12pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;T&nbsp;data;<br /></span><span style="color: #008080; font-size: 12pt">41</span>&nbsp;<span style="color: #000000; font-size: 12pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NODE_PTR&nbsp;leftChild;<br /></span><span style="color: #008080; font-size: 12pt">42</span>&nbsp;<span style="color: #000000; font-size: 12pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NODE_PTR&nbsp;rightChild;<br /></span><span style="color: #008080; font-size: 12pt">43</span>&nbsp;<span style="color: #000000; font-size: 12pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NODE_PTR&nbsp;parent;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; font-size: 12pt">//</span><span style="color: #008000; font-size: 12pt">&nbsp;pointer&nbsp;to&nbsp;parent&nbsp;node,&nbsp;needed&nbsp;by&nbsp;iterator</span><span style="color: #008000"><br /></span><span style="color: #008080; font-size: 12pt">44</span>&nbsp;<span style="color: #008000"></span><span style="color: #000000"><br /></span><span style="color: #008080; font-size: 12pt">45</span>&nbsp;<span style="color: #000000; font-size: 12pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;friend&nbsp;</span><span style="color: #0000ff; font-size: 12pt">class</span><span style="color: #000000; font-size: 12pt">&nbsp;BinaryTree</span><span style="color: #000000; font-size: 12pt">&lt;</span><span style="color: #000000; font-size: 12pt">T</span><span style="color: #000000; font-size: 12pt">&gt;</span><span style="color: #000000; font-size: 12pt">;<br /></span><span style="color: #008080; font-size: 12pt">46</span>&nbsp;<span style="color: #000000; font-size: 12pt">};</span></div></div><br />本文转自：<a href="http://www.cnblogs.com/berry/archive/2009/10/12/1581554.html">http://www.cnblogs.com/berry/archive/2009/10/12/1581554.html</a> <img src ="http://www.cppblog.com/wanghaiguang/aggbug/183667.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/wanghaiguang/" target="_blank">王海光</a> 2012-07-16 08:11 <a href="http://www.cppblog.com/wanghaiguang/archive/2012/07/16/183667.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>singleton模式</title><link>http://www.cppblog.com/wanghaiguang/archive/2012/07/13/183112.html</link><dc:creator>王海光</dc:creator><author>王海光</author><pubDate>Fri, 13 Jul 2012 00:14:00 GMT</pubDate><guid>http://www.cppblog.com/wanghaiguang/archive/2012/07/13/183112.html</guid><wfw:comment>http://www.cppblog.com/wanghaiguang/comments/183112.html</wfw:comment><comments>http://www.cppblog.com/wanghaiguang/archive/2012/07/13/183112.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/wanghaiguang/comments/commentRss/183112.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/wanghaiguang/services/trackbacks/183112.html</trackback:ping><description><![CDATA[<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;singleton模式是Gof提出的23中模式之一，也称为单例模式，那么简单说一下，什么叫单例模式呢？<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;通常我们创建类的对象是使用new Object()，然后就调用该对象里面的方法，那么当我们多次使用new Object()的话，会对系统资源造成一种浪费，当然.net内部已经有垃圾回收机制可以处理这种浪费。当然我们并不会再程序里面多次使用new Object()，但是，作为一个类的设计者，我们需要负什么责任，除了让别的模块可以调用使用之外，我们的设计还需要一种规范，这也是OO里面的规范，singleton模式在这里派上了用场。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;singleton模式的意图：确保一个类只能拥有一个实例，并保证逻辑的正确性以及良好的效率，并提供一个该实例的全局访问点。<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;singleton模式类型：单线程singleton，多线程singleton<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;singleton思路：要让使用者只能使用一个实例的话，那么必须绕过常规的公有缺省构造器</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;singleton代码：</p>
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080">&nbsp;1</span>&nbsp;<span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;singleton<br /></span><span style="color: #008080">&nbsp;2</span>&nbsp;<span style="color: #000000">{<br /></span><span style="color: #008080">&nbsp;3</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">private</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">static</span><span style="color: #000000">&nbsp;singleton&nbsp;instance;<br /></span><span style="color: #008080">&nbsp;4</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">private</span><span style="color: #000000">&nbsp;singleton()&nbsp;{&nbsp;}<br /></span><span style="color: #008080">&nbsp;5</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">static</span><span style="color: #000000">&nbsp;singleton&nbsp;Instance<br /></span><span style="color: #008080">&nbsp;6</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;{<br /></span><span style="color: #008080">&nbsp;7</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">get</span><span style="color: #000000"><br /></span><span style="color: #008080">&nbsp;8</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br /></span><span style="color: #008080">&nbsp;9</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(instance&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">null</span><span style="color: #000000">)<br /></span><span style="color: #008080">10</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br /></span><span style="color: #008080">11</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;instance&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;singleton();<br /></span><span style="color: #008080">12</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /></span><span style="color: #008080">13</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;instance;<br /></span><span style="color: #008080">14</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /></span><span style="color: #008080">15</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}<br /></span><span style="color: #008080">16</span>&nbsp;<span style="color: #000000">}<br /></span><span style="color: #008080">17</span>&nbsp;<span style="color: #000000"></span></div>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;第4行：利用私有构造函数绕开系统自带的缺省公有构造函数，这样就使类的外部不可以直接使用new实例化对象<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;第5行：提供一个静态的公有属性，供类外部调用<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;第9行：在这里可能存在BUG，当有两个线程同时操作公有属性时，常规的话应该返回两个一样的实例，但是假如当第一个实例还未来得及创建时，第二个线程又访问了它，显然也会执行　　　　&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new&nbsp;singleton（）这个语句，那么这两个对象的引用就不一样了，可以使用object.ReferenceEquals测试一下对象的引用是否一样。因此，给大家提供多线程方案，请看下面代码</p>
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080">&nbsp;1</span>&nbsp;<span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;singletons<br /></span><span style="color: #008080">&nbsp;2</span>&nbsp;<span style="color: #000000">{<br /></span><span style="color: #008080">&nbsp;3</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">private</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">static</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">volatile</span><span style="color: #000000">&nbsp;singletons&nbsp;instances&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">null</span><span style="color: #000000">;<br /></span><span style="color: #008080">&nbsp;4</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">private</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">static</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">object</span><span style="color: #000000">&nbsp;lockHelper&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">object</span><span style="color: #000000">();&nbsp;<br /></span><span style="color: #008080">&nbsp;5</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">private</span><span style="color: #000000">&nbsp;singletons()&nbsp;{&nbsp;}<br /></span><span style="color: #008080">&nbsp;6</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">static</span><span style="color: #000000">&nbsp;singletons&nbsp;Instance<br /></span><span style="color: #008080">&nbsp;7</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;{<br /></span><span style="color: #008080">&nbsp;8</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">get</span><span style="color: #000000"><br /></span><span style="color: #008080">&nbsp;9</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br /></span><span style="color: #008080">10</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">(instances</span><span style="color: #000000">==</span><span style="color: #0000ff">null</span><span style="color: #000000">)<br /></span><span style="color: #008080">11</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br /></span><span style="color: #008080">12</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">lock</span><span style="color: #000000">&nbsp;(lockHelper)<br /></span><span style="color: #008080">13</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br /></span><span style="color: #008080">14</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">(instances</span><span style="color: #000000">==</span><span style="color: #0000ff">null</span><span style="color: #000000">&nbsp;)<br /></span><span style="color: #008080">15</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br /></span><span style="color: #008080">16</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;instances&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;singletons();<br /></span><span style="color: #008080">17</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /></span><span style="color: #008080">18</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /></span><span style="color: #008080">19</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /></span><span style="color: #008080">20</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;instances;<br /></span><span style="color: #008080">21</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /></span><span style="color: #008080">22</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}<br /></span><span style="color: #008080">23</span>&nbsp;<span style="color: #000000">}</span></div>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;显然看起来与单线程singleton差不多，多了<span style="color: #0000ff">volatile</span><span style="color: #000000">&nbsp;</span>修饰符，还有一个Object对象，接下来跟大家解释使用这些其中的缘由<br /><span style="color: #0000ff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;volatile</span><span style="color: #000000">&nbsp;</span>修饰符<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;假如我定义两个变量和两个属性</p>
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080">&nbsp;1</span>&nbsp;<span style="color: #000000">&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;a;<br /></span><span style="color: #008080">&nbsp;2</span>&nbsp;<span style="color: #000000">&nbsp;</span><span style="color: #0000ff">volatile</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;b;<br /></span><span style="color: #008080">&nbsp;3</span>&nbsp;<span style="color: #000000">&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;GetFirst<br /></span><span style="color: #008080">&nbsp;4</span>&nbsp;<span style="color: #000000">&nbsp;{<br /></span><span style="color: #008080">&nbsp;5</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">get</span><span style="color: #000000">&nbsp;{&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;a;&nbsp;}<br /></span><span style="color: #008080">&nbsp;6</span>&nbsp;<span style="color: #000000">&nbsp;}<br /></span><span style="color: #008080">&nbsp;7</span>&nbsp;<span style="color: #000000">&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;GetSecond<br /></span><span style="color: #008080">&nbsp;8</span>&nbsp;<span style="color: #000000">&nbsp;{<br /></span><span style="color: #008080">&nbsp;9</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">get</span><span style="color: #000000">&nbsp;{&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;b;&nbsp;}<br /></span><span style="color: #008080">10</span>&nbsp;<span style="color: #000000">&nbsp;}</span></div>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GetFirst会得到当前线程中a的值，而多个线程就会有多个a的变量拷贝，而且这些拷贝之间可以互不相同，换句话说，另一个线程可能改变了它线程内的a值，而这个值和当前线程中的a值不相同，那么就造成线程冲突了。<br />那么再来看看b，因为<span style="color: #0000ff">volatile</span><span style="color: #000000">&nbsp;</span>修饰的变量不允许有不同于&#8220;主&#8221;内存区域的变量拷贝，换句话说，一个变量经<span style="color: #0000ff">volatile</span><span style="color: #000000">&nbsp;修饰后在所有线程中都是同步的；任何线程改变了它的值，所以其他线程立即获取到了相同的值，当然加了<span style="color: #0000ff">volatile</span><span style="color: #000000">&nbsp;</span>修饰的变量存储时会比一般变量消耗的资源要多一点。</span></p>
<p><span style="color: #000000">Object对象锁<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;对象锁可以保证Lock里面的代码只能同时让一个线程执行，所以确保了一个对象只存在一个实例。</span></p>
<p><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;同样的需求可以有不同的方法实现，以下是另外一种实现singleton模式的代码，代码更简单，不够有缺陷，请看</p>
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080">1</span>&nbsp;<span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;singletonss<br /></span><span style="color: #008080">2</span>&nbsp;<span style="color: #000000">&nbsp;{<br /></span><span style="color: #008080">3</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">static</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">readonly</span><span style="color: #000000">&nbsp;singletonss&nbsp;Instance&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;singletonss();<br /></span><span style="color: #008080">4</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">private</span><span style="color: #000000">&nbsp;singletonss()&nbsp;{&nbsp;}<br /></span><span style="color: #008080">5</span>&nbsp;<span style="color: #000000">&nbsp;}</span></div>
<p></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;首先定义一个静态的只读实例，当然也需要私有构造器绕过缺省构造器，这样子也可以保证多线程里也只诞生一个对象实例，因为.Net类型初始化机制保证只有一个线程执行了静态构造器。当然这么少的代码也可以实现singleton，但是静态构造器不支持参数，也不能重构，因为在.Net机制里面只允许一个类拥有一个静态构造器而且是私有的，外部不能调用只能供系统调用，所以我们不能使用参数。<br /><br />本文转自：<a href="http://www.cnblogs.com/magicchaiy/archive/2010/12/02/1894826.html">http://www.cnblogs.com/magicchaiy/archive/2010/12/02/1894826.html</a><br />其他链接：<a href="http://www.cppblog.com/dyj057/archive/2005/09/20/346.html">http://www.cppblog.com/dyj057/archive/2005/09/20/346.html</a></p></span><img src ="http://www.cppblog.com/wanghaiguang/aggbug/183112.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/wanghaiguang/" target="_blank">王海光</a> 2012-07-13 08:14 <a href="http://www.cppblog.com/wanghaiguang/archive/2012/07/13/183112.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++设计模式之一 工厂模式（简单工厂、工厂和抽象工厂）</title><link>http://www.cppblog.com/wanghaiguang/archive/2012/07/12/182948.html</link><dc:creator>王海光</dc:creator><author>王海光</author><pubDate>Thu, 12 Jul 2012 00:44:00 GMT</pubDate><guid>http://www.cppblog.com/wanghaiguang/archive/2012/07/12/182948.html</guid><wfw:comment>http://www.cppblog.com/wanghaiguang/comments/182948.html</wfw:comment><comments>http://www.cppblog.com/wanghaiguang/archive/2012/07/12/182948.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/wanghaiguang/comments/commentRss/182948.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/wanghaiguang/services/trackbacks/182948.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;今天开始这个系列之前，心里有些恐慌，毕竟园子里的高手关于设计模式的经典文章很多很多，特别是大侠李会军、吕震宇 老师的文章更是堪称经典。他们的文笔如行云流水，例子活泼生动，讲解深入浅出。好在他们都是用C#描述，也没有提供必要的源码下载，所以我这里用C++实 现。首先我想声明的是我的文笔绝对不如他们的好，例子也没有他们的形象，不过我打算把C+...&nbsp;&nbsp;<a href='http://www.cppblog.com/wanghaiguang/archive/2012/07/12/182948.html'>阅读全文</a><img src ="http://www.cppblog.com/wanghaiguang/aggbug/182948.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/wanghaiguang/" target="_blank">王海光</a> 2012-07-12 08:44 <a href="http://www.cppblog.com/wanghaiguang/archive/2012/07/12/182948.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Active Object 模式 </title><link>http://www.cppblog.com/wanghaiguang/archive/2012/07/11/182760.html</link><dc:creator>王海光</dc:creator><author>王海光</author><pubDate>Wed, 11 Jul 2012 00:14:00 GMT</pubDate><guid>http://www.cppblog.com/wanghaiguang/archive/2012/07/11/182760.html</guid><wfw:comment>http://www.cppblog.com/wanghaiguang/comments/182760.html</wfw:comment><comments>http://www.cppblog.com/wanghaiguang/archive/2012/07/11/182760.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/wanghaiguang/comments/commentRss/182760.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/wanghaiguang/services/trackbacks/182760.html</trackback:ping><description><![CDATA[<span class="hilite1">Active</span> <span class="hilite2">Object</span> 模式是Command模式的一种，是实现多线程控制的一项古老技术 . <br /><br />在《敏捷软件开发》这本书中描述的算法如下： <br />1、构造一个命令。（实现Command模式的一个命令） <br />2、将该命令放入<span class="hilite1">Active</span> <span class="hilite2">Object</span> Engine（也就是放入一个队列，LinkedList） <br />3、从该Engine取出一个命令，执行，若该命令没有执行过，设为执行过，然后将自己加入队列尾部，若执行过，判断该命令执行需要的事件发生没有，未发生，再将自己加入队列尾部。事件发生了，将需要执行的命令加入队列尾部。 <br /><br />
<div>Active Object模式不属于《Design Pattern》23模式。实际上，她是一种特殊的Command Queue。其特殊之处在于：</div>
<div>1. 队列的拥有者会顺序地执行队列中所有Command对象的Execute方法。（这个其实不算特殊）</div>
<div>2.Command对象在自己的Execute方法结束前，可以把一个新的command对象（实际上常常是这个command对象自己）再加到队列的尾部。</div>
<div>看出来了吗，这个队列有可能不会终止的，他可以一直执行下去。这个可以作为一个应用或者服务的主模块了，想像一下她可以作多少事情吧。</div>
<div>《ASP》指出这个模式可以用来在一个线程中处理多任务的问题！！！ ^_^ 太cool了。</div>
<div>如何处理呢？你可以把每个command对象看作是一个任务。他在Execute函数中，处理自己的任务，在任务告一段落时，记录自己的状态，然后把自己插入到队列的尾部，结束Execute方法。当队列轮完一周后，又会再次执行这个command对象的Execute方法。 ^_^ 很cool吧。</div>
<div>那么这种方法和多线程的方法相比有什么有缺点呢？</div>
<div>最大的优点是，所有的command都在同一个线程中，因此切换时，不需要进入内核模式！！超高效啊！！而且，可以有很多很多的command，数量上远远超过多线程的数量。</div>
<div>缺点嘛，是这种方法需要用户自己来实现调度，另外这其实是一种非剥夺模式的多任务，如果command处理不好，就会连累其它所有的command，因此实际上比多线程要更复杂。（嘿嘿，程序员能够怕麻烦吗？）</div>
<div>还有一点，Active Object运行于单线程，也就是说，她不能享受多处理器或多处理器核心带来的性能上的改善。</div>
<div>其实，这最后一点是非常致命的一点。也就是说，在当前intel的超线程CPU机器上，如果系统的负担并不重的时候。Active Object的效率有可能比多线程更低。</div>
<div>Anyway，这是一个非常有趣的模式。只是一般的程序员可能没有机会用到。<br /><br />本文转自：<a href="http://www.cppblog.com/tx7do/archive/2010/02/28/108617.aspx">http://www.cppblog.com/tx7do/archive/2010/02/28/108617.aspx</a></div><img src ="http://www.cppblog.com/wanghaiguang/aggbug/182760.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/wanghaiguang/" target="_blank">王海光</a> 2012-07-11 08:14 <a href="http://www.cppblog.com/wanghaiguang/archive/2012/07/11/182760.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Command 模式</title><link>http://www.cppblog.com/wanghaiguang/archive/2012/07/10/182608.html</link><dc:creator>王海光</dc:creator><author>王海光</author><pubDate>Tue, 10 Jul 2012 05:40:00 GMT</pubDate><guid>http://www.cppblog.com/wanghaiguang/archive/2012/07/10/182608.html</guid><wfw:comment>http://www.cppblog.com/wanghaiguang/comments/182608.html</wfw:comment><comments>http://www.cppblog.com/wanghaiguang/archive/2012/07/10/182608.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/wanghaiguang/comments/commentRss/182608.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/wanghaiguang/services/trackbacks/182608.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 引言提起Command模式，我想没有什么比遥控器的例子更能说明问题了，本文将通过它来一步步实现GOF的Command模式。我们先看下这个遥控器程序的需求：假如我们需要为家里的电器设计一个远程遥控器，通过这个控制器，我们可以控制电器(诸如灯、风扇、空调等)的开关。我们的控制器上有一系列的按钮，分别对应家中的某个电器，当我们在遥控器上按下&#8220;On&#8221;时，电器打开；当我们按下...&nbsp;&nbsp;<a href='http://www.cppblog.com/wanghaiguang/archive/2012/07/10/182608.html'>阅读全文</a><img src ="http://www.cppblog.com/wanghaiguang/aggbug/182608.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/wanghaiguang/" target="_blank">王海光</a> 2012-07-10 13:40 <a href="http://www.cppblog.com/wanghaiguang/archive/2012/07/10/182608.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>