<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title type="text">博客园_返回首页</title><subtitle type="text">过去30年IT（信息技术）产业经历了三个王朝：IBM创造的硬件王朝、微软创造的软件王朝和谷歌创造的互联网王朝。</subtitle><id>http://feed.cnblogs.com/blog/u/40643/rss</id><updated>2011-12-16T12:01:18Z</updated><author><name>牛司朋</name><uri>http://www.cnblogs.com/buffer/</uri></author><generator>feed.cnblogs.com</generator><link rel="alternate" type="text/html" href="http://www.cnblogs.com/buffer/"/><link rel="self" type="application/atom+xml" href="http://feed.cnblogs.com/blog/u/40643/rss"/><entry><id>http://www.cnblogs.com/buffer/archive/2011/12/16/2290623.html</id><title type="text">ubuntu网络简单设置</title><summary type="text">1、ubuntu系统修改IP地址：sudo gedit /etc/network/interfacesauto eth0iface eth0 inet staticaddress 219.218.122.168netmask 255.255.255.0gateway 219.218.122.2542、ubuntu系统修改DNS： sudo gedit /etc/resolv.confnameserver 202.194.15.123、使网络生效：sudo /etc/init.d/networking restartUbuntu8.04虚拟机更换host主机后开机无法加载网卡,提示:No suc</summary><published>2011-12-16T12:01:00Z</published><updated>2011-12-16T12:01:00Z</updated><author><name>牛司朋</name><uri>http://www.cnblogs.com/buffer/</uri></author><link rel="alternate" href="http://www.cnblogs.com/buffer/archive/2011/12/16/2290623.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/buffer/archive/2011/12/16/2290623.html"/><content type="html">&lt;p&gt;&lt;span style="font-size: 13px;"&gt;1、ubuntu系统修改IP地址：sudo gedit /etc/network/interfaces&lt;br /&gt;auto eth0&lt;br /&gt;iface eth0 inet static&lt;br /&gt;address 219.218.122.168&lt;br /&gt;netmask 255.255.255.0&lt;br /&gt;gateway 219.218.122.254&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 13px;"&gt;2、ubuntu系统修改DNS： sudo gedit /etc/resolv.conf&lt;br /&gt;nameserver 202.194.15.12&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 13px;"&gt;3、使网络生效：sudo /etc/init.d/networking restart&lt;br /&gt;Ubuntu8.04虚拟机更换host主机后开机无法加载网卡,提示:No such device&lt;br /&gt;删除缓存文件，重启后解决。&lt;br /&gt;sudo rm /etc/udev/rules.d/70-persistent-net.rules&lt;br /&gt;reboot&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 13px;"&gt;---------------------------------------------------------------------------&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 13px;"&gt;1&amp;gt; 安装SSH服务端和客户端&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 13px;"&gt;sudo apt-get install openssh-server openssh-client&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 13px;"&gt;2&amp;gt; 测试安装&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 13px;"&gt;ssh localhost测试&lt;br /&gt;3&amp;gt;SSH 远程登入 Ubuntu 机&lt;br /&gt;&lt;br /&gt;ssh username@192.168.0.1&lt;br /&gt;&lt;br /&gt;将 文件/文件夹 从远程 Ubuntu 机拷至本地(scp)&lt;br /&gt;&lt;br /&gt;scp -r username@192.168.0.1:/home/username/remotefile.txt .&lt;br /&gt;&lt;br /&gt;将 文件/文件夹 从本地拷至远程 Ubuntu 机(scp)&lt;br /&gt;&lt;br /&gt;scp -r localfile.txt username@192.168.0.1:/home/username/&lt;br /&gt;&lt;br /&gt;将 文件/文件夹 从远程 Ubuntu 机拷至本地(rsync)&lt;br /&gt;&lt;br /&gt;rsync -v -u -a --delete --rsh=ssh --stats username@192.168.0.1:/home/username/remotefile.txt .&lt;br /&gt;&lt;br /&gt;将 文件/文件夹 从本地拷至远程 Ubuntu 机(rsync)&lt;br /&gt;&lt;br /&gt;rsync -v -u -a --delete --rsh=ssh --stats localfile.txt &lt;span style="color: #108ac6;"&gt;username@192.168.0.1:/home/username/&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 13px;"&gt;&lt;span&gt;&lt;strong&gt;ubuntu防火墙 ufw 简单设置&lt;/strong&gt;&lt;br /&gt;&lt;/span&gt;ubuntu 系统默认已安装ufw.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 13px;"&gt;(以下内容引自:http://www.jmhdtv.com/post/198.html)&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 13px;"&gt;&lt;br /&gt;1.安装&lt;br /&gt;sudo apt-get install ufw&lt;br /&gt;&lt;br /&gt;2.启用&lt;br /&gt;sudo ufw enable&lt;br /&gt;sudo ufw default deny&lt;br /&gt;&lt;br /&gt;运行以上两条命令后，开启了防火墙，并在系统启动时自动开启。关闭所有外部对本机的访问，但本机访问外部正常。&lt;br /&gt;&lt;br /&gt;3.开启/禁用&lt;br /&gt;sudo ufw allow|deny [service]&lt;br /&gt;&lt;br /&gt;打开或关闭某个端口，例如：&lt;br /&gt;sudo ufw allow smtp　允许所有的外部IP访问本机的25/tcp (smtp)端口&lt;br /&gt;sudo ufw allow 22/tcp 允许所有的外部IP访问本机的22/tcp (ssh)端口&lt;br /&gt;sudo ufw allow 53 允许外部访问53端口(tcp/udp)&lt;br /&gt;sudo ufw allow from 192.168.1.100 允许此IP访问所有的本机端口&lt;br /&gt;sudo ufw allow proto udp 192.168.0.1 port 53 to 192.168.0.2 port 53&lt;br /&gt;sudo ufw deny smtp 禁止外部访问smtp服务&lt;br /&gt;sudo ufw delete allow smtp 删除上面建立的某条规则&lt;br /&gt;&lt;br /&gt;4.查看防火墙状态&lt;br /&gt;sudo ufw status&lt;br /&gt;&lt;br /&gt;一般用户，只需如下设置：&lt;br /&gt;sudo apt-get install ufw&lt;br /&gt;sudo ufw enable&lt;br /&gt;sudo ufw default deny&lt;br /&gt;&lt;br /&gt;以上三条命令已经足够安全了，如果你需要开放某些服务，再使用sudo ufw allow开启。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;开启/关闭防火墙 (默认设置是&amp;rsquo;disable&amp;rsquo;)&lt;br /&gt;sudo ufw enable|disable&lt;br /&gt;&lt;br /&gt;转换日志状态&lt;br /&gt;sudo ufw logging on|off&lt;br /&gt;&lt;br /&gt;设置默认策略 (比如 &amp;ldquo;mostly open&amp;rdquo; vs &amp;ldquo;mostly closed&amp;rdquo;)&lt;br /&gt;&lt;br /&gt;sudo ufw default allow|deny&lt;br /&gt;&lt;br /&gt;许可或者屏蔽端口 (可以在&amp;ldquo;status&amp;rdquo; 中查看到服务列表)。可以用&amp;ldquo;协议：端口&amp;rdquo;的方式指定一个存在于/etc/services中的服务名称，也可以通过包的meta-data。 &amp;lsquo;allow&amp;rsquo; 参数将把条目加入 /etc/ufw/maps ，而 &amp;lsquo;deny&amp;rsquo; 则相反。基本语法如下：&lt;br /&gt;sudo ufw allow|deny [service]&lt;br /&gt;&lt;br /&gt;显示防火墙和端口的侦听状态，参见 /var/lib/ufw/maps。括号中的数字将不会被显示出来。&lt;br /&gt;sudo ufw status&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;UFW 使用范例：&lt;br /&gt;&lt;br /&gt;允许 53 端口&lt;br /&gt;$ sudo ufw allow 53&lt;br /&gt;&lt;br /&gt;禁用 53 端口&lt;br /&gt;$ sudo ufw delete allow 53&lt;br /&gt;&lt;br /&gt;允许 80 端口&lt;br /&gt;$ sudo ufw allow 80/tcp&lt;br /&gt;&lt;br /&gt;禁用 80 端口&lt;br /&gt;$ sudo ufw delete allow 80/tcp&lt;br /&gt;&lt;br /&gt;允许 smtp 端口&lt;br /&gt;$ sudo ufw allow smtp&lt;br /&gt;&lt;br /&gt;删除 smtp 端口的许可&lt;br /&gt;$ sudo ufw delete allow smtp&lt;br /&gt;&lt;br /&gt;允许某特定 IP&lt;br /&gt;$ sudo ufw allow from 192.168.254.254&lt;br /&gt;&lt;br /&gt;删除上面的规则&lt;br /&gt;$ sudo ufw delete allow from 192.168.254.254&lt;/span&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/buffer/aggbug/2290623.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/buffer/archive/2011/12/16/2290623.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/buffer/archive/2011/09/26/2192216.html</id><title type="text">使用Memcache缓存MySQL查询</title><summary type="text">实际应用中，尤其是在大规模访问的Web项目中，Memcache作为一种优秀的缓存解决方案，被广泛使用。其灵活性和可扩展性受到了广大开发者的青睐。为了提高响应速度，使用Memcache来减少数据查询运算是一种不错的选择。关于Memcache的安装和配置，网上有很多资料，这里就不再赘述。本文以笔者在实际项目中的应用为例，来说明如何使用Memcache缓存MySQL数据，从而达到高效数据响应的目的。需求背景：网站有一个图片放映功能，页面加载时需从数据库中查询管理员所提交放映的图片信息，图片放映区共有9张图片，对应在数据库表中有9条记录。每次用户访问网站时，需查询数据库，并显示图片。当承受大规模用户同</summary><published>2011-09-26T12:13:00Z</published><updated>2011-09-26T12:13:00Z</updated><author><name>牛司朋</name><uri>http://www.cnblogs.com/buffer/</uri></author><link rel="alternate" href="http://www.cnblogs.com/buffer/archive/2011/09/26/2192216.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/buffer/archive/2011/09/26/2192216.html"/><content type="html">&lt;p&gt;&lt;span style="font-size: 10.5pt; font-family: 'Times New Roman';"&gt;实际应用中，尤其是在大规模访问的&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Web&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;项目中，&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Memcache&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;作为一种优秀的缓存解决方案，被广泛使用。其灵活性和可扩展性受到了广大开发者的青睐。为了提高响应速度，使用&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Memcache&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;来减少数据查询运算是一种不错的选择。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 10.5pt; font-family: 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;关于&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Memcache&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;的安装和配置，网上有很多资料，这里就不再赘述。本文以笔者在实际项目中的应用为例，来说明如何使用&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Memcache&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;缓存&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;MySQL&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;数据，从而达到高效数据响应的目的。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 10.5pt; font-family: 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;需求背景：网站有一个图片放映功能，页面加载时需从数据库中查询管理员所提交放映的图片信息，图片放映区共有&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;9&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;张图片，对应在数据库表中有&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;9&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;条记录。每次用户访问网站时，需查询数据库，并显示图片。当承受大规模用户同时访问时，数据库的压力可想而之。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 10.5pt; font-family: 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;为了降低数据库压力，提高查询速度，我采用了&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Memcache&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;来将图片记录信息缓存到&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Memcache&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;服务器上。这样就将数据库的查询压力分散到了各缓存服务器，提高了网站访问的整体效率&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10.5pt; font-family: 宋体;"&gt;。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 10.5pt; font-family: 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;一、&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Memcache&amp;nbsp;&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;服务器配置&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;(&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;内部集群模拟&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 10.5pt; font-family: 'Times New Roman';"&gt;view&amp;nbsp;plainprint?&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 10.5pt; font-family: 'Times New Roman';"&gt;$MEMCACHE_SERVERS[]&amp;nbsp;=&amp;nbsp;'192.168.1.78:11211';&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 10.5pt; font-family: 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;$MEMCACHE_SERVERS[]&amp;nbsp;=&amp;nbsp;'192.168.1.78:11212';&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 10.5pt; font-family: 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;$MEMCACHE_SERVERS[]&amp;nbsp;=&amp;nbsp;'192.168.1.252:11211';&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 10.5pt; font-family: 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;$MEMCACHE_SERVERS[]&amp;nbsp;=&amp;nbsp;'192.168.1.252:11212';&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 10.5pt; font-family: 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&lt;span face="宋体" style="font-family: 宋体;"&gt;如果要添加&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Memcache&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;节点，就在此处添加即可。&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 10.5pt; font-family: 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;$MEMCACHE_LIFETIME&amp;nbsp;=&amp;nbsp;6000;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;&lt;span face="宋体" style="font-family: 宋体;"&gt;缓存数据生命周期&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 10.5pt; font-family: 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;我采用了两台机器作为&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Memcache&amp;nbsp;Server&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;，每台开启两个端口提供&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Memcache&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;服务，每个服务开启服务内存为&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;1G&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;。这样，缓存空间总的有&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;4G&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 10.5pt; font-family: 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;二、&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;php&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;连接&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Memcache&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;服务器&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 10.5pt; font-family: 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;php&lt;span face="宋体" style="font-family: 宋体;"&gt;中和&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Memcache&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;的交互有两种：&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;1&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;、采用&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;php&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;下的&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;memcache&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;扩展；&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;2&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;、采用&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;libmemcache&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;组件。两者的优劣在此先不作对比。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 10.5pt; font-family: 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 10.5pt; font-family: 'Times New Roman';"&gt;view&amp;nbsp;plainprint?&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 10.5pt; font-family: 'Times New Roman';"&gt;$_SGLOBAL['memcache']&amp;nbsp;=&amp;nbsp;new&amp;nbsp;memcache;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 10.5pt; font-family: 'Times New Roman';"&gt;global&amp;nbsp;$MEMCACHE_SERVERS;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 10.5pt; font-family: 'Times New Roman';"&gt;$result&amp;nbsp;=&amp;nbsp;array();&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 10.5pt; font-family: 'Times New Roman';"&gt;foreach&amp;nbsp;($MEMCACHE_SERVERS&amp;nbsp;as&amp;nbsp;$server){&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 10.5pt; font-family: 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;$serverstr&amp;nbsp;=&amp;nbsp;explode(':',$server);&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 10.5pt; font-family: 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;$host&amp;nbsp;=&amp;nbsp;$serverstr[0];&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 10.5pt; font-family: 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;$port&amp;nbsp;=&amp;nbsp;$serverstr[1];&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 10.5pt; font-family: 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 10.5pt; font-family: 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;$_SGLOBAL['memcache']-＞addServer($host,$port);&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 10.5pt; font-family: 'Times New Roman';"&gt;}&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 10.5pt; font-family: 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;这段程序从刚刚的&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;memcache&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;服务器配置文件中读取所有的&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;server&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;列表，并创立连接。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 10.5pt; font-family: 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;三、&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;php&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;实现&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;memcache&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;和&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;mysql&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;的缓存查询&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 10.5pt; font-family: 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;实现原理其实很简单，在我的数据库操作类中新增一个函数&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;query_memcache($sql,$type)&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;，以&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;$sql&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;的&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;MD5&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;值作为&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Key&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;，从&amp;nbsp;&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Memcache&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;服务器上查询是否存在该&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;key&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;的值，如果存在，则直接返回；如果不存在，则从&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;MySQL&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;数据库中查询，并将结果写入&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Memcache&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 10.5pt; font-family: 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 10.5pt; font-family: 'Times New Roman';"&gt;view&amp;nbsp;plainprint?&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 10.5pt; font-family: 'Times New Roman';"&gt;function&amp;nbsp;query_memcache($sql,$type=''){&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 10.5pt; font-family: 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;$key&amp;nbsp;=&amp;nbsp;md5($sql);&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 10.5pt; font-family: 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 10.5pt; font-family: 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if(!($value&amp;nbsp;=&amp;nbsp;$_SGLOBAL['memcache']-＞get($key))){&amp;nbsp;//Cache&lt;span face="宋体" style="font-family: 宋体;"&gt;中没有&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;,&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;则从&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;My&amp;nbsp;SQL&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;中查询&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 10.5pt; font-family: 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;$query&amp;nbsp;=&amp;nbsp;$this-＞query($sql,$type);&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 10.5pt; font-family: 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;while($item&amp;nbsp;=&amp;nbsp;$this-＞fetch_array($query)){&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 10.5pt; font-family: 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;$result[]&amp;nbsp;=&amp;nbsp;$item;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 10.5pt; font-family: 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 10.5pt; font-family: 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;$value&amp;nbsp;=&amp;nbsp;$result;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 10.5pt; font-family: 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 10.5pt; font-family: 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&lt;span face="宋体" style="font-family: 宋体;"&gt;将&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Key&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;和&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Value&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;写入&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;MemCache&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 10.5pt; font-family: 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;$_SGLOBAL['memcache']-＞set($key,$result,0,$MEMCACHE_LIFETIME);&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 10.5pt; font-family: 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 10.5pt; font-family: 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;$value;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 10.5pt; font-family: 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 10.5pt; font-family: 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;在页面加载的过程中，将图片检索的数据库查询调用改成用&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;query_memcache()&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;函数即可。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 10.5pt; font-family: 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;到此，我们就实现了用&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Memcache&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;缓存首页数据信息，经测试，在大规模的并发访问下，首页加载速度快了许多。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 10.5pt; font-family: 'Times New Roman';"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/buffer/aggbug/2192216.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/buffer/archive/2011/09/26/2192216.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/buffer/archive/2011/09/25/2190201.html</id><title type="text">结构算法之道</title><summary type="text">http://blog.csdn.net/v_july_v/article/details/6543438</summary><published>2011-09-25T05:04:00Z</published><updated>2011-09-25T05:04:00Z</updated><author><name>牛司朋</name><uri>http://www.cnblogs.com/buffer/</uri></author><link rel="alternate" href="http://www.cnblogs.com/buffer/archive/2011/09/25/2190201.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/buffer/archive/2011/09/25/2190201.html"/><content type="html">&lt;p&gt;http://blog.csdn.net/v_july_v/article/details/6543438&lt;/p&gt;&lt;img src="http://www.cnblogs.com/buffer/aggbug/2190201.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/buffer/archive/2011/09/25/2190201.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/buffer/archive/2011/09/21/2184484.html</id><title type="text">两个数据表同步的触发器</title><summary type="text">假如有两个表，TableName1和TableName2，两个表字段相同，都是有一个fID(TableName1表为标识，自动＋1，TableName2表设置为普通字段)，和一个varchar类型的content两个字段。现在要实现TableName2作为TableName1的备份，对TableName1的所有修改（增、删、改）都要对TableName2同时生效。可以使用以下触发器CREATE TRIGGER TableName1_SNY_TO_TableName2 ON TableName1FOR INSERT, UPDATE, DELETEAS delete TableName2 whe.</summary><published>2011-09-21T13:48:00Z</published><updated>2011-09-21T13:48:00Z</updated><author><name>牛司朋</name><uri>http://www.cnblogs.com/buffer/</uri></author><link rel="alternate" href="http://www.cnblogs.com/buffer/archive/2011/09/21/2184484.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/buffer/archive/2011/09/21/2184484.html"/><content type="html">&lt;div&gt;&lt;p&gt;&lt;span class="Apple-style-span" style="font-family: verdana; line-height: 18px;"&gt;假如有两个表，TableName1和TableName2，&lt;br /&gt;&lt;br /&gt;两个表字段相同，都是有一个fID(TableName1表为标识，自动＋1，TableName2表设置为普通字段)，&lt;br /&gt;&lt;br /&gt;和一个varchar类型的content两个字段。&lt;br /&gt;&lt;br /&gt;现在要实现TableName2作为TableName1的备份，对TableName1的所有修改（增、删、改）都要对TableName2同时生效。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;可以使用以下触发器&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;CREATE TRIGGER TableName1_SNY_TO_TableName2 ON TableName1&lt;br /&gt;&lt;br /&gt;FOR INSERT, UPDATE, DELETE&amp;nbsp;&lt;br /&gt;&lt;br /&gt;AS&amp;nbsp; &amp;nbsp;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; delete TableName2 where fID in (select fID from deleted)&amp;nbsp; &amp;nbsp;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; insert TableName2 select * from inserted &amp;nbsp;&lt;br /&gt;&lt;br /&gt;GO&lt;br /&gt;&lt;br /&gt;即可保证同步两个表的内容。&lt;/span&gt;&lt;/p&gt;&lt;div class="ggad" style="text-align: center; margin-left: auto; margin-right: auto; margin-top: 10px; height: 90px; overflow-x: hidden; overflow-y: hidden;"&gt;&lt;/div&gt;&lt;div id="hidden_content" style="margin-top: -20px;"&gt;&lt;p&gt;&lt;span class="Apple-style-span" style="line-height: 18px;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;div class="blog_title" style="margin-bottom: 15px;"&gt;&lt;strong style="font-weight: bold;"&gt;关键字: 如何自增字段中插入指定值&lt;/strong&gt;&lt;/div&gt;&lt;div class="blog_content"&gt;sqlserver 批量插入记录时,对有标识列的字段要设置 set IDENTITY_INSERT 表名 on,然后再执行插入记录操作;插入完毕后恢复为 off 设置&amp;nbsp;&lt;br /&gt;&lt;br /&gt;格式:&amp;nbsp;&lt;br /&gt;&lt;span style="color: red;"&gt;&amp;nbsp; set IDENTITY_INSERT 表名 on&amp;nbsp;&lt;br /&gt;&amp;nbsp; set IDENTITY_INSERT 表名 off&lt;/span&gt;&amp;nbsp;&lt;br /&gt;&lt;br /&gt;举例:&amp;nbsp;&lt;br /&gt;&lt;br /&gt;set IDENTITY_INSERT peoplePworkpositiontype&amp;nbsp; on&amp;nbsp;&lt;br /&gt;insert peoplePworkpositiontype(id,workpositiontype,workpositiontypeid) values(1 , '平台' , 1 )&amp;nbsp;&lt;br /&gt;insert peoplePworkpositiontype(id,workpositiontype,workpositiontypeid) values(2 , '陆地' , 2 )&amp;nbsp;&lt;br /&gt;insert peoplePworkpositiontype(id,workpositiontype,workpositiontypeid) values(3 , '海上' , 3 )&amp;nbsp;&lt;br /&gt;&lt;br /&gt;go&amp;nbsp;&lt;br /&gt;set IDENTITY_INSERT peoplePworkpositiontype&amp;nbsp; off&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;set IDENTITY_INSERT peoplePstatetype&amp;nbsp; on&amp;nbsp;&lt;br /&gt;insert peoplePstatetype(id,nowstatetype,nowstatetypeid) values(1 , '出海' , 1 )&amp;nbsp;&lt;br /&gt;insert peoplePstatetype(id,nowstatetype,nowstatetypeid) values(2 , '出差' , 2 )&amp;nbsp;&lt;br /&gt;insert peoplePstatetype(id,nowstatetype,nowstatetypeid) values(3 , '公司' , 3 )&amp;nbsp;&lt;br /&gt;insert peoplePstatetype(id,nowstatetype,nowstatetypeid) values(4 , '会议' , 4 )&amp;nbsp;&lt;br /&gt;go&amp;nbsp;&lt;br /&gt;set IDENTITY_INSERT peoplePstatetype&amp;nbsp; off&amp;nbsp;&lt;/div&gt;&lt;span class="Apple-style-span" style="line-height: 18px;"&gt;go&amp;nbsp;&lt;/span&gt;&amp;nbsp;&lt;p&gt;&lt;/p&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;img src="http://www.cnblogs.com/buffer/aggbug/2184484.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/buffer/archive/2011/09/21/2184484.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/buffer/archive/2011/09/21/2184028.html</id><title type="text">Linux Shell编程入门</title><summary type="text">从程序员的角度来看， Shell本身是一种用C语言编写的程序，从用户的角度来看，Shell是用户与Linux操作系统沟通的桥梁。用户既可以输入命令执行，又可以利用 Shell脚本编程，完成更加复杂的操作。在Linux GUI日益完善的今天，在系统管理等领域，Shell编程仍然起着不可忽视的作用。深入地了解和熟练地掌握Shell编程，是每一个Linux用户的必修 功课之一。Linux的Shell种类众多，常见的有：Bourne Shell（/usr/bin/sh或/bin/sh）、Bourne Again Shell（/bin/bash）、C Shell（/usr/bin/csh）、K Shel</summary><published>2011-09-21T07:05:00Z</published><updated>2011-09-21T07:05:00Z</updated><author><name>牛司朋</name><uri>http://www.cnblogs.com/buffer/</uri></author><link rel="alternate" href="http://www.cnblogs.com/buffer/archive/2011/09/21/2184028.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/buffer/archive/2011/09/21/2184028.html"/><content type="html">&lt;p&gt;从程序员的角度来看， Shell本身是一种用C语言编写的程序，从用户的角度来看，Shell是用户与Linux操作系统沟通的桥梁。用户既可以输入命令执行，又可以利用 Shell脚本编程，完成更加复杂的操作。在Linux GUI日益完善的今天，在系统管理等领域，Shell编程仍然起着不可忽视的作用。深入地了解和熟练地掌握Shell编程，是每一个Linux用户的必修 功课之一。&lt;/p&gt;&lt;p&gt;Linux的Shell种类众多，常见的有：Bourne Shell（/usr/bin/sh或/bin/sh）、Bourne Again Shell（/bin/bash）、C Shell（/usr/bin/csh）、K Shell（/usr/bin/ksh）、Shell for Root（/sbin/sh），等等。不同的Shell语言的语法有所不同，所以不能交换使用。每种Shell都有其特色之处，基本上，掌握其中任何一种 就足够了。在本文中，我们关注的重点是Bash，也就是Bourne Again Shell，由于易用和免费，Bash在日常工作中被广泛使用；同时，Bash也是大多数Linux系统默认的Shell。在一般情况下，人们并不区分 Bourne Shell和Bourne Again Shell，所以，在下面的文字中，我们可以看到#!/bin/sh，它同样也可以改为#!/bin/bash。&lt;/p&gt;&lt;p&gt;利用vi等文本编辑器编写Shell脚本的格式是固定的，如下：&lt;/p&gt;&lt;p&gt;#!/bin/sh&lt;/p&gt;&lt;p&gt;#comments&lt;/p&gt;&lt;p&gt;Your commands go here&lt;/p&gt;&lt;p&gt;首行中的符号#!告诉系统其后路径所指定的程序即是解释此脚本文件的Shell程 序。如果首行没有这句话，在执行脚本文件的时候，将会出现错误。后续的部分就是主程序，Shell脚本像高级语言一样，也有变量赋值，也有控制语句。除第 一行外，以#开头的行就是注释行，直到此行的结束。如果一行未完成，可以在行尾加上"，这个符号表明下一行与此行会合并为同一行。&lt;/p&gt;&lt;p&gt;编辑完毕，将脚本存盘为filename.sh，文件名后缀sh表明这是一个Bash脚本文件。执行脚本的时候，要先将脚本文件的属性改为可执行的：&lt;/p&gt;&lt;p&gt;chmod +x filename.sh&lt;/p&gt;&lt;p&gt;执行脚本的方法是：&lt;/p&gt;&lt;p&gt;./filename.sh&lt;/p&gt;&lt;p&gt;下面我们从经典的&amp;ldquo;hello world&amp;rdquo;入手，看一看最简单的Shell脚本的模样。&lt;/p&gt;&lt;p&gt;#!/bin/sh&lt;/p&gt;&lt;p&gt;#print hello world in the console window&lt;/p&gt;&lt;p&gt;a = "hello world"&lt;/p&gt;&lt;p&gt;echo $a&lt;/p&gt;&lt;p&gt;Shell Script是一种弱类型语言，使用变量的时候无需首先声明其类型。新的变量会在本地数据区分配内存进行存储，这个变量归当前的Shell所有，任何子进 程都不能访问本地变量。这些变量与环境变量不同，环境变量被存储在另一内存区，叫做用户环境区，这块内存中的变量可以被子进程访问。变量赋值的方式是：&lt;/p&gt;&lt;p&gt;variable_name = variable_value&lt;/p&gt;&lt;p&gt;如果对一个已经有值的变量赋值，新值将取代旧值。取值的时候要在变量名前加$，$variable_name可以在引号中使用，这一点和其他高级语言是明显不同的。如果出现混淆的情况，可以使用花括号来区分，例如：&lt;/p&gt;&lt;p&gt;echo "Hi, $as"&lt;/p&gt;&lt;p&gt;就不会输出&amp;ldquo;Hi, hello worlds&amp;rdquo;，而是输出&amp;ldquo;Hi，&amp;rdquo;。这是因为Shell把$as当成一个变量，而$as未被赋值，其值为空。正确的方法是：&lt;/p&gt;&lt;p&gt;echo "Hi, ${a}s"&lt;/p&gt;&lt;p&gt;单引号中的变量不会进行变量替换操作。&amp;nbsp;&lt;/p&gt;&lt;p&gt;关于变量，还需要知道几个与其相关的Linux命令。&lt;/p&gt;&lt;p&gt;env用于显示用户环境区中的变量及其取值；set用于显示本地数据区和用户环境区中的变量及其取值；unset用于删除指定变量当前的取值，该值将被指定为NULL；export命令用于将本地数据区中的变量转移到用户环境区。&lt;/p&gt;&lt;p&gt;下面我们来看一个更复杂的例子，结合这个例子，我们来讲述Shell Script的语法。&amp;nbsp;&lt;/p&gt;&lt;div style="padding-top: 4px; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; background-color: #eeeeee; font-size: 13px; width: 990px; border-width: 1px; border-color: #cccccc; border-style: solid;"&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;1&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;#&lt;/span&gt;&lt;span style="color: #000000;"&gt;!&lt;/span&gt;&lt;span style="color: #000000;"&gt;/&lt;/span&gt;&lt;span style="color: #000000;"&gt;bin&lt;/span&gt;&lt;span style="color: #000000;"&gt;/&lt;/span&gt;&lt;span style="color: #000000;"&gt;bash&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;2&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;#&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;we&amp;nbsp;have&amp;nbsp;less&amp;nbsp;than&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;3&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;arguments&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;Print&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;the&amp;nbsp;help&amp;nbsp;text:&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;3&lt;/span&gt;&amp;nbsp;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;[&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;$#&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;-lt&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;3&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;]&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;then&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;4&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;cat&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;HELP&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;5&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;ren&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;--&amp;nbsp;renames&amp;nbsp;a&amp;nbsp;number&amp;nbsp;of&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;files&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;using&amp;nbsp;sed&amp;nbsp;regular&amp;nbsp;expressions&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;6&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;7&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;USAGE:&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;ren&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;'regexp'&amp;nbsp;'replacement'&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;files&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;img src="http://www.cnblogs.com/Images/dot.gif" alt="" style="border-style: initial; border-color: initial; border-width: 0px;" /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;8&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;EXAMPLE:&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;rename&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;all&amp;nbsp;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;HTM&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;files&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;in&amp;nbsp;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;html:&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;9&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;ren&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;'HTM&lt;/span&gt;&lt;span style="color: #000000;"&gt;$&lt;/span&gt;&lt;span style="color: #000000;"&gt;'&amp;nbsp;'html'&amp;nbsp;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;HTM&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;11&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;HELP&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;12&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;exit&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;13&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;fi&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;14&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;OLD&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;$1&lt;/span&gt;&lt;span style="color: #000000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;15&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;NEW&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;$2&lt;/span&gt;&lt;span style="color: #000000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;16&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;#&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;The&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;shift&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;command&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;removes&amp;nbsp;one&amp;nbsp;argument&amp;nbsp;from&amp;nbsp;the&amp;nbsp;list&amp;nbsp;of&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;17&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;#&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;command&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;line&amp;nbsp;arguments&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;18&lt;/span&gt;&amp;nbsp;&lt;span style="color: #0000ff;"&gt;shift&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;19&lt;/span&gt;&amp;nbsp;&lt;span style="color: #0000ff;"&gt;shift&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;20&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;#&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;$&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&amp;nbsp;contains&amp;nbsp;now&amp;nbsp;all&amp;nbsp;the&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;files&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;21&lt;/span&gt;&amp;nbsp;&lt;span style="color: #0000ff;"&gt;for&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;file&amp;nbsp;in&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;$&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;do&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;22&lt;/span&gt;&amp;nbsp;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;[&amp;nbsp;-f&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;$file&lt;/span&gt;&lt;span style="color: #000000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;]&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;then&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;23&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;newfile&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;`&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;echo&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;$file&lt;/span&gt;&lt;span style="color: #000000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;|&amp;nbsp;sed&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;s/${OLD}/${NEW}/g&lt;/span&gt;&lt;span style="color: #000000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;`&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;24&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;[&amp;nbsp;-f&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;$newfile&lt;/span&gt;&lt;span style="color: #000000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;]&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;then&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;25&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;echo&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;ERROR:&amp;nbsp;$newfile&amp;nbsp;exists&amp;nbsp;already&lt;/span&gt;&lt;span style="color: #000000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;26&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;else&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;27&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;echo&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;renaming&amp;nbsp;$file&amp;nbsp;to&amp;nbsp;$newfile&amp;nbsp;&lt;img src="http://www.cnblogs.com/Images/dot.gif" alt="" style="border-style: initial; border-color: initial; border-width: 0px;" /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;28&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;mv&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;$file&lt;/span&gt;&lt;span style="color: #000000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;$newfile&lt;/span&gt;&lt;span style="color: #000000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;29&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fi&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;30&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;fi&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;31&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;done&lt;/span&gt;&lt;/div&gt;&lt;p&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px; font-size: 12px;"&gt;&lt;br /&gt;&lt;span class="a14c"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;我们从头来看，前面两行上一个例子中已经解释过了，从第三行开始，有新的内容。if语句和其他编程语言相似，都是流程控制语句。它的语法是：&lt;/p&gt;&lt;p&gt;if &amp;hellip;; then&lt;/p&gt;&lt;p&gt;&amp;hellip;&lt;/p&gt;&lt;p&gt;elif &amp;hellip;; then&lt;/p&gt;&lt;p&gt;&amp;hellip;&lt;/p&gt;&lt;p&gt;else&lt;/p&gt;&lt;p&gt;&amp;hellip;&lt;/p&gt;&lt;p&gt;fi&lt;/p&gt;&lt;p&gt;与其他语言不同，Shell Script中if语句的条件部分要以分号来分隔。第三行中的[]表示条件测试，常用的条件测试有下面几种：&lt;/p&gt;&lt;p&gt;[ -f "$file" ] 判断$file是否是一个文件&lt;/p&gt;&lt;p&gt;[ $a -lt 3 ] 判断$a的值是否小于3，同样-gt和-le分别表示大于或小于等于&lt;/p&gt;&lt;p&gt;[ -x "$file" ] 判断$file是否存在且有可执行权限，同样-r测试文件可读性&lt;/p&gt;&lt;p&gt;[ -n "$a" ] 判断变量$a是否有值，测试空串用-z&lt;/p&gt;&lt;p&gt;[ "$a" = "$b" ] 判断$a和$b的取值是否相等&lt;/p&gt;&lt;p&gt;[ cond1 -a cond2 ] 判断cond1和cond2是否同时成立，-o表示cond1和cond2有一成立&lt;/p&gt;&lt;p&gt;要注意条件测试部分中的空格。在方括号的两侧都有空格，在-f、-lt、=等符号两侧同样也有空格。如果没有这些空格，Shell解释脚本的时候就会出错。&lt;/p&gt;&lt;p&gt;$#表示包括$0在内的命令行参数的个数。在Shell中，脚本名称本身是$0，剩下的依次是$0、$1、$2&amp;hellip;、${10}、${11}，等等。$*表示整个参数列表，不包括$0，也就是说不包括文件名的参数列表。&lt;/p&gt;&lt;p&gt;现在我们明白第三行的含义是如果脚本文件的参数少于三个，则执行if和fi语句之间 的内容。然后，从第四行到第十一行之间的内容在Shell Script编程中被称为Here文档，Here文档用于将多行文本传递给某一命令。Here文档的格式是以&amp;lt;&amp;lt;开始，后跟一个字符串，在 Here文档结束的时候，这个字符串同样也要出现，表示文档结束。在本例中，Here文档被输出给cat命令，也即将文档内容打印在屏幕上，起到显示帮助 信息的作用。&lt;/p&gt;&lt;p&gt;第十二行的exit是Linux的命令，表示退出当前进程。在Shell脚本中可以使用所有的Linux命令，利用上面的cat和exit，从一方面来说，熟练使用Linux命令也可以大大减少Shell脚本的长度。&lt;/p&gt;&lt;p&gt;十四、十五两句是赋值语句，分别将第一和第二参数赋值给变量OLD和NEW。紧接下来的两句是注释，注释下面的两条shift的作用是将参数列表中的第一个和第二个参数删除，后面的参数依次变为新的第一和第二参数，注意参数列表原本也不包括$0。&lt;/p&gt;&lt;p&gt;然后，自二十一行到三十一行是一个循环语句。Shell Script中的循环有下面几种格式：&lt;/p&gt;&lt;p&gt;while [ cond1 ] &amp;amp;&amp;amp; { || } [ cond2 ] &amp;hellip;; do&lt;/p&gt;&lt;p&gt;&amp;hellip;&lt;/p&gt;&lt;p&gt;done&lt;/p&gt;&lt;p&gt;for var in &amp;hellip;; do&lt;/p&gt;&lt;p&gt;&amp;hellip;&lt;/p&gt;&lt;p&gt;done&lt;/p&gt;&lt;p&gt;for (( cond1; cond2; cond3 )) do&lt;/p&gt;&lt;p&gt;&amp;hellip;&lt;/p&gt;&lt;p&gt;done&lt;/p&gt;&lt;p&gt;until [ cond1 ] &amp;amp;&amp;amp; { || } [ cond2 ] &amp;hellip;; do&lt;/p&gt;&lt;p&gt;&amp;hellip;&lt;/p&gt;&lt;p&gt;done&lt;/p&gt;&lt;p&gt;在上面这些循环中，也可以使用类似C语言中的break和continue语句中断 当前的循环操作。第二十一行的循环是将参数列表中的参数一个一个地放入变量file中。然后进入循环，判断file是否为一个文件，如果是文件的话，则用 sed命令搜索和生成新的文件名。sed基本上可以看成一个查找替换程序，从标准输入，例如管道读入文本，并将结果输出到标准输出，sed使用正则表达式 进行搜索。在第二十三行中，backtick（`）的作用是取出两个backtick之间的命令输出结果，在这里，也就是将结果取出赋给变量 newfile。此后，判断newfile是否已经存在，否则就把file改成newfile。这样我们就明白这个脚本的作用了，Shell Script编写的其他脚本与此相似，只不过是语法和用法稍有不同而已。&lt;/p&gt;&lt;p&gt;通过这个例子我们明白了Shell Script的编写规则，但还有几件事情需要讲述一下。&lt;/p&gt;&lt;p&gt;第一个，除了if语句之外，Shell Script中也有类似C语言中多分支结构的case语句，它的语法是：&lt;/p&gt;&lt;p&gt;case var in&lt;/p&gt;&lt;p&gt;pattern 1 )&lt;/p&gt;&lt;p&gt;&amp;hellip; ;;&lt;/p&gt;&lt;p&gt;pattern 2 )&lt;/p&gt;&lt;p&gt;&amp;hellip; ;;&lt;/p&gt;&lt;p&gt;*)&lt;/p&gt;&lt;p&gt;&amp;hellip; ;;&lt;/p&gt;&lt;p&gt;esac&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px; font-size: 12px;"&gt;&lt;span id="zoom" class="a14c"&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;我们再就下面一个例子，看看case语句的用法。&lt;/p&gt;&lt;p&gt;while getopts vc: OPTION&lt;/p&gt;&lt;p&gt;do&lt;/p&gt;&lt;p&gt;case $OPTION in&lt;/p&gt;&lt;p&gt;c) COPIES=$OPTARG&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ehco "$COPIES";;&lt;/p&gt;&lt;p&gt;v) echo "suyang";;&lt;/p&gt;&lt;p&gt;\?) exit 1;;&lt;/p&gt;&lt;p&gt;esac&lt;/p&gt;&lt;p&gt;done&lt;/p&gt;&lt;p&gt;上面的getopts类似于C语言提供的函数getopts，在Shell Script中，getopts经常和while语句联合起来使用。getopts的语法如下：&lt;/p&gt;&lt;p&gt;getopts option_string variable&lt;/p&gt;&lt;p&gt;option_string中包含一串单字符选项，若getopts在命令行参数中 发现了连字符，那么它会将连字符之后的字符与option_string进行比较，若匹配成功，则把变量variable的值设为该选项，若无匹配，则把 变量的值设为？。有时候，选项还会带一个值，例如-c5等，这时要在option_string中该选项字母后面加上一个冒号，getopts发现冒号 后，会读取该值，然后将该值放入特殊变量OPTARG中。这个命令比较复杂，如有需要，读者可以详细参阅Shell编写的相关资料。&lt;/p&gt;&lt;p&gt;上面这个循环的作用就是依次取出脚本名称后面的选项，进行处理，如果输入了非法选项，则进入"?指定的部分，退出脚本程序。&lt;/p&gt;&lt;p&gt;第二个，Bash提供了一种用于交互式应用的扩展select，用户可以从一组不同的值中进行选择。其语法如下：&lt;/p&gt;&lt;p&gt;select var in &amp;hellip;; do&lt;/p&gt;&lt;p&gt;break;&lt;/p&gt;&lt;p&gt;done&lt;/p&gt;&lt;p&gt;例如，下面这段程序的输出是：&lt;/p&gt;&lt;p&gt;#!/bin/bash&lt;/p&gt;&lt;p&gt;echo "Your choice?"&lt;/p&gt;&lt;p&gt;select var in "a" "b" "c"; do&lt;/p&gt;&lt;p&gt;break&lt;/p&gt;&lt;p&gt;done&lt;/p&gt;&lt;p&gt;echo $var&lt;/p&gt;&lt;p&gt;----------------------------&lt;/p&gt;&lt;p&gt;Your choice?&lt;/p&gt;&lt;p&gt;1) a&lt;/p&gt;&lt;p&gt;2) b&lt;/p&gt;&lt;p&gt;3) c&lt;/p&gt;&lt;p&gt;第三，Shell Script中也可以使用自定义的函数，其语法形式如下：&lt;/p&gt;&lt;p&gt;functionname()&lt;/p&gt;&lt;p&gt;{&lt;/p&gt;&lt;p&gt;&amp;hellip;&lt;/p&gt;&lt;p&gt;}&lt;/p&gt;&lt;p&gt;例如我们可以把上面第二个例子中第四到第十二行放入一个名为help函数体内，以后每次调用的时候直接写help即可。函数中处理函数调用参数的方法是，直接用上面讲过的$1、$2来分别表示第一、第二个参数，用$*表示参数列表。&lt;/p&gt;&lt;p&gt;第四，我们也可以在Shell下调试Shell Script脚本，当然最简单的方法就是用echo输出查看变量取值了。Bash也提供了真正的调试方法，就是执行脚本的时候用-x参数。&lt;/p&gt;&lt;p&gt;sh ?x filename.sh&lt;/p&gt;&lt;p&gt;这会执行脚本并显示脚本中所有变量的取值，也可以使用参数-n，它并不执行脚本，只是返回所有的语法错误。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/buffer/aggbug/2184028.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/buffer/archive/2011/09/21/2184028.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/buffer/archive/2011/09/19/2181730.html</id><title type="text">二叉树的深度优先遍历、广度优先遍历和非递归遍历</title><summary type="text">二叉树的遍历：D：访问根结点，L：遍历根结点的左子树，R：遍历根结点的右子树。给定一棵二叉树的前序遍历序列和中序遍历序列可以惟一确定一棵二叉树。二叉树的深度优先遍历的非递归的通用做法是采用栈，广度优先遍历的非递归的通用做法是采用队列。深度优先遍历二叉树。1. 中序遍历（LDR）的递归算法：若二叉树为空，则算法结束；否则： 中序遍历根结点的左子树； 访问根结点； 中序遍历根结点的右子树。2. 前序遍历（DLR）的递归算法：若二叉树为空，则算法结束，否则： 访问根结点； 前序遍历根结点的左子树； 前序遍历根结点的右子树。3. 后序遍历（LRD）的递归算法：若二叉树为空，则算法结束，否则： 后序遍历</summary><published>2011-09-19T12:13:00Z</published><updated>2011-09-19T12:13:00Z</updated><author><name>牛司朋</name><uri>http://www.cnblogs.com/buffer/</uri></author><link rel="alternate" href="http://www.cnblogs.com/buffer/archive/2011/09/19/2181730.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/buffer/archive/2011/09/19/2181730.html"/><content type="html">&lt;p&gt;二叉树的遍历：&lt;/p&gt;&lt;p&gt;D：访问根结点，L：遍历根结点的左子树，R：遍历根结点的右子树。&lt;/p&gt;&lt;p&gt;给定一棵二叉树的前序遍历序列和中序遍历序列可以惟一确定一棵二叉树。&lt;/p&gt;&lt;p&gt;二叉树的深度优先遍历的非递归的通用做法是采用栈，广度优先遍历的非递归的通用做法是采用队列。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;span style="text-decoration: underline;"&gt;深度优先遍历二叉树。&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;1. 中序遍历（LDR）的递归算法：&lt;/p&gt;&lt;p&gt;若二叉树为空，则算法结束；否则：&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 中序遍历根结点的左子树；&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 访问根结点；&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 中序遍历根结点的右子树。&lt;/p&gt;&lt;p&gt;2. 前序遍历（DLR）的递归算法：&lt;/p&gt;&lt;p&gt;若二叉树为空，则算法结束，否则：&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 访问根结点；&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 前序遍历根结点的左子树；&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 前序遍历根结点的右子树。&lt;/p&gt;&lt;p&gt;3. 后序遍历（LRD）的递归算法：&lt;/p&gt;&lt;p&gt;若二叉树为空，则算法结束，否则：&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 后序遍历根结点的左子树；&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 后序遍历根结点的右子树；&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 访问根结点。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;span style="text-decoration: underline;"&gt;广度优先遍历二叉树。&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;广度优先周游二叉树(层序遍历)是用队列来实现的，从二叉树的第一层（根结点）开始，自上至下逐层遍历；在同一层中，按照从左到右的顺序对结点逐一访问。&lt;/p&gt;&lt;p&gt;按照从根结点至叶结点、从左子树至右子树的次序访问二叉树的结点。算法：&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1初始化一个队列，并把根结点入列队；&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 2当队列为非空时，循环执行步骤3到步骤5，否则执行6；&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3出队列取得一个结点，访问该结点；&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 4若该结点的左子树为非空，则将该结点的左子树入队列；&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 5若该结点的右子树为非空，则将该结点的右子树入队列；&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 6结束。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;span style="text-decoration: underline;"&gt;非递归深度优先遍历二叉树。&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;栈是实现递归的最常用的结构，利用一个栈来记下尚待遍历的结点或子树，以备以后访问，可以将递归的深度优先遍历改为非递归的算法。&lt;/p&gt;&lt;p&gt;1. 非递归前序遍历：遇到一个结点，就访问该结点，并把此结点推入栈中，然后下降去遍历它的左子树。遍历完它的左子树后，从栈顶托出这个结点，并按照它的右链接指示的地址再去遍历该结点的右子树结构。&lt;/p&gt;&lt;p&gt;2. 非递归中序遍历：遇到一个结点，就把它推入栈中，并去遍历它的左子树。遍历完左子树后，从栈顶托出这个结点并访问之，然后按照它的右链接指示的地址再去遍历该结点的右子树。&lt;/p&gt;&lt;p&gt;3. 非递归后序遍历：遇到一个结点，把它推入栈中，遍历它的左子树。遍历结束后，还不能马上访问处于栈顶的该结点，而是要再按照它的右链接结构指示的地址去遍历该结点的右子树。遍历遍右子树后才能从栈顶托出该结点并访问之。另外，需要给栈中的每个元素加上一个特征位，以便当从栈顶托出一个结点时区别是从栈顶元素左边回来的(则要继续遍历右子树)，还是从右边回来的(该结点的左、右子树均已周游)。特征为Left表示已进入该结点的左子树，将从左边回来；特征为Right表示已进入该结点的右子树，将从右边回来。&lt;/p&gt;&lt;p&gt;4. 简洁的非递归前序遍历：遇到一个结点，就访问该结点，并把此结点的非空右结点推入栈中，然后下降去遍历它的左子树。遍历完左子树后，从栈顶托出一个结点，并按照它的右链接指示的地址再去遍历该结点的右子树结构。&lt;/p&gt;&lt;p&gt;----------------------------------------------------------------------&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 图的深度优先搜索法是树的先根遍历的推广，它的基本思想是：从图G的某个顶点v0出发，访问v0，然后选择一个与v0相邻且没被访问过的顶点vi访问，再从vi出发选择一个与vi相邻且未被访问的顶点vj进行访问，依次继续。如果当前被访问过的顶点的所有邻接顶点都已被访问，则退回到已被访问的顶点序列中最后一个拥有未被访问的相邻顶点的顶点w，从w出发按同样的方法向前遍历，直到图中所有顶点都被访问。&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 图的广度优先搜索是树的按层次遍历的推广，它的基本思想是：首先访问初始点vi，并将其标记为已访问过，接着访问vi的所有未被访问过的邻接点vi1,vi2, &amp;hellip;, vi t，并均标记已访问过，然后再按照vi1,vi2, &amp;hellip;, vi t的次序，访问每一个顶点的所有未被访问过的邻接点，并均标记为已访问过，依次类推，直到图中所有和初始点vi有路径相通的顶点都被访问过为止。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/buffer/aggbug/2181730.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/buffer/archive/2011/09/19/2181730.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/buffer/archive/2011/09/06/2169292.html</id><title type="text">服务器高性能程序 磁盘I/O篇</title><summary type="text">服务器高性能程序 磁盘I/O篇Linux IO系统的架构图一．设备--------影响磁盘性能的因素硬盘的转速影响硬盘的整体性能。一般情况下转速越大，性能会越好。硬盘的性能因素主要包括两个：1.平均访问时间2传输速率。平均访问时间包括两方面因素：平均寻道时间(Average Seek Time)是指硬盘的磁头移动到盘面指定磁道所需的时间。一般在3ms至15ms之间。平均旋转等待时间(Latency)是指磁头已处于要访问的磁道，等待所要访问的扇区旋转至磁头下方的时间。一般在2ms至6ms之间。传输速率(Data Transfer Rate)硬盘的数据传输率是指硬盘读写数据的速度，单位为兆字节每秒</summary><published>2011-09-06T15:11:00Z</published><updated>2011-09-06T15:11:00Z</updated><author><name>牛司朋</name><uri>http://www.cnblogs.com/buffer/</uri></author><link rel="alternate" href="http://www.cnblogs.com/buffer/archive/2011/09/06/2169292.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/buffer/archive/2011/09/06/2169292.html"/><content type="html">&lt;div class="postTitle" style="font-size: 14.7px; font-weight: bold; margin-bottom: 10px;"&gt;&lt;a id="viewpost1_TitleUrl" class="postTitle2" href="http://www.cppblog.com/range/archive/2011/08/26/154449.html" style="text-decoration: none; color: black;"&gt;服务器高性能程序 磁盘I/O篇&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;p&gt;Linux IO&lt;span style="font-family: 宋体;"&gt;系统的架构图&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;img src="http://www.cppblog.com/images/cppblog_com/range/21.jpg" width="326" height="433" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span&gt;一．&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;设备&lt;/span&gt;--------&amp;nbsp;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;影响磁盘性能的因素&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 宋体;"&gt;硬盘的转速影响硬盘的整体性能。一般情况下转速越大，性能会越好。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 宋体;"&gt;硬盘的性能因素主要包括两个：1.&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;平均访问时间2&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;传输速率。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 宋体;"&gt;平均访问时间包括两方面因素：&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 宋体;"&gt;平均寻道时间&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span style="font-family: Arial, sans-serif; color: black;"&gt;(Average Seek Time)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span style="font-family: 宋体; color: black;"&gt;是指硬盘的磁头移动到盘面指定磁道所需的时间&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。一般在3ms&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;至15ms&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;之间。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 宋体;"&gt;平均旋转等待时间&lt;/span&gt;&lt;span&gt;&lt;span style="font-family: Arial, sans-serif; color: black;"&gt;(Latency)&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="font-family: 宋体; color: black;"&gt;是指磁头已处于要访问的磁道，等待所要访问的扇区旋转至磁头下方的时间。&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;一般在2ms&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;至6ms&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;之间。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 宋体;"&gt;传输速率(Data Transfer Rate)&amp;nbsp;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;硬盘的数据传输率是指硬盘读写数据的速度，单位为兆字节每秒（MB/s&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;）。磁盘每秒能传输80M~320M&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;字节。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 宋体;"&gt;传输速率包括内部传输速率和外部传输速率。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 宋体;"&gt;内部传输率(Internal Transfer Rate)&amp;nbsp;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;也称为持续传输率(Sustained Transfer Rate)&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，它反映了硬盘&lt;/span&gt;&lt;a href="http://baike.baidu.com/view/266782.htm" target="_blank" style="color: #4371a6;"&gt;&lt;span&gt;&lt;span style="font-family: 宋体; color: windowtext; text-decoration: none;"&gt;缓冲区&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: 宋体;"&gt;未用时的性能。内部传输率主要依赖于硬盘的旋转速度。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 宋体;"&gt;外部传输率（External Transfer Rate&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;）也称为&lt;/span&gt;&lt;a href="http://baike.baidu.com/view/188732.htm" target="_blank" style="color: #4371a6;"&gt;&lt;span&gt;&lt;span style="font-family: 宋体; color: windowtext; text-decoration: none;"&gt;突发数据传输率&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: 宋体;"&gt;（&lt;span&gt;Burst Data Transfer Rate&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;）或接口传输率，它标称的是&lt;/span&gt;&lt;a href="http://baike.baidu.com/view/65714.htm" target="_blank" style="color: #4371a6;"&gt;&lt;span&gt;&lt;span style="font-family: 宋体; color: windowtext; text-decoration: none;"&gt;系统总线&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: 宋体;"&gt;与硬盘缓冲区之间的数据传输率，外部数据传输率与&lt;/span&gt;&lt;a href="http://baike.baidu.com/view/82486.htm" target="_blank" style="color: #4371a6;"&gt;&lt;span&gt;&lt;span style="font-family: 宋体; color: windowtext; text-decoration: none;"&gt;硬盘接口类型&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: 宋体;"&gt;和&lt;/span&gt;&lt;a href="http://baike.baidu.com/view/6845.htm" target="_blank" style="color: #4371a6;"&gt;&lt;span&gt;&lt;span style="font-family: 宋体; color: windowtext; text-decoration: none;"&gt;硬盘缓存&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: 宋体;"&gt;的大小有关。STAT2&amp;nbsp;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的传输速率在300MB/s&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;级别。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 宋体;"&gt;因此在硬件级上，提高磁盘性能的关键主要是降低平均访问时间。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span&gt;二．&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;设备驱动&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 宋体;"&gt;内存到硬盘的传输方式：poll&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，中断，DMA&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span&gt;DMA&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;：当 CPU&amp;nbsp;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;初始化这个传输动作，传输动作本身是由&amp;nbsp;DMA&amp;nbsp;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;控制器&amp;nbsp;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;来实行和完成。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;DMA&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;控制器获得总线控制权后，CPU&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;即刻挂起或只执行内部操作，由DMA&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;控制器输出读写命令，直接控制RAM&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;与I/O&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;接口进行DMA&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;传输。DMA&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;每次传送的是磁盘上相邻的扇区。Scatter-gather DMA&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;允许传送不相邻的扇区。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span&gt;CPU&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;性能与硬盘与内存的数据传输速率关系不大。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 宋体;"&gt;设备驱动内有一个结构管理着IO&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的请求队列&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;structrequest_queue&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;（include/linux/Blkdev.h&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;）&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 宋体;"&gt;这里不仅仅有读写请求的数据块，还有用于IO&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;调度的回调函数结构。每次需要传输的时候，就从队列中选出一个数据块交给DMA&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;进行传输。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 宋体;"&gt;所以&lt;a name="_GoBack"&gt;IO&lt;/a&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="font-family: 宋体;"&gt;调度的回调函数这是降低平均访问的时间&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的关键。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span&gt;三．&lt;/span&gt;OS&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;IO&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;调度器&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;Linux kernel&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;提供了四个调度器供用户选择。他们是noop,cfq,deadline,as&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。可以在系统启动时设置内核参数elevator=&amp;lt;name&amp;gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;来指定默认的调度器。也可以在运行时为某个块设备设置IO&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;调度程序。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 宋体;"&gt;下面来简要介绍这四个调度器的电梯调度算法。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;Noop&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;：最简单的调度算法。新的请求总是被添加到队头或者队尾，然后总是从队头中选出将要被处理的请求。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span&gt;CFQ&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;：（Complete FarinessQueueing&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;）它的目标是在所有请求的进程中平均分配IO&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的带宽。因此，它会根据进程创建自己的请求队列，然后将IO&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;请求放入相应的队列中。在使用轮转法从每个非空的队列中取出IO&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;请求。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span&gt;Deadline&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;：使用了四个队列，两个以磁盘块序号排序的读写队列，两个以最后期限时间排序的读写队列。算法首先确定下一个读写的方向，读的优先级高于写。然后检查被选方向的最后期限队列：如果最后期限时间的队列中有超时的请求，则将刚才的请求移动至队尾，然后在磁盘号排序队列中从超时请求开始处理。当处理完一个方向的请求后，在处理另一个方向的请求。（读请求的超时时间是500ms&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，写请求的超时时间是5s&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;）&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span&gt;Anticipatory&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;：它是最复杂的IO&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;调度算法。和deadline&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;算法一样有四个队列。还附带了一些启发式策略。它会从当前的磁头位置后的磁盘号中选择请求。在调度了一个由P&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;进程的IO&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;请求后，会检查下一个请求，如果还是P&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;进程的请求，则立即调度，如果不是，同时预测P&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;进程很快会发出请求，则还延长大约7ms&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的时间等待P&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;进程的IO&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;请求。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span&gt;Write/Read&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;函数&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 宋体;"&gt;以ext3&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的write&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;为例：&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 宋体;"&gt;系统调用write()&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的作用就是修改页高速缓存内的一些页的内容，如果页高速缓存内没有所要的页则分配并追加这些页。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 宋体;"&gt;当脏页达到一定数量或者超时后，将脏页刷回硬盘。也可以执行相关系统调用。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 宋体;"&gt;为什么要达到一定数量，是因为延迟写能在一定层度上提高系统的性能，这也使得块设备的平均读请求会多于写请求。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 宋体;"&gt;在程序中调用write&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;函数，将进入系统调用f_op-&amp;gt;write&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。这个函数将调用ext3&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的do_sync_write&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。这个函数将参数封装后调用generic_file_aio_write&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。由参数名可以看出同步写变成了异步写。如果没有标记O_DIRECT&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，将调用函数generic_file_buffered_write&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;将写的内容写进kernel&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的高速页缓存中。Buffer&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;是以page&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;为单位即4k&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。之后当调用cond_resched()&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;进行进程的调度，DMA&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;会将buffer&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;中的内容写进硬盘。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 宋体;"&gt;所以当每次以4k&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;为单位写入硬盘时效率会达到最高。下面是UNIX&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;环境高级编程的实验结果：&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;img src="http://www.cppblog.com/images/cppblog_com/range/22.jpg" width="471" height="598" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 宋体;"&gt;下图是linux&amp;nbsp;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的块设备的数据操作层次：&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;Sector&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;扇区：是设备驱动和IO&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;调度程序处理数据粒度。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;Block&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;块：是VFS&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;和文件系统处理数据的粒度。其大小不唯一，可以是512,1024,2048,4096&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;字节。内核操作的块大小是4096&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;字节。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;Segment&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;段：是DMA&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;传送的单位。每一个段包含了相邻的扇区，它能使DMA&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;传送不相邻的扇区。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;img src="http://www.cppblog.com/images/cppblog_com/range/23.jpg" width="359" height="353" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span&gt;四．&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;用户程序&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 宋体;"&gt;根据以上的分析，我们的&lt;span&gt;write buffer&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;一般设置为4K&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的倍数。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 宋体;"&gt;在程序中有意识的延迟写。这个是os&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的策略，当然也可以应用到程序的设计中。当然也会有缺点：1.&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;如果硬件错误或掉电，则会丢失内容（做额外的备份）2.&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;需要额外的内存空间。（牺牲内存来提高IO&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的效率）&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 宋体;"&gt;我们还需根据系统的IO&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;调度器的调度策略，设计出不同的IO&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;策略。尽量降低磁盘的平均访问时间，降低请求队列，提高数据传输的速率。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span&gt;五．&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;监控硬盘的工具和指标&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;Iostat&amp;ndash;x &amp;ndash;k 1&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&amp;nbsp;-x&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;显示更多的消息&amp;nbsp;-k&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;数据以KB&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;为单位 1&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;每秒显示一次&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 宋体;"&gt;输出显示的信息&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;Iowait&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;：cpu&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;等待未完成的IO&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;请求而空闲的时间的比例。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;Idle&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;：cpu&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;空闲且无IO&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;请求的比例。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;rrqm/s&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;：每秒这个设备相关的读取请求有多少被Merge&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;了。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;wrqm/s&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;：每秒这个设备相关的写入请求有多少被Merge&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;了。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;rsec/s&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;：每秒读取的扇区数；&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;wsec/&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;：每秒写入的扇区数。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;r/s&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;：每秒完成的读 I/O&amp;nbsp;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;设备次数。即&lt;span&gt;&amp;nbsp;delta(rio)/s&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;w/s&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;：每秒完成的写 I/O&amp;nbsp;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;设备次数。即&lt;span&gt;&amp;nbsp;delta(wio)/s&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;await&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;：每一个IO&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;请求的处理的平均时间（单位是毫秒）。包括加入请求队列和服务的时间。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;svctm:&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;平均每次设备I/O&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;操作的服务时间。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;avgrq-sz:&amp;nbsp;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;平均每次设备I/O&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;操作的数据大小 (&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;扇区)&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。即&lt;span&gt;&amp;nbsp;delta(rsect+wsect)/delta(rio+wio)&lt;br /&gt;avgqu-sz:&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;平均I/O&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;队列长度。即 delta(aveq)/s/1000 (&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;因为aveq&lt;/span&gt;&lt;span&gt;&lt;span style="font-family: 宋体; color: #333333;"&gt;的单位为毫秒&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="font-family: Arial, sans-serif; color: #333333;"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="font-family: 宋体; color: #333333;"&gt;。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;%util&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;：在统计时间内所有处理IO&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;时间，除以总共统计时间。例如，如果统计间隔1&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;秒，该设备有0.8&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;秒在处理IO&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，而0.2&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;秒闲置，那么该设备的%util = 0.8/1 = 80%&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，所以该参数暗示了设备的繁忙程度。一般地，如果该参数是100%&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;表示设备已经接近满负荷运行了（当然如果是多磁盘，即使%util&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;是100%&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，因为磁盘的并发能力，所以磁盘使用未必就到了瓶颈）。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 宋体;"&gt;下面我们做一个实验来分析一下&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 宋体;"&gt;我们使用命令&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span&gt;time dd if=/dev/zero of=/home/zhouyuan/mytest bs=1M count=3000&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 宋体;"&gt;向mytest&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;写入数据，写入3G&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 宋体;"&gt;截取部分的状态监控：&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;img src="http://www.cppblog.com/images/cppblog_com/range/24.jpg" width="992" height="354" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&lt;img src="http://www.cppblog.com/images/cppblog_com/range/25.jpg" width="692" height="361" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&lt;img src="http://www.cppblog.com/images/cppblog_com/range/26.jpg" width="668" height="357" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 宋体;"&gt;如图2&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，当两条数据&lt;span&gt;&amp;nbsp;iowait&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="font-family: 宋体;"&gt;达到了&lt;/span&gt;&amp;nbsp;99%&amp;nbsp;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;以上，写入的数据是0&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，这是因为DMA&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;将内存的中的数据传输给设备。结合图1&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的前两条数据，利用率达到了99%+&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;却没有写入的磁盘块。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 宋体;"&gt;如图3&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，iowait&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;下降，说明cpu&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;开始执行相关程序，而此时块设备开始写入的数据。这两个操作是异步进行的。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span&gt;Vmstat&amp;ndash;k &amp;ndash;n 1&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;Swap&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 宋体;"&gt;si:&amp;nbsp;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;从磁盘交换到内存的交换页数量，单位：KB/&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;秒&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 宋体;"&gt;so:&amp;nbsp;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;从内存交换到磁盘的交换页数量，单位：KB/&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;秒&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;IO&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 宋体;"&gt;bi: 从&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;块设备接受的块数，单位：块/&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;秒&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 宋体;"&gt;bo:&amp;nbsp;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;发送到块设备的块数，单位：块/&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;秒&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;img src="http://www.cppblog.com/images/cppblog_com/range/27.jpg" width="748" height="31" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&lt;img src="http://www.cppblog.com/images/cppblog_com/range/28.jpg" width="736" height="461" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 宋体;"&gt;从图中我们可以看出系统的延迟写。&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;img src="http://www.cnblogs.com/buffer/aggbug/2169292.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/buffer/archive/2011/09/06/2169292.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/buffer/archive/2011/09/06/2169288.html</id><title type="text">五种常见的 PHP 设计模式</title><summary type="text">设计模式一书将设计模式引入软件社区，该书的作者是 Erich Gamma、Richard Helm、Ralph Johnson 和 John Vlissides Design（俗称 “四人帮”）。所介绍的设计模式背后的核心概念非常简单。经过多年的软件开发实践，Gamma 等人发现了某些具有固定设计的模式，就像建筑师设计房子和建筑物一样，可以为浴室的位置或厨房的构造方式开发模板。使用这些模板或者说设计模式意味着可以更快地设计更好的建筑物。同样的概念也适用于软件。设计模式不仅代表着更快开发健壮软件的有用方法，而且还提供了以友好的术语封装大型理念的方法。例如，您可以说您正在编写一个提供松散耦合的消息</summary><published>2011-09-06T15:07:00Z</published><updated>2011-09-06T15:07:00Z</updated><author><name>牛司朋</name><uri>http://www.cnblogs.com/buffer/</uri></author><link rel="alternate" href="http://www.cnblogs.com/buffer/archive/2011/09/06/2169288.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/buffer/archive/2011/09/06/2169288.html"/><content type="html">&lt;p&gt;&lt;em&gt;设计模式&lt;/em&gt;&amp;nbsp;一书将设计模式引入软件社区，该书的作者是 Erich Gamma、Richard Helm、Ralph Johnson 和 John Vlissides Design（俗称 &amp;ldquo;四人帮&amp;rdquo;）。所介绍的设计模式背后的核心概念非常简单。经过多年的软件开发实践，Gamma 等人发现了某些具有固定设计的模式，就像建筑师设计房子和建筑物一样，可以为浴室的位置或厨房的构造方式开发模板。使用这些模板或者说&lt;em&gt;设计模式&lt;/em&gt;&amp;nbsp;意味着可以更快地设计更好的建筑物。同样的概念也适用于软件。&lt;/p&gt;&lt;p&gt;设计模式不仅代表着更快开发健壮软件的有用方法，而且还提供了以友好的术语封装大型理念的方法。例如，您可以说您正在编写一个提供松散耦合的消息传递系统，也可以说你正在编写名称为&lt;em&gt;观察者&lt;/em&gt;&amp;nbsp;的模式。&lt;/p&gt;&lt;p&gt;用较小的示例展示模式的价值是非常困难的。这往往有些大材小用的意味，因为模式实际上是在大型代码库中发挥作用的。本文不展示大型应用程序，所以您需要思索的是在您自己的大型应用程序中应用示例原理的方法 &amp;mdash;&amp;mdash; 而不是本文演示的代码本身。这不是说您不应该在小应用程序中使用模式。很多良好的应用程序都以小应用程序为起点，逐渐发展到大型应用程序，所以没有理由不以此类扎实的编码实践为基础。&lt;/p&gt;&lt;p&gt;既然您已经了解了设计模式以及它们的有用之处，现在我们来看看 PHP V5 的五种常用模式。&lt;/p&gt;&lt;p&gt;&lt;a name="N10063"&gt;&lt;span class="atitle" style="font-size: 1.5em; font-weight: bold;"&gt;工厂模式&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;最初在&lt;em&gt;设计模式&lt;/em&gt;&amp;nbsp;一书中，许多设计模式都鼓励使用&lt;em&gt;松散耦合&lt;/em&gt;。要理解这个概念，让我们最好谈一下许多开发人员从事大型系统的艰苦历程。在更改一个代码片段时，就会发生问题，系统其他部分 &amp;mdash;&amp;mdash; 您曾认为完全不相关的部分中也有可能出现级联破坏。&lt;/p&gt;&lt;p&gt;该问题在于&lt;em&gt;紧密耦合&lt;/em&gt;&amp;nbsp;。系统某个部分中的函数和类严重依赖于系统的其他部分中函数和类的行为和结构。您需要一组模式，使这些类能够相互通信，但不希望将它们紧密绑定在一起，以避免出现联锁。&lt;/p&gt;&lt;p&gt;在大型系统中，许多代码依赖于少数几个关键类。需要更改这些类时，可能会出现困难。例如，假设您有一个从文件读取的&amp;nbsp;&lt;code style="font-family: monospace; font-size: small !important;"&gt;User&lt;/code&gt;类。您希望将其更改为从数据库读取的其他类，但是，所有的代码都引用从文件读取的原始类。这时候，使用工厂模式会很方便。&lt;/p&gt;&lt;p&gt;&lt;em&gt;工厂模式&lt;/em&gt;&amp;nbsp;是一种类，它具有为您创建对象的某些方法。您可以使用工厂类创建对象，而不直接使用&amp;nbsp;&lt;code style="font-family: monospace; font-size: small !important;"&gt;new&lt;/code&gt;。这样，如果您想要更改所创建的对象类型，只需更改该工厂即可。使用该工厂的所有代码会自动更改。&lt;/p&gt;&lt;p&gt;清单 1 显示工厂类的一个示列。等式的服务器端包括两个部分：数据库和一组 PHP 页面，这些页面允许您添加反馈、请求反馈列表并获取与特定反馈相关的文章。&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span" style="font-family: Simsun; line-height: normal; font-size: medium;"&gt;&lt;br /&gt;&lt;a name="listing1"&gt;&lt;b style="font-size: 0.76em; font-weight: bold; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-family: arial, sans-serif;"&gt;清单 1. Factory1.php&lt;/b&gt;&lt;/a&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;table cellpadding="0" cellspacing="0" border="0" style="font-size: 0.8em; width: 100%;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class="code-outline" style="font-family: arial, nsimsun, sans-serif; background-color: #f7f7f7 !important; padding-top: 2px; padding-right: 2px; padding-bottom: 5px; padding-left: 2px; border-width: 1px; border-color: #cccccc; border-style: solid;"&gt;&amp;lt;?php&lt;br/&gt;interface IUser&lt;br/&gt;{&lt;br/&gt;  function getName();&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;class User implements IUser&lt;br/&gt;{&lt;br/&gt;  public function __construct( $id ) { }&lt;br/&gt;&lt;br/&gt;  public function getName()&lt;br/&gt;  {&lt;br/&gt;    return "Jack";&lt;br/&gt;  }&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;class UserFactory&lt;br/&gt;{&lt;br/&gt;  public static function Create( $id )&lt;br/&gt;  {&lt;br/&gt;    return new User( $id );&lt;br/&gt;  }&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;$uo = UserFactory::Create( 1 );&lt;br/&gt;echo( $uo-&amp;gt;getName()."\n" );&lt;br/&gt;?&amp;gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;span class="Apple-style-span" style="font-family: Simsun; line-height: normal; font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;code style="font-family: monospace; font-size: small !important;"&gt;IUser&lt;/code&gt;&amp;nbsp;接口定义用户对象应执行什么操作。&lt;code style="font-family: monospace; font-size: small !important;"&gt;IUser&lt;/code&gt;&amp;nbsp;的实现称为&amp;nbsp;&lt;code style="font-family: monospace; font-size: small !important;"&gt;User&lt;/code&gt;，&lt;code style="font-family: monospace; font-size: small !important;"&gt;UserFactory&lt;/code&gt;&amp;nbsp;工厂类则创建&amp;nbsp;&lt;code style="font-family: monospace; font-size: small !important;"&gt;IUser&lt;/code&gt;&amp;nbsp;对象。此关系可以用图 1 中的 UML 表示。&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span" style="font-family: Simsun; line-height: normal; font-size: medium;"&gt;&lt;br /&gt;&lt;a name="fig1"&gt;&lt;b style="font-size: 0.76em; font-weight: bold; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-family: arial, sans-serif;"&gt;图 1. 工厂类及其相关 IUser 接口和用户类&lt;/b&gt;&lt;/a&gt;&lt;br /&gt;&lt;img alt="工厂类及其相关 IUser 接口和用户类" height="86" src="http://www.ibm.com/developerworks/cn/opensource/os-php-designptrns/factory1.gif" width="229" style="border-style: initial; border-color: initial; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; border-width: 0px;" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;如果您使用&amp;nbsp;&lt;code style="font-family: monospace; font-size: small !important;"&gt;php&lt;/code&gt;&amp;nbsp;解释器在命令行上运行此代码，将得到如下结果：&lt;/p&gt;&lt;table cellpadding="0" cellspacing="0" border="0" style="font-size: 0.8em; width: 100%;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class="code-outline" style="font-family: arial, nsimsun, sans-serif; background-color: #f7f7f7 !important; padding-top: 2px; padding-right: 2px; padding-bottom: 5px; padding-left: 2px; border-width: 1px; border-color: #cccccc; border-style: solid;"&gt;% php factory1.php &lt;br/&gt;Jack&lt;br/&gt;%&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;span class="Apple-style-span" style="font-family: Simsun; line-height: normal; font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;测试代码会向工厂请求&amp;nbsp;&lt;code style="font-family: monospace; font-size: small !important;"&gt;User&lt;/code&gt;&amp;nbsp;对象，并输出&amp;nbsp;&lt;code style="font-family: monospace; font-size: small !important;"&gt;getName&lt;/code&gt;&amp;nbsp;方法的结果。&lt;/p&gt;&lt;p&gt;有一种工厂模式的变体使用工厂方法。类中的这些公共静态方法构造该类型的对象。如果创建此类型的对象非常重要，此方法非常有用。例如，假设您需要先创建对象，然后设置许多属性。此版本的工厂模式会将该进程封装在单个位置中，这样，不用复制复杂的初始化代码，也不必将复制好的代码在在代码库中到处粘贴。&lt;/p&gt;&lt;p&gt;清单 2 显示使用工厂方法的一个示例。&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span" style="font-family: Simsun; line-height: normal; font-size: medium;"&gt;&lt;br /&gt;&lt;a name="listing2"&gt;&lt;b style="font-size: 0.76em; font-weight: bold; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-family: arial, sans-serif;"&gt;清单 2. Factory2.php&lt;/b&gt;&lt;/a&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;table cellpadding="0" cellspacing="0" border="0" style="font-size: 0.8em; width: 100%;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class="code-outline" style="font-family: arial, nsimsun, sans-serif; background-color: #f7f7f7 !important; padding-top: 2px; padding-right: 2px; padding-bottom: 5px; padding-left: 2px; border-width: 1px; border-color: #cccccc; border-style: solid;"&gt;&amp;lt;?php&lt;br/&gt;interface IUser&lt;br/&gt;{&lt;br/&gt;  function getName();&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;class User implements IUser&lt;br/&gt;{&lt;br/&gt;  public static function Load( $id ) &lt;br/&gt;  {&lt;br/&gt;        return new User( $id );&lt;br/&gt;  }&lt;br/&gt;&lt;br/&gt;  public static function Create( ) &lt;br/&gt;  {&lt;br/&gt;        return new User( null );&lt;br/&gt;  }&lt;br/&gt;&lt;br/&gt;  public function __construct( $id ) { }&lt;br/&gt;&lt;br/&gt;  public function getName()&lt;br/&gt;  {&lt;br/&gt;    return "Jack";&lt;br/&gt;  }&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;$uo = User::Load( 1 );&lt;br/&gt;echo( $uo-&amp;gt;getName()."\n" );&lt;br/&gt;?&amp;gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;span class="Apple-style-span" style="font-family: Simsun; line-height: normal; font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;这段代码要简单得多。它仅有一个接口&amp;nbsp;&lt;code style="font-family: monospace; font-size: small !important;"&gt;IUser&lt;/code&gt;&amp;nbsp;和一个实现此接口的&amp;nbsp;&lt;code style="font-family: monospace; font-size: small !important;"&gt;User&lt;/code&gt;&amp;nbsp;类。&lt;code style="font-family: monospace; font-size: small !important;"&gt;User&lt;/code&gt;&amp;nbsp;类有两个创建对象的静态方法。此关系可用图 2 中的 UML 表示。&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span" style="font-family: Simsun; line-height: normal; font-size: medium;"&gt;&lt;br /&gt;&lt;a name="fig2"&gt;&lt;b style="font-size: 0.76em; font-weight: bold; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-family: arial, sans-serif;"&gt;图 2. IUser 接口和带有工厂方法的 user 类&lt;/b&gt;&lt;/a&gt;&lt;br /&gt;&lt;img alt="IUser 接口和带有工厂方法的用户类" height="113" src="http://www.ibm.com/developerworks/cn/opensource/os-php-designptrns/factory2.gif" width="95" style="border-style: initial; border-color: initial; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; border-width: 0px;" /&gt;&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;在命令行中运行脚本产生的结果与清单 1 的结果相同，如下所示：&lt;/p&gt;&lt;table cellpadding="0" cellspacing="0" border="0" style="font-size: 0.8em; width: 100%;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class="code-outline" style="font-family: arial, nsimsun, sans-serif; background-color: #f7f7f7 !important; padding-top: 2px; padding-right: 2px; padding-bottom: 5px; padding-left: 2px; border-width: 1px; border-color: #cccccc; border-style: solid;"&gt;% php factory2.php &lt;br/&gt;Jack&lt;br/&gt;%&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;span class="Apple-style-span" style="font-family: Simsun; line-height: normal; font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;如上所述，有时此类模式在规模较小的环境中似乎有些大材小用。不过，最好还是学习这种扎实的编码形式，以便应用于任意规模的项目中。&lt;/p&gt;&lt;p&gt;&lt;a name="N1010F"&gt;&lt;span class="atitle" style="font-size: 1.5em; font-weight: bold;"&gt;单元素模式&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;某些应用程序资源是&lt;em&gt;独占的&lt;/em&gt;，因为有且只有一个此类型的资源。例如，通过数据库句柄到数据库的连接是独占的。您希望在应用程序中共享数据库句柄，因为在保持连接打开或关闭时，它是一种开销，在获取单个页面的过程中更是如此。&lt;/p&gt;&lt;p&gt;单元素模式可以满足此要求。如果应用程序每次包含且仅包含一个对象，那么这个对象就是一个&lt;em&gt;单元素&lt;/em&gt;（Singleton）。清单 3 中的代码显示了 PHP V5 中的一个数据库连接单元素。&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span" style="font-family: Simsun; line-height: normal; font-size: medium;"&gt;&lt;br /&gt;&lt;a name="listing3"&gt;&lt;b style="font-size: 0.76em; font-weight: bold; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-family: arial, sans-serif;"&gt;清单 3. Singleton.php&lt;/b&gt;&lt;/a&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;table cellpadding="0" cellspacing="0" border="0" style="font-size: 0.8em; width: 100%;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class="code-outline" style="font-family: arial, nsimsun, sans-serif; background-color: #f7f7f7 !important; padding-top: 2px; padding-right: 2px; padding-bottom: 5px; padding-left: 2px; border-width: 1px; border-color: #cccccc; border-style: solid;"&gt;&amp;lt;?php&lt;br/&gt;require_once("DB.php");&lt;br/&gt;&lt;br/&gt;class DatabaseConnection&lt;br/&gt;{&lt;br/&gt;  public static function get()&lt;br/&gt;  {&lt;br/&gt;    static $db = null;&lt;br/&gt;    if ( $db == null )&lt;br/&gt;      $db = new DatabaseConnection();&lt;br/&gt;    return $db;&lt;br/&gt;  }&lt;br/&gt;&lt;br/&gt;  private $_handle = null;&lt;br/&gt;&lt;br/&gt;  private function __construct()&lt;br/&gt;  {&lt;br/&gt;    $dsn = 'mysql://root:password@localhost/photos';&lt;br/&gt;    $this-&amp;gt;_handle =&amp;amp; DB::Connect( $dsn, array() );&lt;br/&gt;  }&lt;br/&gt;  &lt;br/&gt;  public function handle()&lt;br/&gt;  {&lt;br/&gt;    return $this-&amp;gt;_handle;&lt;br/&gt;  }&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;print( "Handle = ".DatabaseConnection::get()-&amp;gt;handle()."\n" );&lt;br/&gt;print( "Handle = ".DatabaseConnection::get()-&amp;gt;handle()."\n" );&lt;br/&gt;?&amp;gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;span class="Apple-style-span" style="font-family: Simsun; line-height: normal; font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;此代码显示名为&amp;nbsp;&lt;code style="font-family: monospace; font-size: small !important;"&gt;DatabaseConnection&lt;/code&gt;&amp;nbsp;的单个类。您不能创建自已的&amp;nbsp;&lt;code style="font-family: monospace; font-size: small !important;"&gt;DatabaseConnection&lt;/code&gt;，因为构造函数是专用的。但使用静态&amp;nbsp;&lt;code style="font-family: monospace; font-size: small !important;"&gt;get&lt;/code&gt;方法，您可以获得且仅获得一个&amp;nbsp;&lt;code style="font-family: monospace; font-size: small !important;"&gt;DatabaseConnection&lt;/code&gt;&amp;nbsp;对象。此代码的 UML 如图 3 所示。&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span" style="font-family: Simsun; line-height: normal; font-size: medium;"&gt;&lt;br /&gt;&lt;a name="fig3"&gt;&lt;b style="font-size: 0.76em; font-weight: bold; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-family: arial, sans-serif;"&gt;图 3. 数据库连接单元素&lt;/b&gt;&lt;/a&gt;&lt;br /&gt;&lt;img alt="数据库连接单元素" height="41" src="http://www.ibm.com/developerworks/cn/opensource/os-php-designptrns/singleton.gif" width="165" style="border-style: initial; border-color: initial; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; border-width: 0px;" /&gt;&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;在两次调用间，&lt;code style="font-family: monospace; font-size: small !important;"&gt;handle&lt;/code&gt;&amp;nbsp;方法返回的数据库句柄是相同的，这就是最好的证明。您可以在命令行中运行代码来观察这一点。&lt;/p&gt;&lt;table cellpadding="0" cellspacing="0" border="0" style="font-size: 0.8em; width: 100%;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class="code-outline" style="font-family: arial, nsimsun, sans-serif; background-color: #f7f7f7 !important; padding-top: 2px; padding-right: 2px; padding-bottom: 5px; padding-left: 2px; border-width: 1px; border-color: #cccccc; border-style: solid;"&gt;% php singleton.php &lt;br/&gt;Handle = Object id #3&lt;br/&gt;Handle = Object id #3&lt;br/&gt;%&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;span class="Apple-style-span" style="font-family: Simsun; line-height: normal; font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;返回的两个句柄是同一对象。如果您在整个应用程序中使用数据库连接单元素，那么就可以在任何地方重用同一句柄。&lt;/p&gt;&lt;p&gt;您可以使用全局变量存储数据库句柄，但是，该方法仅适用于较小的应用程序。在较大的应用程序中，应避免使用全局变量，并使用对象和方法访问资源。&lt;/p&gt;&lt;p&gt;&lt;a name="N10162"&gt;&lt;span class="atitle" style="font-size: 1.5em; font-weight: bold;"&gt;观察者模式&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;观察者模式为您提供了避免组件之间紧密耦合的另一种方法。该模式非常简单：一个对象通过添加一个方法（该方法允许另一个对象，即&lt;em&gt;观察者&lt;/em&gt;&amp;nbsp;注册自己）使本身变得可观察。当可观察的对象更改时，它会将消息发送到已注册的观察者。这些观察者使用该信息执行的操作与可观察的对象无关。结果是对象可以相互对话，而不必了解原因。&lt;/p&gt;&lt;p&gt;一个简单示例是系统中的用户列表。清单 4 中的代码显示一个用户列表，添加用户时，它将发送出一条消息。添加用户时，通过发送消息的日志观察者可以观察此列表。&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span" style="font-family: Simsun; line-height: normal; font-size: medium;"&gt;&lt;br /&gt;&lt;a name="listing4"&gt;&lt;b style="font-size: 0.76em; font-weight: bold; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-family: arial, sans-serif;"&gt;清单 4. Observer.php&lt;/b&gt;&lt;/a&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;table cellpadding="0" cellspacing="0" border="0" style="font-size: 0.8em; width: 100%;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class="code-outline" style="font-family: arial, nsimsun, sans-serif; background-color: #f7f7f7 !important; padding-top: 2px; padding-right: 2px; padding-bottom: 5px; padding-left: 2px; border-width: 1px; border-color: #cccccc; border-style: solid;"&gt;&amp;lt;?php&lt;br/&gt;interface IObserver&lt;br/&gt;{&lt;br/&gt;  function onChanged( $sender, $args );&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;interface IObservable&lt;br/&gt;{&lt;br/&gt;  function addObserver( $observer );&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;class UserList implements IObservable&lt;br/&gt;{&lt;br/&gt;  private $_observers = array();&lt;br/&gt;&lt;br/&gt;  public function addCustomer( $name )&lt;br/&gt;  {&lt;br/&gt;    foreach( $this-&amp;gt;_observers as $obs )&lt;br/&gt;      $obs-&amp;gt;onChanged( $this, $name );&lt;br/&gt;  }&lt;br/&gt;&lt;br/&gt;  public function addObserver( $observer )&lt;br/&gt;  {&lt;br/&gt;    $this-&amp;gt;_observers []= $observer;&lt;br/&gt;  }&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;class UserListLogger implements IObserver&lt;br/&gt;{&lt;br/&gt;  public function onChanged( $sender, $args )&lt;br/&gt;  {&lt;br/&gt;    echo( "'$args' added to user list\n" );&lt;br/&gt;  }&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;$ul = new UserList();&lt;br/&gt;$ul-&amp;gt;addObserver( new UserListLogger() );&lt;br/&gt;$ul-&amp;gt;addCustomer( "Jack" );&lt;br/&gt;?&amp;gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;span class="Apple-style-span" style="font-family: Simsun; line-height: normal; font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;此代码定义四个元素：两个接口和两个类。&lt;code style="font-family: monospace; font-size: small !important;"&gt;IObservable&lt;/code&gt;&amp;nbsp;接口定义可以被观察的对象，&lt;code style="font-family: monospace; font-size: small !important;"&gt;UserList&lt;/code&gt;&amp;nbsp;实现该接口，以便将本身注册为可观察。&lt;code style="font-family: monospace; font-size: small !important;"&gt;IObserver&lt;/code&gt;&amp;nbsp;列表定义要通过怎样的方法才能成为观察者，&lt;code style="font-family: monospace; font-size: small !important;"&gt;UserListLogger&lt;/code&gt;&amp;nbsp;实现&amp;nbsp;&lt;code style="font-family: monospace; font-size: small !important;"&gt;IObserver&lt;/code&gt;&amp;nbsp;接口。图 4 的 UML 中展示了这些元素。&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span" style="font-family: Simsun; line-height: normal; font-size: medium;"&gt;&lt;br /&gt;&lt;a name="fig4"&gt;&lt;b style="font-size: 0.76em; font-weight: bold; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-family: arial, sans-serif;"&gt;图 4. 可观察的用户列表和用户列表事件日志程序&lt;/b&gt;&lt;/a&gt;&lt;br /&gt;&lt;img alt="可观察的用户列表和用户列表事件日志程序" height="99" src="http://www.ibm.com/developerworks/cn/opensource/os-php-designptrns/observer.gif" width="414" style="border-style: initial; border-color: initial; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; border-width: 0px;" /&gt;&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;如果在命令行中运行它，您将看到以下输出：&lt;/p&gt;&lt;table cellpadding="0" cellspacing="0" border="0" style="font-size: 0.8em; width: 100%;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class="code-outline" style="font-family: arial, nsimsun, sans-serif; background-color: #f7f7f7 !important; padding-top: 2px; padding-right: 2px; padding-bottom: 5px; padding-left: 2px; border-width: 1px; border-color: #cccccc; border-style: solid;"&gt;% php observer.php &lt;br/&gt;'Jack' added to user list&lt;br/&gt;%&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;span class="Apple-style-span" style="font-family: Simsun; line-height: normal; font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;测试代码创建&amp;nbsp;&lt;code style="font-family: monospace; font-size: small !important;"&gt;UserList&lt;/code&gt;，并将&amp;nbsp;&lt;code style="font-family: monospace; font-size: small !important;"&gt;UserListLogger&lt;/code&gt;&amp;nbsp;观察者添加到其中。然后添加一个消费者，并将这一更改通知&amp;nbsp;&lt;code style="font-family: monospace; font-size: small !important;"&gt;UserListLogger&lt;/code&gt;。&lt;/p&gt;&lt;p&gt;认识到&amp;nbsp;&lt;code style="font-family: monospace; font-size: small !important;"&gt;UserList&lt;/code&gt;&amp;nbsp;不知道日志程序将执行什么操作很关键。可能存在一个或多个执行其他操作的侦听程序。例如，您可能有一个向新用户发送消息的观察者，欢迎新用户使用该系统。这种方法的价值在于&amp;nbsp;&lt;code style="font-family: monospace; font-size: small !important;"&gt;UserList&lt;/code&gt;&amp;nbsp;忽略所有依赖它的对象，它主要关注在列表更改时维护用户列表并发送消息这一工作。&lt;/p&gt;&lt;p&gt;此模式不限于内存中的对象。它是在较大的应用程序中使用的数据库驱动的消息查询系统的基础。&lt;/p&gt;&lt;p&gt;&lt;a name="N101C9"&gt;&lt;span class="atitle" style="font-size: 1.5em; font-weight: bold;"&gt;命令链模式&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;命令链&lt;/em&gt;&amp;nbsp;模式以松散耦合主题为基础，发送消息、命令和请求，或通过一组处理程序发送任意内容。每个处理程序都会自行判断自己能否处理请求。如果可以，该请求被处理，进程停止。您可以为系统添加或移除处理程序，而不影响其他处理程序。清单 5 显示了此模式的一个示例。&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span" style="font-family: Simsun; line-height: normal; font-size: medium;"&gt;&lt;br /&gt;&lt;a name="listing5"&gt;&lt;b style="font-size: 0.76em; font-weight: bold; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-family: arial, sans-serif;"&gt;清单 5. Chain.php&lt;/b&gt;&lt;/a&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;table cellpadding="0" cellspacing="0" border="0" style="font-size: 0.8em; width: 100%;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class="code-outline" style="font-family: arial, nsimsun, sans-serif; background-color: #f7f7f7 !important; padding-top: 2px; padding-right: 2px; padding-bottom: 5px; padding-left: 2px; border-width: 1px; border-color: #cccccc; border-style: solid;"&gt;&amp;lt;?php&lt;br/&gt;interface ICommand&lt;br/&gt;{&lt;br/&gt;  function onCommand( $name, $args );&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;class CommandChain&lt;br/&gt;{&lt;br/&gt;  private $_commands = array();&lt;br/&gt;&lt;br/&gt;  public function addCommand( $cmd )&lt;br/&gt;  {&lt;br/&gt;    $this-&amp;gt;_commands []= $cmd;&lt;br/&gt;  }&lt;br/&gt;&lt;br/&gt;  public function runCommand( $name, $args )&lt;br/&gt;  {&lt;br/&gt;    foreach( $this-&amp;gt;_commands as $cmd )&lt;br/&gt;    {&lt;br/&gt;      if ( $cmd-&amp;gt;onCommand( $name, $args ) )&lt;br/&gt;        return;&lt;br/&gt;    }&lt;br/&gt;  }&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;class UserCommand implements ICommand&lt;br/&gt;{&lt;br/&gt;  public function onCommand( $name, $args )&lt;br/&gt;  {&lt;br/&gt;    if ( $name != 'addUser' ) return false;&lt;br/&gt;    echo( "UserCommand handling 'addUser'\n" );&lt;br/&gt;    return true;&lt;br/&gt;  }&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;class MailCommand implements ICommand&lt;br/&gt;{&lt;br/&gt;  public function onCommand( $name, $args )&lt;br/&gt;  {&lt;br/&gt;    if ( $name != 'mail' ) return false;&lt;br/&gt;    echo( "MailCommand handling 'mail'\n" );&lt;br/&gt;    return true;&lt;br/&gt;  }&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;$cc = new CommandChain();&lt;br/&gt;$cc-&amp;gt;addCommand( new UserCommand() );&lt;br/&gt;$cc-&amp;gt;addCommand( new MailCommand() );&lt;br/&gt;$cc-&amp;gt;runCommand( 'addUser', null );&lt;br/&gt;$cc-&amp;gt;runCommand( 'mail', null );&lt;br/&gt;?&amp;gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;span class="Apple-style-span" style="font-family: Simsun; line-height: normal; font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;此代码定义维护&amp;nbsp;&lt;code style="font-family: monospace; font-size: small !important;"&gt;ICommand&lt;/code&gt;&amp;nbsp;对象列表的&amp;nbsp;&lt;code style="font-family: monospace; font-size: small !important;"&gt;CommandChain&lt;/code&gt;&amp;nbsp;类。两个类都可以实现&amp;nbsp;&lt;code style="font-family: monospace; font-size: small !important;"&gt;ICommand&lt;/code&gt;&amp;nbsp;接口 &amp;mdash;&amp;mdash; 一个对邮件的请求作出响应，另一个对添加用户作出响应。 图 5 给出了 UML。&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span" style="font-family: Simsun; line-height: normal; font-size: medium;"&gt;&lt;br /&gt;&lt;a name="fig5"&gt;&lt;b style="font-size: 0.76em; font-weight: bold; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-family: arial, sans-serif;"&gt;图 5. 命令链及其相关命令&lt;/b&gt;&lt;/a&gt;&lt;br /&gt;&lt;img alt="命令链及其相关命令" height="121" src="http://www.ibm.com/developerworks/cn/opensource/os-php-designptrns/chain.gif" width="359" style="border-style: initial; border-color: initial; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; border-width: 0px;" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;如果您运行包含某些测试代码的脚本，则会得到以下输出：&lt;/p&gt;&lt;table cellpadding="0" cellspacing="0" border="0" style="font-size: 0.8em; width: 100%;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class="code-outline" style="font-family: arial, nsimsun, sans-serif; background-color: #f7f7f7 !important; padding-top: 2px; padding-right: 2px; padding-bottom: 5px; padding-left: 2px; border-width: 1px; border-color: #cccccc; border-style: solid;"&gt;% php chain.php &lt;br/&gt;UserCommand handling 'addUser'&lt;br/&gt;MailCommand handling 'mail'&lt;br/&gt;%&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;span class="Apple-style-span" style="font-family: Simsun; line-height: normal; font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;代码首先创建&amp;nbsp;&lt;code style="font-family: monospace; font-size: small !important;"&gt;CommandChain&lt;/code&gt;&amp;nbsp;对象，并为它添加两个命令对象的实例。然后运行两个命令以查看谁对这些命令作出了响应。如果命令的名称匹配&amp;nbsp;&lt;code style="font-family: monospace; font-size: small !important;"&gt;UserCommand&lt;/code&gt;&amp;nbsp;或&amp;nbsp;&lt;code style="font-family: monospace; font-size: small !important;"&gt;MailCommand&lt;/code&gt;，则代码失败，不发生任何操作。&lt;/p&gt;&lt;p&gt;为处理请求而创建可扩展的架构时，命令链模式很有价值，使用它可以解决许多问题。&lt;/p&gt;&lt;p&gt;&lt;a name="N10218"&gt;&lt;span class="atitle" style="font-size: 1.5em; font-weight: bold;"&gt;策略模式&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;我们讲述的最后一个设计模式是&lt;em&gt;策略&lt;/em&gt;&amp;nbsp;模式。在此模式中，算法是从复杂类提取的，因而可以方便地替换。例如，如果要更改搜索引擎中排列页的方法，则策略模式是一个不错的选择。思考一下搜索引擎的几个部分 &amp;mdash;&amp;mdash; 一部分遍历页面，一部分对每页排列，另一部分基于排列的结果排序。在复杂的示例中，这些部分都在同一个类中。通过使用策略模式，您可将排列部分放入另一个类中，以便更改页排列的方式，而不影响搜索引擎的其余代码。&lt;/p&gt;&lt;p&gt;作为一个较简单的示例，清单 6 显示了一个用户列表类，它提供了一个根据一组即插即用的策略查找一组用户的方法。&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span" style="font-family: Simsun; line-height: normal; font-size: medium;"&gt;&lt;br /&gt;&lt;a name="listing6"&gt;&lt;b style="font-size: 0.76em; font-weight: bold; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-family: arial, sans-serif;"&gt;清单 6. Strategy.php&lt;/b&gt;&lt;/a&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;table cellpadding="0" cellspacing="0" border="0" style="font-size: 0.8em; width: 100%;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class="code-outline" style="font-family: arial, nsimsun, sans-serif; background-color: #f7f7f7 !important; padding-top: 2px; padding-right: 2px; padding-bottom: 5px; padding-left: 2px; border-width: 1px; border-color: #cccccc; border-style: solid;"&gt;&amp;lt;?php&lt;br/&gt;interface IStrategy&lt;br/&gt;{&lt;br/&gt;  function filter( $record );&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;class FindAfterStrategy implements IStrategy&lt;br/&gt;{&lt;br/&gt;  private $_name;&lt;br/&gt;&lt;br/&gt;  public function __construct( $name )&lt;br/&gt;  {&lt;br/&gt;    $this-&amp;gt;_name = $name;&lt;br/&gt;  }&lt;br/&gt;&lt;br/&gt;  public function filter( $record )&lt;br/&gt;  {&lt;br/&gt;    return strcmp( $this-&amp;gt;_name, $record ) &amp;lt;= 0;&lt;br/&gt;  }&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;class RandomStrategy implements IStrategy&lt;br/&gt;{&lt;br/&gt;  public function filter( $record )&lt;br/&gt;  {&lt;br/&gt;    return rand( 0, 1 ) &amp;gt;= 0.5;&lt;br/&gt;  }&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;class UserList&lt;br/&gt;{&lt;br/&gt;  private $_list = array();&lt;br/&gt;&lt;br/&gt;  public function __construct( $names )&lt;br/&gt;  {&lt;br/&gt;    if ( $names != null )&lt;br/&gt;    {&lt;br/&gt;      foreach( $names as $name )&lt;br/&gt;      {&lt;br/&gt;        $this-&amp;gt;_list []= $name;&lt;br/&gt;      }&lt;br/&gt;    }&lt;br/&gt;  }&lt;br/&gt;&lt;br/&gt;  public function add( $name )&lt;br/&gt;  {&lt;br/&gt;    $this-&amp;gt;_list []= $name;&lt;br/&gt;  }&lt;br/&gt;&lt;br/&gt;  public function find( $filter )&lt;br/&gt;  {&lt;br/&gt;    $recs = array();&lt;br/&gt;    foreach( $this-&amp;gt;_list as $user )&lt;br/&gt;    {&lt;br/&gt;      if ( $filter-&amp;gt;filter( $user ) )&lt;br/&gt;        $recs []= $user;&lt;br/&gt;    }&lt;br/&gt;    return $recs;&lt;br/&gt;  }&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;$ul = new UserList( array( "Andy", "Jack", "Lori", "Megan" ) );&lt;br/&gt;$f1 = $ul-&amp;gt;find( new FindAfterStrategy( "J" ) );&lt;br/&gt;print_r( $f1 );&lt;br/&gt;&lt;br/&gt;$f2 = $ul-&amp;gt;find( new RandomStrategy() );&lt;br/&gt;print_r( $f2 );&lt;br/&gt;?&amp;gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;span class="Apple-style-span" style="font-family: Simsun; line-height: normal; font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;此代码的 UML 如图 6 所示。&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span" style="font-family: Simsun; line-height: normal; font-size: medium;"&gt;&lt;br /&gt;&lt;a name="fig6"&gt;&lt;b style="font-size: 0.76em; font-weight: bold; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-family: arial, sans-serif;"&gt;图 6. 用户列表和用于选择用户的策略&lt;/b&gt;&lt;/a&gt;&lt;br /&gt;&lt;img alt="用户列表和用于选择用户的策略" height="138" src="http://www.ibm.com/developerworks/cn/opensource/os-php-designptrns/strategy.gif" width="309" style="border-style: initial; border-color: initial; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; border-width: 0px;" /&gt;&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;code style="font-family: monospace; font-size: small !important;"&gt;UserList&lt;/code&gt;&amp;nbsp;类是打包名称数组的一个包装器。它实现&amp;nbsp;&lt;code style="font-family: monospace; font-size: small !important;"&gt;find&lt;/code&gt;&amp;nbsp;方法，该方法利用几个策略之一来选择这些名称的子集。这些策略由&lt;code style="font-family: monospace; font-size: small !important;"&gt;IStrategy&lt;/code&gt;&amp;nbsp;接口定义，该接口有两个实现：一个随机选择用户，另一个根据指定名称选择其后的所有名称。运行测试代码时，将得到以下输出：&lt;/p&gt;&lt;table cellpadding="0" cellspacing="0" border="0" style="font-size: 0.8em; width: 100%;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class="code-outline" style="font-family: arial, nsimsun, sans-serif; background-color: #f7f7f7 !important; padding-top: 2px; padding-right: 2px; padding-bottom: 5px; padding-left: 2px; border-width: 1px; border-color: #cccccc; border-style: solid;"&gt;% php strategy.php &lt;br/&gt;Array&lt;br/&gt;(&lt;br/&gt;    [0] =&amp;gt; Jack&lt;br/&gt;    [1] =&amp;gt; Lori&lt;br/&gt;    [2] =&amp;gt; Megan&lt;br/&gt;)&lt;br/&gt;Array&lt;br/&gt;(&lt;br/&gt;    [0] =&amp;gt; Andy&lt;br/&gt;    [1] =&amp;gt; Megan&lt;br/&gt;)&lt;br/&gt;%&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;span class="Apple-style-span" style="font-family: Simsun; line-height: normal; font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;测试代码为两个策略运行同一用户列表，并显示结果。在第一种情况中，策略查找排列在&amp;nbsp;&lt;code style="font-family: monospace; font-size: small !important;"&gt;J&lt;/code&gt;&amp;nbsp;后的任何名称，所以您将得到 Jack、Lori 和 Megan。第二个策略随机选取名称，每次会产生不同的结果。在这种情况下，结果为 Andy 和 Megan。&lt;/p&gt;&lt;p&gt;策略模式非常适合复杂数据管理系统或数据处理系统，二者在数据筛选、搜索或处理的方式方面需要较高的灵活性。&lt;/p&gt;&lt;p&gt;&lt;a name="N10263"&gt;&lt;span class="atitle" style="font-size: 1.5em; font-weight: bold;"&gt;结束语&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;本文介绍的仅仅是 PHP 应用程序中使用的几种最常见的设计模式。在&lt;em&gt;设计模式&lt;/em&gt;&amp;nbsp;一书中演示了更多的设计模式。不要因架构的神秘性而放弃。模式是一种绝妙的理念，适用于任何编程语言、任何技能水平。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/buffer/aggbug/2169288.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/buffer/archive/2011/09/06/2169288.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/buffer/archive/2011/09/06/2169287.html</id><title type="text">C++设计模式-工厂方法</title><summary type="text">定义定义一个用于创建对象的接口，让子类决定实例化哪一个类。工厂方法（Factory Method）使一个类的实例化延迟到其子类。也叫虚构造器（Virtual Constructor）结构理解1.Product是工厂方法生产产品的抽象基类。2.Creator是生产产品的工厂对象抽象基类。Creator提供创建虚方法即工厂方法FactoryMeothod()。FactoryMeothod()由派生类（ConcreteCreator）具体实现，生产对应的具体产品（ConcreteProduct）。3.ConcreteProduct是继承Product的具体产品。4.ConcreteCreator是生</summary><published>2011-09-06T15:05:00Z</published><updated>2011-09-06T15:05:00Z</updated><author><name>牛司朋</name><uri>http://www.cnblogs.com/buffer/</uri></author><link rel="alternate" href="http://www.cnblogs.com/buffer/archive/2011/09/06/2169287.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/buffer/archive/2011/09/06/2169287.html"/><content type="html">&lt;div style="line-height: 22px;"&gt;&lt;b&gt;&lt;span style="font-size: 12pt; line-height: 24px; font-family: 宋体;"&gt;定义&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div style="line-height: 22px;"&gt;&lt;span style="font-family: 宋体;"&gt;定义一个用于创建对象的接口，让子类决定实例化哪一个类。工厂方法（&lt;/span&gt;Factory Method&lt;span style="font-family: 宋体;"&gt;）使一个类的实例化延迟到其子类。也叫虚构造器（&lt;/span&gt;Virtual Constructor&lt;span style="font-family: 宋体;"&gt;）&lt;/span&gt;&lt;/div&gt;&lt;div style="line-height: 22px;"&gt;&amp;nbsp;&lt;span id="more-288"&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="line-height: 22px;"&gt;&lt;b&gt;&lt;span style="font-size: 12pt; line-height: 24px; font-family: 宋体;"&gt;结构&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div align="center" style="text-align: center; line-height: 22px;"&gt;&lt;img width="450" height="181" align="middle" src="http://www.shenmiguo.com/wp-content/uploads/factory-method.jpg" alt="工厂方法" style="max-width: 580px; margin-left: 5px; margin-right: 5px; border-style: initial; border-color: initial; border-width: 0px;" /&gt;&lt;/div&gt;&lt;div style="line-height: 22px;"&gt;&amp;nbsp;&lt;/div&gt;&lt;div style="line-height: 22px;"&gt;&lt;b&gt;&lt;span style="font-size: 12pt; line-height: 24px; font-family: 宋体;"&gt;理解&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div style="margin-left: 18pt; text-indent: -18pt; line-height: 22px;"&gt;&lt;span&gt;1.&lt;span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;Product&lt;span style="font-family: 宋体;"&gt;是工厂方法生产产品的抽象基类。&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 18pt; text-indent: -18pt; line-height: 22px;"&gt;&lt;span&gt;2.&lt;span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;Creator&lt;span style="font-family: 宋体;"&gt;是生产产品的工厂对象抽象基类。&lt;/span&gt;Creator&lt;span style="font-family: 宋体;"&gt;提供创建虚方法即&lt;span style="color: red;"&gt;工厂方法&lt;/span&gt;&lt;/span&gt;FactoryMeothod()&lt;span style="font-family: 宋体;"&gt;。&lt;/span&gt;FactoryMeothod()&lt;span style="font-family: 宋体;"&gt;由派生类（&lt;/span&gt;ConcreteCreator&lt;span style="font-family: 宋体;"&gt;）具体实现，生产对应的具体产品（&lt;/span&gt;ConcreteProduct&lt;span style="font-family: 宋体;"&gt;）。&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 18pt; text-indent: -18pt; line-height: 22px;"&gt;&lt;span&gt;3.&lt;span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;ConcreteProduct&lt;span style="font-family: 宋体;"&gt;是继承&lt;/span&gt;Product&lt;span style="font-family: 宋体;"&gt;的具体产品。&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 18pt; text-indent: -18pt; line-height: 22px;"&gt;&lt;span&gt;4.&lt;span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;ConcreteCreator&lt;span style="font-family: 宋体;"&gt;是生产对应具体产品（&lt;/span&gt;ConcreteProduct&lt;span style="font-family: 宋体;"&gt;）的具体工厂。它重新实现继承的工厂方法&lt;/span&gt;FactoryMeothod()&lt;span style="font-family: 宋体;"&gt;，生产具体产品。&lt;/span&gt;&lt;/div&gt;&lt;div style="line-height: 22px;"&gt;&amp;nbsp;&lt;/div&gt;&lt;div style="line-height: 22px;"&gt;&lt;b&gt;&lt;span style="font-size: 12pt; line-height: 24px; font-family: 宋体;"&gt;要点&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div style="margin-left: 18pt; text-indent: -18pt; line-height: 22px;"&gt;&lt;span&gt;1.&lt;span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;工厂方法模式中，工厂和产品的基类和派生类是平行关系。抽象产品（&lt;/span&gt;Product&lt;span style="font-family: 宋体;"&gt;）对应层次是抽象工厂（&lt;/span&gt;Creator&lt;span style="font-family: 宋体;"&gt;）。在派生类层次，每个具体产品（&lt;/span&gt;ConcreteProduct&lt;span style="font-family: 宋体;"&gt;）对应一个具体工厂（&lt;/span&gt;ConcreteCreator&lt;span style="font-family: 宋体;"&gt;）。换句话说，&lt;span style="color: red;"&gt;每新增一个具体产品，就要新增一个对应的具体工厂&lt;/span&gt;。&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 18pt; text-indent: -18pt; line-height: 22px;"&gt;&lt;span&gt;2.&lt;span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;工厂方法的核心是&lt;/span&gt;FactoryMeothod()&lt;span style="font-family: 宋体;"&gt;，每个具体工厂都重新实现该接口，产生具体类对象。&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 18pt; text-indent: -18pt; line-height: 22px;"&gt;&lt;span&gt;3.&lt;span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;工厂方法&lt;span style="color: red;"&gt;分离客户端和具体类的实现&lt;/span&gt;。利用子类（即具体工厂），让子类来决定如何来生产一个具体产品。这样，客户端（即调用者）只需要知道这个类的抽象类型，由子类去和具体产品类打交道。&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 18pt; text-indent: -18pt; line-height: 22px;"&gt;&lt;span&gt;4.&lt;span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;工厂基类中的方法&lt;/span&gt;AnOperation()&lt;span style="font-family: 宋体;"&gt;，不是工厂方法，只是供具体工厂实现的公共接口（可以说是&lt;span style="color: red;"&gt;工厂对产品的使用行为&lt;/span&gt;）。但个人认为，工厂方法只是生产产品，公共接口的重点应该是产品，因此在&lt;span style="color: red;"&gt;产品基类里增加产品使用的公共接口&lt;/span&gt;更加实用。&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 18pt; text-indent: -18pt; line-height: 22px;"&gt;&lt;span&gt;5.&lt;span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;工厂方法模式的工厂（&lt;/span&gt;Creator&lt;span style="font-family: 宋体;"&gt;）若要全局唯一，可以结合单件（&lt;/span&gt;Singleton&lt;span style="font-family: 宋体;"&gt;）模式应用。&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 18pt; text-indent: -18pt; line-height: 22px;"&gt;&lt;span&gt;6.&lt;span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;关于&lt;span style="color: red;"&gt;简单工厂&lt;/span&gt;&lt;/span&gt;&lt;span style="color: red;"&gt;(&lt;/span&gt;&lt;span style="font-family: 宋体; color: red;"&gt;也叫静态工厂&lt;/span&gt;&lt;span style="color: red;"&gt;)&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。工厂方法强调的是&amp;ldquo;&lt;span style="color: red;"&gt;让子类决定实例化什么样的对象&lt;/span&gt;&amp;rdquo;，因为子类知道它们要使用的特定产品。如果我们将&lt;/span&gt;Creator&lt;span style="font-family: 宋体;"&gt;和&lt;/span&gt;ConcreteCreator&lt;span style="font-family: 宋体;"&gt;的角色合一，并且将工厂方法&lt;/span&gt;FactoryMeothod()&lt;span style="font-family: 宋体;"&gt;静态化，那么就退化成了简单工厂模式。&lt;/span&gt;&lt;/div&gt;&lt;div style="line-height: 22px;"&gt;&amp;nbsp;&lt;/div&gt;&lt;div style="line-height: 22px;"&gt;&lt;b&gt;&lt;span style="font-size: 12pt; line-height: 24px; font-family: 宋体;"&gt;应用&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div style="margin-left: 18pt; text-indent: -18pt; line-height: 22px;"&gt;&lt;span&gt;1.&lt;span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;工厂方法应用场景：&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 18pt; line-height: 22px;"&gt;&lt;span style="font-family: 宋体;"&gt;当一个类不知道它所必须创建的对象的类的时候。&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 18pt; line-height: 22px;"&gt;&lt;span style="font-family: 宋体;"&gt;当一个类希望由它的子类来指定它所创建的对象的时候。&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 18pt; line-height: 22px;"&gt;&lt;span style="font-family: 宋体;"&gt;当类将创建对象的职责委托给多个帮助子类中的某一个，并且你希望将哪一个帮助子类是代理者这一信息局部化的时候。（往往放在抽象产品侧）&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 18pt; text-indent: -18pt; line-height: 22px;"&gt;&lt;span&gt;2.&lt;span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;Loki&lt;span style="font-family: 宋体;"&gt;库中对工厂方法有一个比较完美的实现，结合了函数对象（&lt;/span&gt;Functor&lt;span style="font-family: 宋体;"&gt;），可制定产品创建方法。可参见：&lt;/span&gt;&lt;a href="http://loki-lib.sourceforge.net/index.php?n=Pattern.FactoryMethod" style="color: #08476a; text-decoration: none; border-bottom-width: 1px; border-bottom-style: dotted; border-bottom-color: #cccccc;"&gt;http://loki-lib.sourceforge.net/index.php?n=Pattern.FactoryMethod&lt;/a&gt;&lt;/div&gt;&lt;div style="margin-left: 18pt; text-indent: -18pt; line-height: 22px;"&gt;&lt;span&gt;3.&lt;span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;源码中的应用&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 18pt; line-height: 22px;"&gt;COSProduct&lt;span style="font-family: 宋体;"&gt;是产品基类。并且有产品的公共使用接口。&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 18pt; line-height: 22px;"&gt;COSCreator&lt;span style="font-family: 宋体;"&gt;是工厂基类。模式结构中的产品使用行为接口&lt;/span&gt;AnOperaion&lt;span style="font-family: 宋体;"&gt;并没有出现在工厂基类接口中，放在了产品侧（&lt;/span&gt;Start&lt;span style="font-family: 宋体;"&gt;接口）。&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 18pt; line-height: 22px;"&gt;&lt;span style="font-family: 宋体;"&gt;具体工厂可以通过继承&lt;/span&gt;COSCreator&lt;span style="font-family: 宋体;"&gt;实现，有多少个具体工厂，就要有多少个具体工厂类。通过&lt;/span&gt;C++&lt;span style="font-family: 宋体;"&gt;模板可以避免创建多个具体工厂（模板类&lt;/span&gt;CConcreteCreator&lt;span style="font-family: 宋体;"&gt;）。&lt;/span&gt;&lt;/div&gt;&lt;div style="line-height: 22px;"&gt;&amp;nbsp;&lt;/div&gt;&lt;div style="line-height: 22px;"&gt;&lt;b&gt;&lt;span style="font-size: 12pt; line-height: 24px; font-family: 宋体;"&gt;源码&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New'; color: blue;"&gt;#include&lt;/span&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;&amp;nbsp;&lt;span style="color: #a31515;"&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New'; color: blue;"&gt;#include&lt;/span&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;&amp;nbsp;&lt;span style="color: #a31515;"&gt;&amp;lt;string&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New'; color: blue;"&gt;using&lt;/span&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;namespace&lt;/span&gt;&amp;nbsp;&lt;span style="color: #010001;"&gt;std&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&amp;nbsp;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New'; color: green;"&gt;///////////////////&lt;/span&gt;&lt;span style="font-size: 9pt; font-family: 宋体; color: green;"&gt;产品&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New'; color: blue;"&gt;class&lt;/span&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;&amp;nbsp;&lt;span style="color: #010001;"&gt;COSProduct&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New'; color: blue;"&gt;public&lt;/span&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;:&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;virtual&lt;/span&gt;&amp;nbsp;~&lt;span style="color: #010001;"&gt;COSProduct&lt;/span&gt;(){};&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 9pt; font-family: 宋体; color: green;"&gt;产品的公共接口。相当于&lt;/span&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New'; color: green;"&gt;AnOperation&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;virtual&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;void&lt;/span&gt;&amp;nbsp;&lt;span style="color: #010001;"&gt;Start&lt;/span&gt;() = 0;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;};&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&amp;nbsp;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New'; color: blue;"&gt;class&lt;/span&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;&amp;nbsp;&lt;span style="color: #010001;"&gt;CWindowsProduct&lt;/span&gt;&amp;nbsp;:&amp;nbsp;&lt;span style="color: blue;"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="color: #010001;"&gt;COSProduct&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New'; color: blue;"&gt;public&lt;/span&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;:&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;virtual&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;void&lt;/span&gt;&amp;nbsp;&lt;span style="color: #010001;"&gt;Start&lt;/span&gt;()&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #010001;"&gt;cout&lt;/span&gt;&amp;nbsp;&amp;lt;&amp;lt;&amp;nbsp;&lt;span style="color: #a31515;"&gt;"Windows start."&lt;/span&gt;&amp;nbsp;&amp;lt;&amp;lt;&amp;nbsp;&lt;span style="color: #010001;"&gt;endl&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;};&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&amp;nbsp;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New'; color: blue;"&gt;class&lt;/span&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;&amp;nbsp;&lt;span style="color: #010001;"&gt;CLinuxProduct&lt;/span&gt;&amp;nbsp;:&amp;nbsp;&lt;span style="color: blue;"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="color: #010001;"&gt;COSProduct&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New'; color: blue;"&gt;public&lt;/span&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;:&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;virtual&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;void&lt;/span&gt;&amp;nbsp;&lt;span style="color: #010001;"&gt;Start&lt;/span&gt;()&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #010001;"&gt;cout&lt;/span&gt;&amp;nbsp;&amp;lt;&amp;lt;&amp;nbsp;&lt;span style="color: #a31515;"&gt;"Linux start."&lt;/span&gt;&amp;nbsp;&amp;lt;&amp;lt;&amp;nbsp;&lt;span style="color: #010001;"&gt;endl&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;};&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&amp;nbsp;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New'; color: green;"&gt;///////////////////&lt;/span&gt;&lt;span style="font-size: 9pt; font-family: 宋体; color: green;"&gt;工厂基类&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New'; color: blue;"&gt;class&lt;/span&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;&amp;nbsp;&lt;span style="color: #010001;"&gt;COSCreator&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New'; color: blue;"&gt;public&lt;/span&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;:&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ~&lt;span style="color: #010001;"&gt;COSCreator&lt;/span&gt;(){};&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 9pt; font-family: 宋体; color: green;"&gt;工厂方法。生产产品&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;virtual&lt;/span&gt;&amp;nbsp;&lt;span style="color: #010001;"&gt;COSProduct&lt;/span&gt;*&amp;nbsp;&lt;span style="color: #010001;"&gt;Create&lt;/span&gt;() = 0;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;};&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&amp;nbsp;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New'; color: green;"&gt;///////////////////&lt;/span&gt;&lt;span style="font-size: 9pt; font-family: 宋体; color: green;"&gt;具体工厂&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New'; color: blue;"&gt;class&lt;/span&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;&amp;nbsp;&lt;span style="color: #010001;"&gt;CWindowsCreator&lt;/span&gt;&amp;nbsp;:&amp;nbsp;&lt;span style="color: blue;"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="color: #010001;"&gt;COSCreator&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New'; color: blue;"&gt;public&lt;/span&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;:&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;virtual&lt;/span&gt;&amp;nbsp;&lt;span style="color: #010001;"&gt;COSProduct&lt;/span&gt;*&amp;nbsp;&lt;span style="color: #010001;"&gt;Create&lt;/span&gt;()&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #010001;"&gt;cout&lt;/span&gt;&amp;nbsp;&amp;lt;&amp;lt;&amp;nbsp;&lt;span style="color: #a31515;"&gt;"Create windows&amp;hellip;"&lt;/span&gt;&amp;nbsp;&amp;lt;&amp;lt;&amp;nbsp;&lt;span style="color: #010001;"&gt;endl&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;return&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;new&lt;/span&gt;&amp;nbsp;&lt;span style="color: #010001;"&gt;CWindowsProduct&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; };&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;};&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New'; color: blue;"&gt;class&lt;/span&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;&amp;nbsp;&lt;span style="color: #010001;"&gt;CLinuxCreator&lt;/span&gt;&amp;nbsp;:&amp;nbsp;&lt;span style="color: blue;"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="color: #010001;"&gt;COSCreator&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New'; color: blue;"&gt;public&lt;/span&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;:&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;virtual&lt;/span&gt;&amp;nbsp;&lt;span style="color: #010001;"&gt;COSProduct&lt;/span&gt;*&amp;nbsp;&lt;span style="color: #010001;"&gt;Create&lt;/span&gt;()&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #010001;"&gt;cout&lt;/span&gt;&amp;nbsp;&amp;lt;&amp;lt;&amp;nbsp;&lt;span style="color: #a31515;"&gt;"Create linux&amp;hellip;"&lt;/span&gt;&amp;nbsp;&amp;lt;&amp;lt;&amp;nbsp;&lt;span style="color: #010001;"&gt;endl&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;return&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;new&lt;/span&gt;&amp;nbsp;&lt;span style="color: #010001;"&gt;CLinuxProduct&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; };&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;};&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&amp;nbsp;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New'; color: green;"&gt;/////&lt;/span&gt;&lt;span style="font-size: 9pt; font-family: 宋体; color: green;"&gt;另一种具体工厂：使用模板避免创建多个具体工厂子类&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New'; color: blue;"&gt;template&lt;/span&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;&amp;lt;&lt;span style="color: blue;"&gt;typename&lt;/span&gt;&amp;nbsp;&lt;span style="color: #010001;"&gt;T&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New'; color: blue;"&gt;class&lt;/span&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;&amp;nbsp;&lt;span style="color: #010001;"&gt;CConcreteCreator&lt;/span&gt;&amp;nbsp;:&amp;nbsp;&lt;span style="color: blue;"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="color: #010001;"&gt;COSCreator&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New'; color: blue;"&gt;public&lt;/span&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;:&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #010001;"&gt;CConcreteCreator&lt;/span&gt;(&lt;span style="color: blue;"&gt;const&lt;/span&gt;&amp;nbsp;&lt;span style="color: #010001;"&gt;string&lt;/span&gt;&amp;nbsp;&lt;span style="color: #010001;"&gt;strProductType&lt;/span&gt;) :&amp;nbsp;&lt;span style="color: #010001;"&gt;m_strProductType&lt;/span&gt;(&lt;span style="color: #010001;"&gt;strProductType&lt;/span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {};&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&amp;nbsp;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;virtual&lt;/span&gt;&amp;nbsp;&lt;span style="color: #010001;"&gt;COSProduct&lt;/span&gt;*&amp;nbsp;&lt;span style="color: #010001;"&gt;Create&lt;/span&gt;()&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #010001;"&gt;cout&lt;/span&gt;&amp;nbsp;&amp;lt;&amp;lt;&amp;nbsp;&lt;span style="color: #a31515;"&gt;"ConcreteCreator. product type: "&lt;/span&gt;&amp;nbsp;&amp;lt;&amp;lt;&amp;nbsp;&lt;span style="color: #010001;"&gt;m_strProductType&lt;/span&gt;&amp;nbsp;&amp;lt;&amp;lt;&amp;nbsp;&lt;span style="color: #010001;"&gt;endl&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;return&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;new&lt;/span&gt;&amp;nbsp;&lt;span style="color: #010001;"&gt;T&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; };&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&amp;nbsp;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New'; color: blue;"&gt;protected&lt;/span&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;:&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #010001;"&gt;string&lt;/span&gt;&amp;nbsp;&lt;span style="color: #010001;"&gt;m_strProductType&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;};&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&amp;nbsp;&lt;/div&gt;&lt;div align="left"&gt;&amp;nbsp;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New'; color: blue;"&gt;int&lt;/span&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;&amp;nbsp;&lt;span style="color: #010001;"&gt;main&lt;/span&gt;()&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #010001;"&gt;COSCreator&lt;/span&gt;*&amp;nbsp;&lt;span style="color: #010001;"&gt;pCreator&lt;/span&gt;&amp;nbsp;=&amp;nbsp;&lt;span style="color: #010001;"&gt;NULL&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #010001;"&gt;COSProduct&lt;/span&gt;&amp;nbsp;*&lt;span style="color: #010001;"&gt;pProduct&lt;/span&gt;&amp;nbsp;=&amp;nbsp;&lt;span style="color: #010001;"&gt;NULL&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&amp;nbsp;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #010001;"&gt;pCreator&lt;/span&gt;&amp;nbsp;=&amp;nbsp;&lt;span style="color: blue;"&gt;new&lt;/span&gt;&amp;nbsp;&lt;span style="color: #010001;"&gt;CWindowsCreator&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #010001;"&gt;pProduct&lt;/span&gt;&amp;nbsp;=&amp;nbsp;&lt;span style="color: #010001;"&gt;pCreator&lt;/span&gt;-&amp;gt;&lt;span style="color: #010001;"&gt;Create&lt;/span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #010001;"&gt;pProduct&lt;/span&gt;-&amp;gt;&lt;span style="color: #010001;"&gt;Start&lt;/span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;delete&lt;/span&gt;&amp;nbsp;&lt;span style="color: #010001;"&gt;pProduct&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;delete&lt;/span&gt;&amp;nbsp;&lt;span style="color: #010001;"&gt;pCreator&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&amp;nbsp;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #010001;"&gt;pCreator&lt;/span&gt;&amp;nbsp;=&amp;nbsp;&lt;span style="color: blue;"&gt;new&lt;/span&gt;&amp;nbsp;&lt;span style="color: #010001;"&gt;CLinuxCreator&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #010001;"&gt;pProduct&lt;/span&gt;&amp;nbsp;=&amp;nbsp;&lt;span style="color: #010001;"&gt;pCreator&lt;/span&gt;-&amp;gt;&lt;span style="color: #010001;"&gt;Create&lt;/span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #010001;"&gt;pProduct&lt;/span&gt;-&amp;gt;&lt;span style="color: #010001;"&gt;Start&lt;/span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;delete&lt;/span&gt;&amp;nbsp;&lt;span style="color: #010001;"&gt;pProduct&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;delete&lt;/span&gt;&amp;nbsp;&lt;span style="color: #010001;"&gt;pCreator&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&amp;nbsp;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 9pt; font-family: 宋体; color: green;"&gt;另一种实现具体工厂方式：使用模板避免创建子类&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #010001;"&gt;CConcreteCreator&lt;/span&gt;&amp;lt;&lt;span style="color: #010001;"&gt;CWindowsProduct&lt;/span&gt;&amp;gt;&amp;nbsp;&lt;span style="color: #010001;"&gt;windowsCreator&lt;/span&gt;(&lt;span style="color: #a31515;"&gt;"windows"&lt;/span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #010001;"&gt;pProduct&lt;/span&gt;&amp;nbsp;=&amp;nbsp;&lt;span style="color: #010001;"&gt;windowsCreator&lt;/span&gt;.&lt;span style="color: #010001;"&gt;Create&lt;/span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #010001;"&gt;pProduct&lt;/span&gt;-&amp;gt;&lt;span style="color: #010001;"&gt;Start&lt;/span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;delete&lt;/span&gt;&amp;nbsp;&lt;span style="color: #010001;"&gt;pProduct&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&amp;nbsp;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #010001;"&gt;CConcreteCreator&lt;/span&gt;&amp;lt;&lt;span style="color: #010001;"&gt;CLinuxProduct&lt;/span&gt;&amp;gt;&amp;nbsp;&lt;span style="color: #010001;"&gt;linuxCreator&lt;/span&gt;(&lt;span style="color: #a31515;"&gt;"linux"&lt;/span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #010001;"&gt;pProduct&lt;/span&gt;&amp;nbsp;=&amp;nbsp;&lt;span style="color: #010001;"&gt;linuxCreator&lt;/span&gt;.&lt;span style="color: #010001;"&gt;Create&lt;/span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #010001;"&gt;pProduct&lt;/span&gt;-&amp;gt;&lt;span style="color: #010001;"&gt;Start&lt;/span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;delete&lt;/span&gt;&amp;nbsp;&lt;span style="color: #010001;"&gt;pProduct&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&amp;nbsp;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #010001;"&gt;system&lt;/span&gt;(&lt;span style="color: #a31515;"&gt;"pause"&lt;/span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;return&lt;/span&gt;&amp;nbsp;0;&lt;/span&gt;&lt;/div&gt;&lt;div style="line-height: 22px;"&gt;&lt;span style="font-size: 9pt; line-height: 18px; font-family: 'Courier New';"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div style="border-top-style: none; border-right-style: none; border-bottom-style: double; border-left-style: none; border-top-width: medium; border-right-width: medium; border-bottom-width: 2.25pt; border-left-width: medium; padding-top: 0cm; padding-right: 0cm; padding-bottom: 1pt; padding-left: 0cm;"&gt;&lt;div style="border-color: initial; line-height: 22px; border-width: medium; border-style: none; padding: 0cm;"&gt;&amp;nbsp;&lt;/div&gt;&lt;div style="border-color: initial; line-height: 22px; border-width: medium; border-style: none; padding: 0cm;"&gt;&lt;span style="font-size: 9pt; line-height: 18px; font-family: 宋体;"&gt;输出：&lt;/span&gt;&lt;/div&gt;&lt;div style="border-color: initial; line-height: 22px; border-width: medium; border-style: none; padding: 0cm;"&gt;&lt;span style="font-size: 9pt; line-height: 18px; font-family: 'Courier New';"&gt;Create windows&amp;hellip;&lt;/span&gt;&lt;/div&gt;&lt;div style="border-color: initial; line-height: 22px; border-width: medium; border-style: none; padding: 0cm;"&gt;&lt;span style="font-size: 9pt; line-height: 18px; font-family: 'Courier New';"&gt;Windows start.&lt;/span&gt;&lt;/div&gt;&lt;div style="border-color: initial; line-height: 22px; border-width: medium; border-style: none; padding: 0cm;"&gt;&lt;span style="font-size: 9pt; line-height: 18px; font-family: 'Courier New';"&gt;Create linux&amp;hellip;&lt;/span&gt;&lt;/div&gt;&lt;div style="border-color: initial; line-height: 22px; border-width: medium; border-style: none; padding: 0cm;"&gt;&lt;span style="font-size: 9pt; line-height: 18px; font-family: 'Courier New';"&gt;Linux start.&lt;/span&gt;&lt;/div&gt;&lt;div style="border-color: initial; line-height: 22px; border-width: medium; border-style: none; padding: 0cm;"&gt;&lt;span style="font-size: 9pt; line-height: 18px; font-family: 'Courier New';"&gt;ConcreteCreator. product type: windows&lt;/span&gt;&lt;/div&gt;&lt;div style="border-color: initial; line-height: 22px; border-width: medium; border-style: none; padding: 0cm;"&gt;&lt;span style="font-size: 9pt; line-height: 18px; font-family: 'Courier New';"&gt;Windows start.&lt;/span&gt;&lt;/div&gt;&lt;div style="border-color: initial; line-height: 22px; border-width: medium; border-style: none; padding: 0cm;"&gt;&lt;span style="font-size: 9pt; line-height: 18px; font-family: 'Courier New';"&gt;ConcreteCreator. product type: linux&lt;/span&gt;&lt;/div&gt;&lt;div style="border-color: initial; line-height: 22px; border-width: medium; border-style: none; padding: 0cm;"&gt;&lt;span style="font-size: 9pt; line-height: 18px; font-family: 'Courier New';"&gt;Linux start.&lt;/span&gt;&lt;/div&gt;&lt;div style="border-color: initial; line-height: 22px; border-width: medium; border-style: none; padding: 0cm;"&gt;&amp;nbsp;&lt;/div&gt;&lt;/div&gt;&lt;img src="http://www.cnblogs.com/buffer/aggbug/2169287.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/buffer/archive/2011/09/06/2169287.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/buffer/archive/2011/09/06/2169285.html</id><title type="text">C++设计模式(转载)</title><summary type="text">C++设计模式之Adapter一、功能 将一个类的接口转换成客户希望的另外一个接口，解决两个已有接口之间不匹配的问题。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。 二、结构图 (1)class adapter (2)object adapter 三、实现 和其他很多模式一样，学习设计模式的重点是学习每种模式的思 想，而不应拘泥于它的某种具体结构图和实现。因为模式是灵活的，其实现可以是千变万化的，只是所谓万变不离其宗。 在STL中大量运用了Adapter模式，象function adapter、iterator adpter，它们与这里说的adapte...</summary><published>2011-09-06T15:04:00Z</published><updated>2011-09-06T15:04:00Z</updated><author><name>牛司朋</name><uri>http://www.cnblogs.com/buffer/</uri></author><link rel="alternate" href="http://www.cnblogs.com/buffer/archive/2011/09/06/2169285.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/buffer/archive/2011/09/06/2169285.html"/><content type="html">&lt;div id="cnblogs_post_body"&gt;&lt;a href="http://blog.csdn.net/i_like_cpp/archive/2004/11/29/197760.aspx" style="color: #1a8bc8; text-decoration: none;"&gt;C++设计模式之Adapter&lt;/a&gt;&lt;br /&gt;&lt;strong&gt;一、功能&lt;/strong&gt;&amp;nbsp;将一个类的接口转换成客户希望的另外一个接口，解决两个已有接口之间不匹配的问题。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。&lt;p class="title" style="line-height: 19px; margin-top: 5px; margin-right: auto; margin-bottom: 5px; margin-left: auto; text-indent: 0px;"&gt;&lt;b&gt;二、结构图&lt;/b&gt;&lt;/p&gt;(1)class adapter&amp;nbsp;&lt;br /&gt;&lt;p align="center" style="line-height: 19px; margin-top: 5px; margin-right: auto; margin-bottom: 5px; margin-left: auto; text-indent: 0px;"&gt;&lt;img src="http://www.yesky.com/20020725/fangz20725_3.gif" height="197" width="543" style="border-style: initial; border-color: initial; border-width: 0px;" /&gt;&lt;/p&gt;&lt;p&gt;(2)object adapter&lt;/p&gt;&lt;p align="center" style="line-height: 19px; margin-top: 5px; margin-right: auto; margin-bottom: 5px; margin-left: auto; text-indent: 0px;"&gt;&lt;img src="http://www.yesky.com/20020725/fangz20725_4.gif" height="197" width="524" style="border-style: initial; border-color: initial; border-width: 0px;" /&gt;&lt;/p&gt;&lt;p class="title" style="line-height: 19px; margin-top: 5px; margin-right: auto; margin-bottom: 5px; margin-left: auto; text-indent: 0px;"&gt;　&amp;nbsp;&amp;nbsp;&amp;nbsp; 三&lt;b&gt;、实现&lt;/b&gt;&lt;/p&gt;和其他很多模式一样，学习设计模式的重点是学习每种模式的思 想，而不应拘泥于它的某种具体结构图和实现。因为模式是灵活的，其实现可以是千变万化的，只是所谓万变不离其宗。 在STL中大量运用了Adapter模式，象function adapter、iterator adpter，它们与这里说的adapter结构并不一样，但思想是一样的。具体的介绍可到侯捷网站上找相关文章，他讲得非常好。&lt;p class="title" style="line-height: 19px; margin-top: 5px; margin-right: auto; margin-bottom: 5px; margin-left: auto; text-indent: 0px;"&gt;&lt;b&gt;四、示例代码&lt;/b&gt;&lt;/p&gt;(1)class adapter&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;table bgcolor="#ffffff" border="0" cellpadding="0" cellspacing="0" style="width: 600px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="font-size: 12px; color: #454545; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"&gt;&lt;p&gt;namespace DesignPattern_Adapter&lt;br /&gt;{&lt;br /&gt;// class Adaptee&lt;br /&gt;class Adaptee&lt;br /&gt;{&lt;br /&gt;public:&lt;br /&gt;void SpecialRequest() {}&lt;br /&gt;} ;&lt;/p&gt;&lt;p&gt;// class Target&lt;br /&gt;class Target&lt;br /&gt;{&lt;br /&gt;public:&lt;br /&gt;virtual void Request() = 0 ;&lt;br /&gt;} ;&lt;/p&gt;&lt;p&gt;// class Adapter&lt;br /&gt;class Adapter : public Target, private Adaptee&lt;br /&gt;{&lt;br /&gt;public:&lt;br /&gt;virtual void Request() { SpecialRequest() ; }&lt;br /&gt;} ;&lt;br /&gt;}&lt;/p&gt;&lt;p&gt;客户端代码：&lt;br /&gt;{&lt;br /&gt;using namespace DesignPattern_Adapter ;&lt;br /&gt;Target *p = new Adapter() ;&lt;br /&gt;p-&amp;gt;Request() ; //实际上调用的是Adaptee::SpecialRequest()&lt;br /&gt;}&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;(2)object adapter namespace DesignPattern_Adapter&lt;/p&gt;&lt;table bgcolor="#ffffff" border="0" cellpadding="0" cellspacing="0" style="width: 600px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="font-size: 12px; color: #454545; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"&gt;&lt;p&gt;{&lt;br /&gt;// class Adaptee&lt;br /&gt;class Adaptee&lt;br /&gt;{&lt;br /&gt;public:&lt;br /&gt;void SpecialRequest() {}&lt;br /&gt;} ;&lt;/p&gt;&lt;p&gt;// class Target&lt;br /&gt;class Target&lt;br /&gt;{&lt;br /&gt;public:&lt;br /&gt;virtual void Request() = 0 ;&lt;br /&gt;} ;&lt;/p&gt;&lt;p&gt;// class Adapter&lt;br /&gt;class Adapter : public Target&lt;br /&gt;{&lt;br /&gt;public:&lt;br /&gt;virtual void Request() { _adaptee.SpecialRequest() ; }&lt;br /&gt;private:&lt;br /&gt;Adaptee _adaptee ;&lt;br /&gt;} ;&lt;br /&gt;}&lt;/p&gt;&lt;p&gt;客户端代码：&lt;br /&gt;{&lt;br /&gt;using namespace DesignPattern_Adapter ;&lt;br /&gt;Target *p = new Adapter() ;&lt;br /&gt;p-&amp;gt;Request() ; //实际上调用的是Adaptee::SpecialRequest()&lt;br /&gt;}&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;b&gt;六、实例&lt;/b&gt;&lt;/p&gt;(1)STL中的Class Adapter&amp;nbsp;&lt;br /&gt;&lt;br /&gt;STL中的Adapter Class包括：a.stack(对应的adaptee是deque)。b.queue(对应的adaptee是deque)。 c.priority_queue(对应的adaptee是vector)。 下面是从VC中的&amp;lt; stack &amp;gt;拷出的stack的类定义：&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;table bgcolor="#ffffff" border="0" cellpadding="0" cellspacing="0" style="width: 600px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="font-size: 12px; color: #454545; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"&gt;&lt;p&gt;template&lt;class _ty=""&gt;&lt;br /&gt;class _Container = deque&amp;lt;_Ty&amp;gt; &amp;gt;&lt;br /&gt;class stack&lt;br /&gt;{ // LIFO queue implemented with a container&lt;br /&gt;public:&lt;br /&gt;typedef _Container container_type;&lt;br /&gt;typedef typename _Container::value_type value_type;&lt;br /&gt;typedef typename _Container::size_type size_type;&lt;/class&gt;&lt;/p&gt;&lt;p&gt;stack()&lt;br /&gt;: c()&lt;br /&gt;{ // construct with empty container&lt;br /&gt;}&lt;/p&gt;&lt;p&gt;explicit stack(const _Container&amp;amp; _Cont)&lt;br /&gt;: c(_Cont)&lt;br /&gt;{ // construct by copying specified container&lt;br /&gt;}&lt;/p&gt;&lt;p&gt;bool empty() const&lt;br /&gt;{ // test if stack is empty&lt;br /&gt;return (c.empty());&lt;br /&gt;}&lt;/p&gt;&lt;p&gt;size_type size() const&lt;br /&gt;{ // test length of stack&lt;br /&gt;return (c.size());&lt;br /&gt;}&lt;/p&gt;&lt;p&gt;value_type&amp;amp; top()&lt;br /&gt;{ // return last element of mutable stack&lt;br /&gt;return (c.back());&lt;br /&gt;}&lt;/p&gt;&lt;p&gt;const value_type&amp;amp; top() const&lt;br /&gt;{ // return last element of nonmutable stack&lt;br /&gt;return (c.back());&lt;br /&gt;}&lt;/p&gt;&lt;p&gt;void push(const value_type&amp;amp; _Val)&lt;br /&gt;{ // insert element at end&lt;br /&gt;c.push_back(_Val);&lt;br /&gt;}&lt;/p&gt;&lt;p&gt;void pop()&lt;br /&gt;{ // erase last element&lt;br /&gt;c.pop_back();&lt;br /&gt;}&lt;/p&gt;&lt;p&gt;bool _Eq(const stack&amp;lt;_Ty, _Container&amp;gt;&amp;amp; _Right) const&lt;br /&gt;{ // test for stack equality&lt;br /&gt;return (c == _Right.c);&lt;br /&gt;}&lt;/p&gt;&lt;p&gt;bool _Lt(const stack&amp;lt;_Ty, _Container&amp;gt;&amp;amp; _Right) const&lt;br /&gt;{ // test if this &amp;lt; _Right for stacks&lt;br /&gt;return (c &amp;lt; _Right.c);&lt;br /&gt;}&lt;/p&gt;&lt;p&gt;protected:&lt;br /&gt;_Container c; // the underlying container&lt;br /&gt;};&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;关键之处在于&lt;b&gt;_Container c&lt;/b&gt;，stack所有的操作都转交给c去处理了。(这实际上就是前面所说的"object adapter"，注意STL中的class adapter与上面所说的class adapter概念不完全一致)&amp;nbsp;&lt;br /&gt;stack的使用方法很简单，如下：&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;table bgcolor="#ffffff" border="0" cellpadding="0" cellspacing="0" style="width: 600px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="font-size: 12px; color: #454545; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"&gt;{&lt;br /&gt;int ia[] = { 1,3,2,4 };&lt;br /&gt;deque&lt;int&gt;&amp;nbsp;id(ia, ia+4);&lt;br /&gt;stack&lt;int&gt;&amp;nbsp;is(id);&lt;br /&gt;}&lt;/int&gt;&lt;/int&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;(2)近日看了一篇文章&amp;ldquo;Generic&amp;lt; Programming &amp;gt;：简化异常安全代码&amp;rdquo;，原文出自http://www.cuj.com/experts/1812/alexandr.htm?topic= experts， 中文译文出自"C++ View第5期"。 文章绝对一流，作者给出的代码中也使用了Adaptor模式，也有一定代表性。我将其问题一般化，概括出以下示例：&lt;/p&gt;&lt;p&gt;&lt;b&gt;问题&lt;/b&gt;：假设有几个已有类，他们有某些共同的行为，但它们彼此间是独立的(没有共同的基类)。如：&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;table bgcolor="#ffffff" border="0" cellpadding="0" cellspacing="0" style="width: 600px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="font-size: 12px; color: #454545; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"&gt;&lt;p&gt;class T1&lt;br /&gt;{&lt;br /&gt;public:&lt;br /&gt;void Proc() {}&lt;br /&gt;} ;&lt;/p&gt;&lt;p&gt;class T2&lt;br /&gt;{&lt;br /&gt;public:&lt;br /&gt;void Proc() {}&lt;br /&gt;} ;&lt;/p&gt;&lt;p&gt;// ...&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;b&gt;&lt;/b&gt;如何以统一的方式去调用这些行为呢？&lt;/p&gt;&lt;p&gt;&lt;b&gt;解决方法1&lt;/b&gt;：很自然的会想到用模板，如：&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;table bgcolor="#ffffff" border="0" cellpadding="0" cellspacing="0" style="width: 600px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="font-size: 12px; color: #454545; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"&gt;&lt;span color="blue" style="color: blue;"&gt;template&lt;/span&gt;&amp;nbsp;&amp;lt;&lt;span color="blue" style="color: blue;"&gt;class&lt;/span&gt;&amp;nbsp;T&amp;gt;&lt;br /&gt;&lt;span color="blue" style="color: blue;"&gt;void&lt;/span&gt;&amp;nbsp;Test(T t)&lt;br /&gt;{&lt;br /&gt;t.Proc() ;&lt;br /&gt;}&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;的确不错，但这只适用于简单的情况，有时情况是很复杂的，比如我们无法把类型放到模板参数中！&lt;/p&gt;&lt;p&gt;&lt;b&gt;解决方法2&lt;/b&gt;：困难来自于这些类没有共同的基类，所以我们就创造一个基类，然后再Adapt。&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;table bgcolor="#ffffff" border="0" cellpadding="0" cellspacing="0" style="width: 600px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="font-size: 12px; color: #454545; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"&gt;&lt;span color="green" style="color: green;"&gt;// class IAdaptor，抽象基类&lt;/span&gt;&lt;br /&gt;&lt;span color="blue" style="color: blue;"&gt;class&lt;/span&gt;&amp;nbsp;IAdaptor&lt;br /&gt;{&lt;br /&gt;&lt;span color="blue" style="color: blue;"&gt;public&lt;/span&gt;:&lt;br /&gt;&lt;span color="blue" style="color: blue;"&gt;virtual&lt;/span&gt;&amp;nbsp;&lt;span color="blue" style="color: blue;"&gt;void&lt;/span&gt;&amp;nbsp;Proc() = 0 ;&lt;br /&gt;} ;&amp;nbsp;&lt;br /&gt;&lt;span color="green" style="color: green;"&gt;// class Adaptor&lt;/span&gt;&lt;br /&gt;&lt;span color="blue" style="color: blue;"&gt;template&lt;/span&gt;&amp;nbsp;&amp;lt;&lt;span color="blue" style="color: blue;"&gt;class&lt;/span&gt;&amp;nbsp;T&amp;gt;&lt;br /&gt;&lt;span color="blue" style="color: blue;"&gt;class&lt;/span&gt;&amp;nbsp;Adaptor :&amp;nbsp;&lt;span color="blue" style="color: blue;"&gt;public&lt;/span&gt;&amp;nbsp;IAdaptor,&amp;nbsp;&lt;span color="blue" style="color: blue;"&gt;private&lt;/span&gt;&amp;nbsp;T&amp;nbsp;&lt;span color="green" style="color: green;"&gt;//实现继承&lt;/span&gt;&lt;br /&gt;{&lt;br /&gt;&lt;span color="blue" style="color: blue;"&gt;public&lt;/span&gt;:&lt;br /&gt;&lt;span color="blue" style="color: blue;"&gt;virtual&lt;/span&gt;&amp;nbsp;&lt;span color="blue" style="color: blue;"&gt;void&lt;/span&gt;&amp;nbsp;Proc() { T::Proc() ; }&lt;br /&gt;} ;&lt;br /&gt;&lt;span color="green" style="color: green;"&gt;// 以统一方式调用函数Proc，而不关心是T1、T2或其他什么类&lt;/span&gt;&lt;br /&gt;&lt;span color="blue" style="color: blue;"&gt;void&lt;/span&gt;&amp;nbsp;Test(&lt;span color="blue" style="color: blue;"&gt;const&lt;/span&gt;&amp;nbsp;std::auto_ptr&lt;iadaptor&gt;&amp;amp; sp)&lt;br /&gt;{&lt;br /&gt;sp-&amp;gt;Proc() ;&lt;br /&gt;}&lt;br /&gt;客户端代码：&lt;br /&gt;Test(std::auto_ptr&lt;iadaptor&gt;(&lt;span color="blue" style="color: blue;"&gt;new&lt;/span&gt;&amp;nbsp;Adaptor&lt;t1&gt;)) ;&lt;br /&gt;Test(std::auto_ptr&lt;iadaptor&gt;(&lt;span color="blue" style="color: blue;"&gt;new&lt;/span&gt;&amp;nbsp;Adaptor&lt;t2&gt;)) ;&lt;/t2&gt;&lt;/iadaptor&gt;&lt;/t1&gt;&lt;/iadaptor&gt;&lt;/iadaptor&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;上例很简单，用方法一中的模板函数就可以很好地解决了。下面是一个略微复杂一点的例子，根据参数类型来创建适当的对象：&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;table bgcolor="#ffffff" border="0" cellpadding="0" cellspacing="0" style="width: 600px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="font-size: 12px; color: #454545; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"&gt;&lt;p&gt;class T1&lt;br /&gt;{&lt;br /&gt;public:&lt;br /&gt;T1(int) { /*...*/ }&lt;br /&gt;void Proc() { /*...*/ }&lt;br /&gt;} ;&lt;/p&gt;&lt;p&gt;class T2&lt;br /&gt;{&lt;br /&gt;public:&lt;br /&gt;T2(char) { /*...*/ }&lt;br /&gt;void Proc() { /*...*/ }&lt;br /&gt;} ;&lt;/p&gt;&lt;p&gt;// class IAdaptor，抽象基类&lt;br /&gt;class IAdaptor&lt;br /&gt;{&lt;br /&gt;public:&lt;br /&gt;virtual void Proc() = 0 ;&lt;br /&gt;} ;&lt;/p&gt;&lt;p&gt;// class Adaptor&lt;br /&gt;template&amp;nbsp;&lt;class t=""&gt;&lt;br /&gt;class Adaptor : public IAdaptor, private T //实现继承&lt;br /&gt;{&lt;br /&gt;public:&lt;br /&gt;Adaptor(int n) : T(n) {}&lt;br /&gt;Adaptor(char c) : T(c) {}&lt;br /&gt;virtual void Proc() { T::Proc() ; }&lt;br /&gt;} ;&lt;/class&gt;&lt;/p&gt;&lt;p&gt;class Test&lt;br /&gt;{&lt;br /&gt;public:&lt;br /&gt;Test(int n) : sp(new Adaptor&lt;t1&gt;(n)) {}&lt;br /&gt;Test(char c) : sp(new Adaptor&lt;t2&gt;(c)) {}&lt;/t2&gt;&lt;/t1&gt;&lt;/p&gt;&lt;p&gt;void Proc() { sp-&amp;gt;Proc() ; }&lt;br /&gt;private:&lt;br /&gt;std::auto_ptr&lt;iadaptor&gt;&amp;nbsp;sp ;&lt;br /&gt;} ;&lt;/iadaptor&gt;&lt;/p&gt;&lt;p&gt;客户端代码：&lt;br /&gt;Test t1(10) ;&lt;br /&gt;t1.Proc() ;&lt;/p&gt;&lt;p&gt;Test t2('c') ;&lt;br /&gt;t2.Proc() ;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;上面是示例而非实例，你也许更愿意看看它实际的运用。去下载作者所写的代码，好好欣赏一下吧。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;table border="0" cellpadding="0" cellspacing="2" style="width: 550px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align="center" style="font-size: 12px; color: #454545; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"&gt;&lt;b&gt;&lt;span color="#333399" style="color: #333399;"&gt;C++设计模式之Abstract Factory&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td bgcolor="#bbbbbb" height="1" style="font-size: 12px; color: #454545; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="center" style="font-size: 12px; color: #454545; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"&gt;&lt;span face="Arial, Helvetica, sans-serif" style="font-family: Arial, Helvetica, sans-serif;"&gt;2002-07-23&amp;middot; &amp;middot; &amp;middot;&amp;middot;COM集中营&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="font-size: 12px; color: #454545; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"&gt;&lt;b&gt;一、功能&lt;/b&gt;&amp;nbsp;&lt;br /&gt;提供一个创建一系列相关或相互依赖对象的接口，而无需指定它们具体的类。&lt;p&gt;&lt;b&gt;二、结构图&lt;/b&gt;&lt;/p&gt;类厂最基本的结构示意图如下：&lt;p align="center" style="line-height: 18px; margin-top: 5px; margin-right: auto; margin-bottom: 5px; margin-left: auto; text-indent: 0px;"&gt;&lt;img src="http://www.yesky.com/20020715/fangz20715_2.gif" style="border-style: initial; border-color: initial; width: 300px; cursor: pointer; border-width: 0px;" /&gt;&lt;/p&gt;&lt;p&gt;在实际应用中，类厂模式可以扩充到很复杂的情况，如下图所示：&lt;/p&gt;&lt;p align="center" style="line-height: 18px; margin-top: 5px; margin-right: auto; margin-bottom: 5px; margin-left: auto; text-indent: 0px;"&gt;&lt;img src="http://www.yesky.com/20020715/fangz20715_3.gif" style="border-style: initial; border-color: initial; width: 300px; cursor: pointer; border-width: 0px;" /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;三、优缺点&lt;/b&gt;&lt;/p&gt;&lt;p&gt;优点：(1)封装&lt;span color="red" style="color: red;"&gt;创建过程&lt;/span&gt;。客户不用知道类厂是如何创建类实例的，类厂封闭了所有创建的细节。这样可选择不同的创建方法，增加了灵活性。 (2)将客户与具体类&lt;span color="red" style="color: red;"&gt;隔离&lt;/span&gt;，提高了各自的可重用性。&amp;nbsp;&lt;br /&gt;缺点：Factory类层次与具体类层次通常是平行的(即一一对应的)。增加一个具体类，一般也要相应地增加一个factory类，增加了系统复杂度。&lt;/p&gt;&lt;p&gt;&lt;b&gt;四、实现&lt;/b&gt;&lt;/p&gt;(1)Abstract Factory类中通常是一组Factory Method的集合。个人认为与Factory Method模式没有本质区别。&amp;nbsp;&lt;br /&gt;&lt;br /&gt;(2)通常可以把工厂作为单件。&lt;p&gt;&lt;b&gt;五、示例代码&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;span color="blue" style="color: blue;"&gt;namespace&lt;/span&gt;&amp;nbsp;DesignPattern_AbstractFactory&lt;br /&gt;&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;&lt;span color="blue" style="color: blue;"&gt;class&lt;/span&gt;&amp;nbsp;AbstractProductA {};&amp;nbsp;&lt;span color="green" style="color: green;"&gt;// Product A&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span color="blue" style="color: blue;"&gt;class&lt;/span&gt;&amp;nbsp;ProductA1 :&amp;nbsp;&lt;span color="blue" style="color: blue;"&gt;public&lt;/span&gt;&amp;nbsp;AbstractProductA {};&lt;br /&gt;&lt;br /&gt;&lt;span color="blue" style="color: blue;"&gt;class&lt;/span&gt;&amp;nbsp;ProductA2 :&amp;nbsp;&lt;span color="blue" style="color: blue;"&gt;public&lt;/span&gt;&amp;nbsp;AbstractProductA {};&lt;br /&gt;&lt;br /&gt;&lt;span color="blue" style="color: blue;"&gt;class&lt;/span&gt;&amp;nbsp;AbstractProductB {};&amp;nbsp;&lt;span color="green" style="color: green;"&gt;// Product B&lt;/span&gt;&lt;br /&gt;&lt;span color="blue" style="color: blue;"&gt;class&lt;/span&gt;&amp;nbsp;ProductB1 :&amp;nbsp;&lt;span color="blue" style="color: blue;"&gt;public&lt;/span&gt;&amp;nbsp;AbstractProductB {};&lt;br /&gt;&lt;span color="blue" style="color: blue;"&gt;class&lt;/span&gt;&amp;nbsp;ProductB2 :&amp;nbsp;&lt;span color="blue" style="color: blue;"&gt;public&lt;/span&gt;&amp;nbsp;AbstractProductB {};&lt;br /&gt;&lt;span color="blue" style="color: blue;"&gt;class&lt;/span&gt;&amp;nbsp;AbstractFactory&lt;br /&gt;{&lt;br /&gt;&lt;span color="blue" style="color: blue;"&gt;public&lt;/span&gt;:&lt;br /&gt;&lt;span color="blue" style="color: blue;"&gt;virtual&lt;/span&gt;&amp;nbsp;AbstractProductA* CreateProductA() = 0 ;&lt;span color="green" style="color: green;"&gt;// 创建ProductA&lt;/span&gt;&lt;br /&gt;&lt;span color="blue" style="color: blue;"&gt;virtual&lt;/span&gt;&amp;nbsp;AbstractProductB* CreateProductB() = 0 ;&lt;span color="green" style="color: green;"&gt;// 创建ProductB&lt;/span&gt;&lt;br /&gt;} ;&lt;br /&gt;&lt;span color="blue" style="color: blue;"&gt;class&lt;/span&gt;&amp;nbsp;ConcreteFactory1 :&amp;nbsp;&lt;span color="blue" style="color: blue;"&gt;public&lt;/span&gt;&amp;nbsp;AbstractFactory&lt;br /&gt;{&lt;br /&gt;&lt;span color="blue" style="color: blue;"&gt;public&lt;/span&gt;:&lt;br /&gt;&lt;span color="blue" style="color: blue;"&gt;virtual&lt;/span&gt;&amp;nbsp;AbstractProductA* CreateProductA() {&amp;nbsp;&lt;span color="blue" style="color: blue;"&gt;return&lt;/span&gt;&amp;nbsp;&lt;span color="blue" style="color: blue;"&gt;new&lt;/span&gt;&amp;nbsp;ProductA1() ; }&lt;br /&gt;&lt;span color="blue" style="color: blue;"&gt;virtual&lt;/span&gt;&amp;nbsp;AbstractProductB* CreateProductB() {&amp;nbsp;&lt;span color="blue" style="color: blue;"&gt;return&lt;/span&gt;&amp;nbsp;&lt;span color="blue" style="color: blue;"&gt;new&lt;/span&gt;&amp;nbsp;ProductB1() ; }&lt;br /&gt;&lt;span color="blue" style="color: blue;"&gt;static&lt;/span&gt;&amp;nbsp;ConcreteFactory1* Instance() {&amp;nbsp;&lt;span color="blue" style="color: blue;"&gt;static&lt;/span&gt;&amp;nbsp;ConcreteFactory1 instance ;&lt;span color="blue" style="color: blue;"&gt;return&lt;/span&gt;&amp;nbsp;&amp;amp;instance ; } &lt;br /&gt;&lt;span color="blue" style="color: blue;"&gt;protected&lt;/span&gt;:&lt;br /&gt;ConcreteFactory1() {}&lt;br /&gt;&lt;span color="blue" style="color: blue;"&gt;private&lt;/span&gt;:&lt;br /&gt;ConcreteFactory1(&lt;span color="blue" style="color: blue;"&gt;const&lt;/span&gt;&amp;nbsp;ConcreteFactory1&amp;amp;) ;&lt;br /&gt;ConcreteFactory1&amp;amp;&amp;nbsp;&lt;span color="blue" style="color: blue;"&gt;operator&lt;/span&gt;=(&lt;span color="blue" style="color: blue;"&gt;const&lt;/span&gt;&amp;nbsp;ConcreteFactory1&amp;amp;) ;&lt;br /&gt;} ;&lt;br /&gt;&lt;span color="blue" style="color: blue;"&gt;class&lt;/span&gt;&amp;nbsp;ConcreteFactory2 :&amp;nbsp;&lt;span color="blue" style="color: blue;"&gt;public&lt;/span&gt;&amp;nbsp;AbstractFactory&lt;br /&gt;{&lt;br /&gt;&lt;span color="blue" style="color: blue;"&gt;public&lt;/span&gt;:&lt;br /&gt;&lt;span color="blue" style="color: blue;"&gt;virtual&lt;/span&gt;&amp;nbsp;AbstractProductA* CreateProductA() {&amp;nbsp;&lt;span color="blue" style="color: blue;"&gt;return&lt;/span&gt;&amp;nbsp;&lt;span color="blue" style="color: blue;"&gt;new&lt;/span&gt;&amp;nbsp;ProductA2() ; }&lt;br /&gt;&lt;span color="blue" style="color: blue;"&gt;virtual&lt;/span&gt;&amp;nbsp;AbstractProductB* CreateProductB() {&amp;nbsp;&lt;span color="blue" style="color: blue;"&gt;return&lt;/span&gt;&amp;nbsp;&lt;span color="blue" style="color: blue;"&gt;new&lt;/span&gt;&amp;nbsp;ProductB2() ; }&lt;br /&gt;&lt;span color="blue" style="color: blue;"&gt;static&lt;/span&gt;&amp;nbsp;ConcreteFactory2* Instance() {&amp;nbsp;&lt;span color="blue" style="color: blue;"&gt;static&lt;/span&gt;&amp;nbsp;ConcreteFactory2 instance ;&lt;span color="blue" style="color: blue;"&gt;return&lt;/span&gt;&amp;nbsp;&amp;amp;instance ; }&amp;nbsp;&lt;br /&gt;&lt;span color="blue" style="color: blue;"&gt;protected&lt;/span&gt;:&lt;br /&gt;ConcreteFactory2() {}&lt;br /&gt;&lt;span color="blue" style="color: blue;"&gt;private&lt;/span&gt;:&lt;br /&gt;ConcreteFactory2(&lt;span color="blue" style="color: blue;"&gt;const&lt;/span&gt;&amp;nbsp;ConcreteFactory2&amp;amp;) ;&lt;br /&gt;ConcreteFactory2&amp;amp;&amp;nbsp;&lt;span color="blue" style="color: blue;"&gt;operator&lt;/span&gt;=(&lt;span color="blue" style="color: blue;"&gt;const&lt;/span&gt;&amp;nbsp;ConcreteFactory2&amp;amp;) ;&lt;br /&gt;} ;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;客户端代码：&lt;br /&gt;&lt;br /&gt;{&lt;br /&gt;&lt;span color="blue" style="color: blue;"&gt;using&lt;/span&gt;&amp;nbsp;&lt;span color="blue" style="color: blue;"&gt;namespace&lt;/span&gt;&amp;nbsp;DesignPattern_AbstractFactory ;&lt;br /&gt;&lt;span color="green" style="color: green;"&gt;// 第一种创建方法&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;AbstractFactory *pFactory = ConcreteFactory1::Instance() ;&lt;br /&gt;AbstractProductA *pProductA = pFactory-&amp;gt;CreateProductA() ;&lt;br /&gt;AbstractProductB *pProductB = pFactory-&amp;gt;CreateProductB() ;&lt;br /&gt;&lt;br /&gt;&lt;span color="green" style="color: green;"&gt;// 第二种创建方法&lt;/span&gt;&lt;br /&gt;pFactory = ConcreteFactory2::Instance() ;&lt;br /&gt;pProductA = pFactory-&amp;gt;CreateProductA() ;&lt;br /&gt;pProductB = pFactory-&amp;gt;CreateProductB() ;&lt;br /&gt;}&lt;/p&gt;&lt;p&gt;&lt;b&gt;六、实例&lt;/b&gt;&lt;/p&gt;最早知道类厂的概念是在COM中，但当时也没想到这是如此重要的一种模式，在许多其他模式中都可以用到类厂模式。 COM中不能直接创建组件，这也是由COM的一个特性决定的：即客户不知道要创建的组件的类名。&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;&lt;table border="0" cellpadding="0" cellspacing="2" style="width: 550px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align="center" style="font-size: 12px; color: #454545; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"&gt;&lt;b&gt;&lt;span color="#333399" style="color: #333399;"&gt;C++设计模式之Singleton&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td bgcolor="#bbbbbb" height="1" style="font-size: 12px; color: #454545; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="center" style="font-size: 12px; color: #454545; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"&gt;&lt;span face="Arial, Helvetica, sans-serif" style="font-family: Arial, Helvetica, sans-serif;"&gt;2002-07-26&amp;middot; &amp;middot; &amp;middot;&amp;middot;COM集中营&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="font-size: 12px; color: #454545; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"&gt;&lt;b&gt;一、功能&lt;/b&gt;&lt;p&gt;保证一个类仅有一个实例。&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;二、结构图&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p align="center" style="line-height: 18px; margin-top: 5px; margin-right: auto; margin-bottom: 5px; margin-left: auto; text-indent: 0px;"&gt;&lt;img src="http://www.yesky.com/20020723/fangz20723_1.gif" style="border-style: initial; border-color: initial; width: 300px; cursor: pointer; border-width: 0px;" /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;三、优缺点&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Singleton模式是做为"全局变量"的替代品出现的。所以它具有全局变量的特点：全局可见、贯穿应用程序的整个生命期，它也具有全局变量不具备的性质：同类型的对象实例只可能有一个。&lt;/p&gt;&lt;p&gt;&lt;b&gt;四、实现&lt;/b&gt;&lt;/p&gt;&lt;p&gt;教科书上的Singleton定义如下：&amp;nbsp;&lt;/p&gt;&lt;table bgcolor="#ffffff" border="0" cellpadding="0" cellspacing="0" style="width: 600px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="font-size: 12px; color: #454545; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"&gt;&lt;p&gt;class Singleton&lt;br /&gt;{&lt;br /&gt;public:&lt;br /&gt;static Singleton* Instance() ;&lt;br /&gt;protected:&lt;br /&gt;Singleton() {}&lt;br /&gt;private:&lt;br /&gt;static Singleton *_instance ;&lt;br /&gt;Singleton(const Singleton&amp;amp;) ;&lt;br /&gt;Singleton&amp;amp; operator=(const Singleton&amp;amp;) ;&lt;br /&gt;} ;&lt;/p&gt;&lt;p&gt;Singleton* Singleton::_instance = NULL ;&lt;/p&gt;&lt;p&gt;Singleton* Singleton::Instance()&lt;br /&gt;{&lt;br /&gt;(_instance == NULL) ? _instance = new Singleton() : 0 ; //lazy initialization&lt;br /&gt;return _instance ;&lt;br /&gt;}&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;(1)因为返回的是指针，为防止用户调用delete函数，可把static Singleton *_instance；改为在Instance()中定义static Singleton _instance。这样显然更安全，同时也具有lazy initialization的特性(即第一次访问时才创建)。&amp;nbsp;&lt;br /&gt;&lt;br /&gt;(2)假设需要从Singleton派生子类，而子类也需要有同 样的性质，既只能创建一个实例。我觉得，这很难办。根本原因在于Instance()函数不是虚函数，不具有多态的性质。一种常用方法是把 Instance()函数移到子类中，这时就只能用static Singleton *_instance，而不能用static Singleton _instance了，除非把_instance也要移到子类，无论怎么做都不优雅。另一种方法是用模板。具体用什么方法，只能根据实际情况权衡。&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;五、示例代码&lt;/b&gt;&lt;/p&gt;&lt;p&gt;(1)没子类的情况&lt;/p&gt;&lt;table bgcolor="#ffffff" border="0" cellpadding="0" cellspacing="0" style="width: 600px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="font-size: 12px; color: #454545; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"&gt;&lt;p&gt;namespace DesignPattern_Singleton&lt;br /&gt;{&lt;/p&gt;&lt;p&gt;class Singleton&lt;br /&gt;{&lt;br /&gt;public:&lt;br /&gt;static Singleton* Instance() { static Singleton _instance ; return &amp;amp;_instance ; }&lt;br /&gt;protected:&lt;br /&gt;Singleton() {}&lt;br /&gt;private:&lt;br /&gt;Singleton(const Singleton&amp;amp;) ;&lt;br /&gt;Singleton&amp;amp; operator=(const Singleton&amp;amp;) ;&lt;br /&gt;} ;&lt;br /&gt;}&lt;/p&gt;&lt;p&gt;客户端代码：&lt;br /&gt;{&lt;br /&gt;using namespace DesignPattern_Singleton ;&lt;br /&gt;Singleton *p = Singleton::Instance() ;&lt;br /&gt;......&lt;br /&gt;}&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;(2)有子类的情况&amp;nbsp;&lt;/p&gt;&lt;table bgcolor="#ffffff" border="0" cellpadding="0" cellspacing="0" style="width: 600px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="font-size: 12px; color: #454545; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"&gt;&lt;p&gt;方法一：&lt;br /&gt;namespace DesignPattern_Singleton&lt;br /&gt;{&lt;br /&gt;// class Singleton&lt;br /&gt;class Singleton&lt;br /&gt;{&lt;br /&gt;protected:&lt;br /&gt;Singleton() {}&lt;br /&gt;static Singleton *_instance ;&lt;br /&gt;private:&lt;br /&gt;Singleton(const Singleton&amp;amp;) ;&lt;br /&gt;Singleton&amp;amp; operator=(const Singleton&amp;amp;) ;&lt;br /&gt;} ;&lt;br /&gt;Singleton* Singleton::_instance = NULL ;&lt;/p&gt;&lt;p&gt;// class ConcreteSingleton&lt;br /&gt;class ConcreteSingleton : public Singleton&lt;br /&gt;{&lt;br /&gt;public:&lt;br /&gt;static Singleton* Instance() ;&lt;br /&gt;protected:&lt;br /&gt;ConcreteSingleton() {}&lt;br /&gt;} ;&lt;/p&gt;&lt;p&gt;Singleton* ConcreteSingleton::Instance()&lt;br /&gt;{&lt;br /&gt;(_instance == NULL) ? _instance = new ConcreteSingleton() : 0 ;&amp;nbsp;&lt;br /&gt;return _instance ;&lt;br /&gt;}&lt;br /&gt;}&lt;/p&gt;&lt;p&gt;客户端代码：&lt;br /&gt;{&lt;br /&gt;using namespace DesignPattern_Singleton ;&lt;br /&gt;Singleton *p = ConcreteSingleton::Instance() ;&lt;br /&gt;}&lt;/p&gt;&lt;p&gt;方法二：&lt;br /&gt;namespace DesignPattern_Singleton&lt;br /&gt;{&lt;br /&gt;// class Singleton&lt;br /&gt;class Singleton&lt;br /&gt;{&lt;br /&gt;protected:&lt;br /&gt;Singleton() {}&lt;br /&gt;private:&lt;br /&gt;Singleton(const Singleton&amp;amp;) ;&lt;br /&gt;Singleton&amp;amp; operator=(const Singleton&amp;amp;) ;&lt;br /&gt;} ;&lt;/p&gt;&lt;p&gt;// class ConcreteSingleton&lt;br /&gt;class ConcreteSingleton : public Singleton&lt;br /&gt;{&lt;br /&gt;public:&lt;br /&gt;static Singleton* Instance() { static ConcreteSingleton _instance ; return &amp;amp;_instance ; }&lt;br /&gt;protected:&lt;br /&gt;ConcreteSingleton() {}&lt;br /&gt;} ;&lt;br /&gt;}&lt;/p&gt;&lt;p&gt;客户端代码：&lt;br /&gt;{&lt;br /&gt;using namespace DesignPattern_Singleton ;&lt;br /&gt;Singleton *p = ConcreteSingleton::Instance() ;&lt;br /&gt;}&lt;/p&gt;&lt;p&gt;方法三：&lt;br /&gt;namespace DesignPattern_Singleton&lt;br /&gt;{&lt;br /&gt;template &amp;lt; class T &amp;gt;&lt;br /&gt;class Singleton&lt;br /&gt;{&lt;br /&gt;public:&lt;br /&gt;static T* Instance() { static T _instance ; return &amp;amp;_instance ; }&lt;br /&gt;protected:&lt;br /&gt;Singleton() {}&lt;br /&gt;private:&lt;br /&gt;Singleton(const Singleton &amp;amp;) ;&lt;br /&gt;Singleton&amp;amp; operator=(const Singleton&amp;amp;) ;&lt;br /&gt;} ;&lt;/p&gt;&lt;p&gt;class ConcreteSingleton : public Singleton&amp;lt; ConcreteSingleton &amp;gt; {} ;&lt;br /&gt;}&lt;/p&gt;&lt;p&gt;客户端代码&lt;br /&gt;{&lt;br /&gt;using namespace DesignPattern_Singleton ;&lt;/p&gt;&lt;p&gt;ConcreteSingleton *p = ConcreteSingleton::Instance() ;&lt;br /&gt;}&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;&lt;table border="0" cellpadding="0" cellspacing="2" style="width: 550px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align="center" style="font-size: 12px; color: #454545; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"&gt;&lt;b&gt;&lt;span color="#333399" style="color: #333399;"&gt;C++模式开发之Bridge&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td bgcolor="#bbbbbb" height="1" style="font-size: 12px; color: #454545; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="center" style="font-size: 12px; color: #454545; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"&gt;&lt;span face="Arial, Helvetica, sans-serif" style="font-family: Arial, Helvetica, sans-serif;"&gt;2002-07-29&amp;middot; &amp;middot; &amp;middot;&amp;middot;COM集中营&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="font-size: 12px; color: #454545; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"&gt;&lt;b&gt;一、功能&lt;/b&gt;&amp;nbsp;&lt;br /&gt;将抽象部分与它的实现部分分离，使它们都可以独立地变化。&lt;p&gt;&lt;b&gt;二、结构图&lt;/b&gt;&lt;/p&gt;&lt;p align="center" style="line-height: 18px; margin-top: 5px; margin-right: auto; margin-bottom: 5px; margin-left: auto; text-indent: 0px;"&gt;&lt;img src="http://www.yesky.com/20020725/fangz20725_1.gif" style="border-style: initial; border-color: initial; width: 300px; cursor: pointer; border-width: 0px;" /&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;三&lt;b&gt;、示例代码&lt;/b&gt;&lt;table bgcolor="#ffffff" border="0" cellpadding="0" cellspacing="0" style="width: 600px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="font-size: 12px; color: #454545; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"&gt;&lt;p&gt;namespace DesignPattern_Bridge&lt;br /&gt;{&lt;br /&gt;// class Implementor&lt;br /&gt;class Implementor&lt;br /&gt;{&lt;br /&gt;public:&lt;br /&gt;virtual void OperationImp() = 0 ;&lt;br /&gt;} ;&lt;/p&gt;&lt;p&gt;// class ConcreteImplementorA&lt;br /&gt;class ConcreteImplementorA : public Implementor&lt;br /&gt;{&lt;br /&gt;public:&lt;br /&gt;virtual void OperationImp() {}&lt;br /&gt;} ;&lt;/p&gt;&lt;p&gt;// class ConcreteImplementorB&lt;br /&gt;class ConcreteImplementorB : public Implementor&lt;br /&gt;{&lt;br /&gt;public:&lt;br /&gt;virtual void OperationImp() {}&lt;br /&gt;} ;&lt;/p&gt;&lt;p&gt;// class Abstraction&lt;br /&gt;class Abstraction&lt;br /&gt;{&lt;br /&gt;public:&lt;br /&gt;void Operation(Implementor* imp) { assert(imp) ; imp-&amp;gt;OperationImp() ; }&lt;br /&gt;} ;&lt;br /&gt;}&lt;/p&gt;&lt;p&gt;客户端代码：&lt;br /&gt;{&lt;br /&gt;using namespace DesignPattern_Bridge ;&lt;/p&gt;&lt;p&gt;Abstraction obj ;&lt;br /&gt;Implementor *impa = new ConcreteImplementorA() ;&lt;br /&gt;Implementor *impb = new ConcreteImplementorB() ;&lt;br /&gt;obj.Operation(impa) ; //第一种实现方法&lt;br /&gt;obj.Operation(impb) ; //第二种实现方法&lt;br /&gt;}&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;b&gt;四、实例&lt;/b&gt;&lt;/p&gt;(1)创建可以在X Window System和IBM的Presentation Manager系统中都可以使用的窗口。(书上的例子)&lt;p align="center" style="line-height: 18px; margin-top: 5px; margin-right: auto; margin-bottom: 5px; margin-left: auto; text-indent: 0px;"&gt;&lt;img src="http://www.yesky.com/20020725/fangz20725_2.gif" style="border-style: initial; border-color: initial; width: 300px; cursor: pointer; border-width: 0px;" /&gt;&lt;/p&gt;&lt;p&gt;Bridge的魅力在于抽象和实现之间是松散的关系，它们之间可以进行随意组合。如上图中，就有IconWindow+ XWindowImp、TransientWindow+XWindowImp、IconWindow+PMWindowImp、 TransientWindow+PMWindowImp四种组合。&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;&lt;table border="0" cellpadding="0" cellspacing="2" style="width: 550px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align="center" style="font-size: 12px; color: #454545; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"&gt;&lt;b&gt;&lt;span color="#333399" style="color: #333399;"&gt;C++模式设计之Builder&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td bgcolor="#bbbbbb" height="1" style="font-size: 12px; color: #454545; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="center" style="font-size: 12px; color: #454545; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"&gt;&lt;span face="Arial, Helvetica, sans-serif" style="font-family: Arial, Helvetica, sans-serif;"&gt;2002-07-30&amp;middot; &amp;middot; &amp;middot;&amp;middot;COM集中营&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="font-size: 12px; color: #454545; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"&gt;&lt;b&gt;一、功能&lt;/b&gt;&amp;nbsp;&lt;br /&gt;&lt;br /&gt;将一个复杂对象的构建与它的表示分离，使得同样的构建过程可以&lt;b&gt;创建不同的表示&lt;/b&gt;。&amp;nbsp;&lt;br /&gt;&lt;p&gt;&lt;b&gt;二、结构图&lt;/b&gt;&lt;/p&gt;&lt;p align="center" style="line-height: 18px; margin-top: 5px; margin-right: auto; margin-bottom: 5px; margin-left: auto; text-indent: 0px;"&gt;&lt;img src="http://www.yesky.com/20020723/fangz20723_2.gif" style="border-style: initial; border-color: initial; width: 300px; cursor: pointer; border-width: 0px;" /&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;各类之间的交互关系如下图所示：&amp;nbsp;&lt;/p&gt;&lt;p align="center" style="line-height: 18px; margin-top: 5px; margin-right: auto; margin-bottom: 5px; margin-left: auto; text-indent: 0px;"&gt;&lt;img src="http://www.yesky.com/20020723/fangz20723_3.gif" style="border-style: initial; border-color: initial; width: 300px; cursor: pointer; border-width: 0px;" /&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;b&gt;三、示例代码&lt;/b&gt;&amp;nbsp;&lt;br /&gt;&lt;table bgcolor="#ffffff" border="0" cellpadding="0" cellspacing="0" style="width: 600px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="font-size: 12px; color: #454545; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"&gt;&lt;p&gt;namespace DesignPattern_Builder&lt;br /&gt;{&lt;br /&gt;class Product1 { /*...*/ } ;&lt;br /&gt;class Product2 { /*...*/ } ;&lt;/p&gt;&lt;p&gt;// class Builder&lt;br /&gt;class Builder //抽象基类&lt;br /&gt;{&lt;br /&gt;public:&lt;br /&gt;virtual void BuilderPartA() {} //提供缺省实现&lt;br /&gt;virtual void BuilderPartB() {}&lt;br /&gt;virtual void BuilderPartC() {}&lt;br /&gt;protected:&lt;br /&gt;Builder() {}&lt;br /&gt;} ;&lt;/p&gt;&lt;p&gt;// class ConcreteBuilder1&lt;br /&gt;class ConcreteBuilder1 : public Builder //创建Product1&lt;br /&gt;{&lt;br /&gt;public:&lt;br /&gt;ConcreteBuilder1() : _product(NULL) {}&lt;/p&gt;&lt;p&gt;virtual void BuilderPartA() { /*...*/ }&amp;nbsp;&lt;br /&gt;virtual void BuilderPartB() { /*...*/ }&lt;br /&gt;virtual void BuilderPartC() { /*...*/ }&lt;/p&gt;&lt;p&gt;virtual Product1* GetProduct1() { return _product ; } //返回创建的Product1对象&lt;br /&gt;private:&lt;br /&gt;Product1 *_product ;&lt;br /&gt;} ;&lt;/p&gt;&lt;p&gt;// class ConcreteBuilder2&lt;br /&gt;class ConcreteBuilder2 : public Builder //创建Product2&lt;br /&gt;{&lt;br /&gt;public:&lt;br /&gt;ConcreteBuilder2() : _product(NULL) {}&lt;/p&gt;&lt;p&gt;virtual void BuilderPartA() { /*...*/ }&amp;nbsp;&lt;br /&gt;virtual void BuilderPartB() { /*...*/ }&lt;br /&gt;virtual void BuilderPartC() { /*...*/ }&lt;/p&gt;&lt;p&gt;virtual Product2* GetProduct2() { return _product ; } //返回创建的Product2对象&lt;br /&gt;private:&lt;br /&gt;Product2 *_product ;&lt;br /&gt;} ;&lt;/p&gt;&lt;p&gt;// class Director&lt;br /&gt;class Director&lt;br /&gt;{&lt;br /&gt;public:&lt;br /&gt;//创建对象(Director并不知道具体创建出来的对象是什么样的，只有调用该函数的client知道)&lt;br /&gt;void Construct(Builder *builder)&lt;br /&gt;{&lt;br /&gt;builder-&amp;gt;BuilderPartA() ;&lt;br /&gt;builder-&amp;gt;BuilderPartB() ;&lt;br /&gt;builder-&amp;gt;BuilderPartC() ;&lt;br /&gt;}&lt;br /&gt;} ;&lt;br /&gt;}&lt;/p&gt;&lt;p&gt;客户端代码：&lt;br /&gt;{&lt;br /&gt;using namespace DesignPattern_Builder ;&lt;/p&gt;&lt;p&gt;Director director ;&lt;/p&gt;&lt;p&gt;// 创建第一种对象&lt;br /&gt;ConcreteBuilder1 *pBuilder1 = new ConcreteBuilder1() ;&lt;br /&gt;director.Construct(pBuilder1) ;&lt;br /&gt;Product1 *product1 = pBuilder1-&amp;gt;GetProduct1() ;&lt;/p&gt;&lt;p&gt;// 创建第二种对象&lt;br /&gt;ConcreteBuilder2 *pBuilder2 = new ConcreteBuilder2() ;&lt;br /&gt;director.Construct(pBuilder2) ;&lt;br /&gt;Product2 *product2 = pBuilder2-&amp;gt;GetProduct2() ;&lt;br /&gt;}&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;　&lt;b&gt;　四、实例&lt;/b&gt;&lt;/p&gt;&lt;p&gt;(1)例子一。如下图所示：&amp;nbsp;&lt;/p&gt;&lt;p align="center" style="line-height: 18px; margin-top: 5px; margin-right: auto; margin-bottom: 5px; margin-left: auto; text-indent: 0px;"&gt;&lt;img src="http://www.yesky.com/20020723/fangz20723_4.gif" style="border-style: initial; border-color: initial; width: 300px; cursor: pointer; border-width: 0px;" /&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;上图的功能是是把一个RTF文件转换为多种正文格式。RTFReader进行语法分析，然后将所有的token串逐一转换。可见builder就是一步步地把各个部分组装为一个整体。它封闭了组装的方法，组装出来的对象也大相径庭。&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;&lt;table border="0" cellpadding="0" cellspacing="2" style="width: 550px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align="center" style="font-size: 12px; color: #454545; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"&gt;&lt;b&gt;&lt;span color="#333399" style="color: #333399;"&gt;C++设计模式之Prototype&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td bgcolor="#bbbbbb" height="1" style="font-size: 12px; color: #454545; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="center" style="font-size: 12px; color: #454545; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"&gt;&lt;span face="Arial, Helvetica, sans-serif" style="font-family: Arial, Helvetica, sans-serif;"&gt;2002-08-01&amp;middot; &amp;middot; &amp;middot;&amp;middot;COM集中营&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="font-size: 12px; color: #454545; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"&gt;&lt;b&gt;一、功能&lt;/b&gt;&amp;nbsp;&lt;br /&gt;&lt;p&gt;用原型实例指定创建对象的种类，并且通过&lt;b&gt;拷贝&lt;/b&gt;这些原型创建新的对象。&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;二、结构图&lt;/b&gt;&lt;/p&gt;&lt;p align="center" style="line-height: 18px; margin-top: 5px; margin-right: auto; margin-bottom: 5px; margin-left: auto; text-indent: 0px;"&gt;&lt;img src="http://www.yesky.com/20020723/fangz20723_5.gif" style="border-style: initial; border-color: initial; width: 300px; cursor: pointer; border-width: 0px;" /&gt;&lt;/p&gt;&lt;p&gt;　&lt;b&gt;　三、优缺点&lt;/b&gt;&lt;/p&gt;&lt;p&gt;优点：复制自身。客户不知道需要对象的实际类型，只需知道它的抽象基类即可。(即有继承树的情况)&amp;nbsp;&lt;br /&gt;&lt;br /&gt;缺点：必须先有一个对象实例(即原型)才能clone。&lt;/p&gt;&lt;p&gt;　&lt;b&gt;　四、示例代码&lt;/b&gt;&lt;/p&gt;&lt;table bgcolor="#ffffff" border="0" cellpadding="0" cellspacing="0" style="width: 600px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="font-size: 12px; color: #454545; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"&gt;&lt;p&gt;namespace DesignPattern_Prototype&lt;br /&gt;{&lt;br /&gt;// class Prototype&lt;br /&gt;class Prototype //抽象基类&lt;br /&gt;{&lt;br /&gt;public:&lt;br /&gt;virtual Prototype* Clone() = 0 ;&lt;br /&gt;} ;&lt;/p&gt;&lt;p&gt;// class ConcretePrototype1&lt;br /&gt;class ConcretePrototype1 : public Prototype&lt;br /&gt;{&lt;br /&gt;public:&lt;br /&gt;virtual Prototype* Clone()&lt;br /&gt;{&lt;br /&gt;ConcretePrototype1 *p = new ConcretePrototype1() ;&lt;br /&gt;*p = *this ; //复制对象&lt;br /&gt;return p ;&lt;br /&gt;}&lt;br /&gt;} ;&lt;/p&gt;&lt;p&gt;// class ConcretePrototype2&lt;br /&gt;class ConcretePrototype2 : public Prototype&lt;br /&gt;{&lt;br /&gt;public:&lt;br /&gt;virtual Prototype* Clone()&lt;br /&gt;{&lt;br /&gt;ConcretePrototype2 *p = new ConcretePrototype2() ;&lt;br /&gt;*p = *this ; //复制对象&lt;br /&gt;return p ;&lt;br /&gt;}&lt;br /&gt;} ;&lt;br /&gt;}&lt;/p&gt;&lt;p&gt;客户端代码：&lt;br /&gt;{&lt;br /&gt;using namespace DesignPattern_Prototype ;&lt;/p&gt;&lt;p&gt;ConcretePrototype1 *obj1 = new ConcretePrototype1() ;//原型对象1&lt;br /&gt;ConcretePrototype2 *obj2 = new ConcretePrototype2() ;//原型对象2&lt;/p&gt;&lt;p&gt;Prototype *newobj1 = obj1-&amp;gt;Clone() ;//克隆对象1&lt;br /&gt;Prototype *newobj2 = obj2-&amp;gt;Clone() ;//克隆对象2&lt;/p&gt;&lt;p&gt;//使用复制出的对象newobj1和newobj2&lt;br /&gt;}&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;b&gt;五、实例&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;　在一个图形编辑器中，每一个图形元素，如线、圆、文字等都应该支持拷贝操作，即点中图形，按下Ctrl+C，再按下Ctrl+V后就会复制一个新的图形。显然这是一种clone操作。所以在每个从&lt;i&gt;Graphic&lt;/i&gt;派生出的图形子类都应运用Prototype模式，加上Clone操作。&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;table border="0" cellpadding="0" cellspacing="2" style="width: 550px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align="center" style="font-size: 12px; color: #454545; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"&gt;&lt;b&gt;&lt;span color="#333399" style="color: #333399;"&gt;C++设计模式之Factory Method&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td bgcolor="#bbbbbb" height="1" style="font-size: 12px; color: #454545; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="center" style="font-size: 12px; color: #454545; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"&gt;&lt;span face="Arial, Helvetica, sans-serif" style="font-family: Arial, Helvetica, sans-serif;"&gt;2002-08-05&amp;middot; &amp;middot; &amp;middot;&amp;middot;COM集中营&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="font-size: 12px; color: #454545; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"&gt;&lt;b&gt;一、功能&lt;/b&gt;&amp;nbsp;&lt;br /&gt;&lt;p&gt;定义一个用于创建对象的接口，让子类决定实例化哪一个类。Factory Method 使一个类的实例化延迟到其子类。&lt;/p&gt;&lt;p&gt;&lt;b&gt;二、结构图&lt;/b&gt;&lt;/p&gt;&lt;p align="center" style="line-height: 18px; margin-top: 5px; margin-right: auto; margin-bottom: 5px; margin-left: auto; text-indent: 0px;"&gt;&lt;img src="http://www.yesky.com/20020723/fangz20723_6.gif" style="border-style: initial; border-color: initial; width: 300px; cursor: pointer; border-width: 0px;" /&gt;&lt;/p&gt;&lt;p&gt;三&lt;b&gt;、实现&lt;/b&gt;&lt;/p&gt;(1)在某些情况下，比如仅仅为了创建适当的Product对象而派生新的Creator子类，并且创建不同Product的方法一致时，可以考虑用模板代替继承。如：&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;table bgcolor="#ffffff" border="0" cellpadding="0" cellspacing="0" style="width: 600px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="font-size: 12px; color: #454545; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"&gt;class Creator&amp;nbsp;&lt;br /&gt;{&lt;br /&gt;public:&lt;br /&gt;virtual Product* CreateProduct() = 0 ;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;template &amp;lt; class ConcreteProduct &amp;gt;&lt;br /&gt;class ConcreteCreator: public Creator&amp;nbsp;&lt;br /&gt;{&lt;br /&gt;public:&lt;br /&gt;virtual Product* CreateProduct() { return new ConcreteProduct() ; }&lt;br /&gt;};&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;模板与继承的本质区别之一是：&lt;b&gt;模板：行为不依赖于类型。继承：行为依赖于类型。&lt;/b&gt;(Effective C++ Item 41) 事实上，在很多模式中都存在着可以用模板代替继承的情况，其根本原因就在于&lt;b&gt;子类的行为是一致的&lt;/b&gt;。&lt;/p&gt;&lt;p&gt;四&lt;b&gt;、示例代码&lt;/b&gt;&lt;/p&gt;&lt;table bgcolor="#ffffff" border="0" cellpadding="0" cellspacing="0" style="width: 600px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="font-size: 12px; color: #454545; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"&gt;&lt;p&gt;namespace DesignPattern_FactoryMethod&lt;br /&gt;{&lt;br /&gt;class Product { /*...*/ } ;&lt;br /&gt;class ConcreteProduct : public Product { /*...*/ } ;&lt;/p&gt;&lt;p&gt;// class Creator&lt;br /&gt;class Creator&lt;br /&gt;{&lt;br /&gt;public:&lt;br /&gt;virtual Product* CreateProduct() = 0 ;&lt;br /&gt;void Operate() ;&lt;br /&gt;} ;&lt;/p&gt;&lt;p&gt;void Creator::Operate()&lt;br /&gt;{&lt;br /&gt;// ...&lt;br /&gt;Product *p = CreateProduct() ;&lt;br /&gt;// ...&lt;br /&gt;}&lt;/p&gt;&lt;p&gt;// class ConcreteCreator&lt;br /&gt;class ConcreteCreator : public Creator&lt;br /&gt;{&lt;br /&gt;public:&lt;br /&gt;virtual Product* CreateProduct() { return new ConcreteProduct() ; }&lt;br /&gt;} ;&lt;br /&gt;}&lt;/p&gt;&lt;p&gt;客户端代码：&lt;br /&gt;{&lt;br /&gt;using namespace DesignPattern_FactoryMethod ;&lt;br /&gt;ConcreteCreator p ;&lt;br /&gt;p.Operate() ;&lt;br /&gt;}&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&lt;i&gt;&lt;span color="#ff0000" style="color: #ff0000;"&gt;&lt;/span&gt;&lt;/i&gt;&lt;b&gt;这里的CreateProduct其实也是一个Template Method。&lt;/b&gt;&lt;/p&gt;&lt;p&gt;五&lt;b&gt;、实例&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Factory Method的运用太广泛了，它经常运用在其它模式中，其实例举不胜数。&amp;nbsp;&lt;br /&gt;(1)&lt;/p&gt;&lt;p align="center" style="line-height: 18px; margin-top: 5px; margin-right: auto; margin-bottom: 5px; margin-left: auto; text-indent: 0px;"&gt;&lt;img src="http://www.yesky.com/20020723/fangz20723_7.gif" style="border-style: initial; border-color: initial; width: 300px; cursor: pointer; border-width: 0px;" /&gt;&lt;/p&gt;&lt;p&gt;MFC中的CDocument类就包含了类似于上图CApplication中的三个函数。这里的CreateDocument就是一个factory method，因为它负责创建一个文档对象。&lt;/p&gt;&lt;p&gt;(2)&lt;/p&gt;&lt;p align="center" style="line-height: 18px; margin-top: 5px; margin-right: auto; margin-bottom: 5px; margin-left: auto; text-indent: 0px;"&gt;&lt;img src="http://www.yesky.com/20020723/fangz20723_8.gif" style="border-style: initial; border-color: initial; width: 300px; cursor: pointer; border-width: 0px;" /&gt;&lt;/p&gt;&lt;p&gt;当一个类将它的一些职责委托给一个独立的类时，就产生了&lt;b&gt;平行类层次&lt;/b&gt;。上图中Figure和Manipulator就是平 行类层次，Figure代表一些图形元素，如线、文字等，Manipulator表示作用于这些图形元素的操作，如拖拉、移动、选中等。如果这些操作所需 要的状态信息并不需要保存在Figure中，那么把Figure和Manipulator分成两个类层次是个好主意。这里的&lt;i&gt;CreateManipulator&lt;/i&gt;就是一个factory method。&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;&lt;table border="0" cellpadding="0" cellspacing="2" style="width: 550px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align="center" style="font-size: 12px; color: #454545; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"&gt;&lt;b&gt;&lt;span color="#333399" style="color: #333399;"&gt;C++设计模式之Composite&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td bgcolor="#bbbbbb" height="1" style="font-size: 12px; color: #454545; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="center" style="font-size: 12px; color: #454545; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"&gt;&lt;span face="Arial, Helvetica, sans-serif" style="font-family: Arial, Helvetica, sans-serif;"&gt;2002-08-06&amp;middot; &amp;middot; &amp;middot;&amp;middot;COM集中营&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="font-size: 12px; color: #454545; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"&gt;&lt;b&gt;一、功能&lt;/b&gt;&amp;nbsp;&lt;br /&gt;表示&amp;ldquo;部分-整体&amp;rdquo;关系，并使用户以一致的方式使用单个对象和组合对象。&lt;p&gt;&lt;b&gt;二、结构图&lt;/b&gt;&lt;/p&gt;&lt;p align="center" style="line-height: 18px; margin-top: 5px; margin-right: auto; margin-bottom: 5px; margin-left: auto; text-indent: 0px;"&gt;&lt;img src="http://www.yesky.com/20020725/fangz20725_5.gif" style="border-style: initial; border-color: initial; width: 300px; cursor: pointer; border-width: 0px;" /&gt;&lt;/p&gt;&lt;p&gt;上图中，也可以做些扩展，根据需要可以将Leaf和Composite做为抽象基类，从中派生出子类来。&lt;/p&gt;&lt;p&gt;&lt;b&gt;三、优缺点&lt;/b&gt;&lt;/p&gt;&lt;p&gt;优点：对于Composite模式，也许人们一开始的注意力会集中在它是如何实现组合对象的。但Composite最重要之处在于用户并不关心是组合对象还是单个对象，用户将以统一的方式进行处理，所以基类应是从单个对象和组合对象中提出的公共接口。&amp;nbsp;&lt;br /&gt;缺点：Composite最大的问题在于不容易限制组合中的组件。&lt;/p&gt;&lt;p&gt;&lt;b&gt;四、实现&lt;/b&gt;&lt;/p&gt;有时需要限制组合中的组件，即希望一个Composite只能有某些特定的Leaf。这个问题我是 用多继承和动态类型转换来解决的。假如组合对象Composite1只能包含单个对象ConcreteLeaf1，Composite2可以包含单个对象 ConcreteLeaf1和ConcreteLeaf2。如下图所示：&lt;p align="center" style="line-height: 18px; margin-top: 5px; margin-right: auto; margin-bottom: 5px; margin-left: auto; text-indent: 0px;"&gt;&lt;img src="http://www.yesky.com/20020725/fangz20725_6.gif" style="border-style: initial; border-color: initial; width: 300px; cursor: pointer; border-width: 0px;" /&gt;&lt;/p&gt;&lt;p&gt;上图中的类层次比较多，使用了AbstractLeaf1和AbstractLeaf2，但没使用 AbstractComposite1和AbstractComposite2，这个并不重要，也可以把AbstractLeaf1和 AbstractLeaf2去掉，这个并不重要，可以根据具体情况决定要不要。&amp;nbsp;&lt;br /&gt;简单的代码实现如下：&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;table bgcolor="#ffffff" border="0" cellpadding="0" cellspacing="0" style="width: 600px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="font-size: 12px; color: #454545; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"&gt;&lt;p&gt;namespace DesignPattern_Composite&lt;br /&gt;{&amp;nbsp;&lt;br /&gt;class Component&lt;br /&gt;{&lt;br /&gt;public:&lt;br /&gt;virtual void operation() = 0 ;&lt;br /&gt;virtual void Add(Component*) {}&lt;br /&gt;} ;&lt;/p&gt;&lt;p&gt;class AbstractComponent1 : virtual public Component {} ;&lt;/p&gt;&lt;p&gt;class AbstractLeaf1 : virtual public AbstractComponent1 {} ;&lt;/p&gt;&lt;p&gt;class Composite1 : public AbstractComponent1&lt;br /&gt;{&lt;br /&gt;public:&lt;br /&gt;virtual void operation() { /* do operation */ }&lt;br /&gt;virtual void Add(Component*) ;&lt;br /&gt;} ;&lt;br /&gt;void Composite1::Add(Component *p)&lt;br /&gt;{&lt;br /&gt;AbstractComponent1 *pc1 = dynamic_cast＜ABSTRACTCOMPONENT1*＞(p) ;&lt;br /&gt;if (pc1 == NULL) return ;&lt;br /&gt;// do add operation&lt;br /&gt;}&lt;/p&gt;&lt;p&gt;class AbstractComponent2 : virtual public Component {} ;&lt;/p&gt;&lt;p&gt;class AbstractLeaf2 : virtual public AbstractComponent2 {} ;&lt;/p&gt;&lt;p&gt;class Composite2 : public AbstractComponent2&lt;br /&gt;{&lt;br /&gt;public:&lt;br /&gt;virtual void operation() { /* do operation */ }&lt;br /&gt;virtual void Add(Component*) ;&lt;br /&gt;} ;&lt;br /&gt;void Composite2::Add(Component *p)&lt;br /&gt;{&lt;br /&gt;AbstractComponent2 *pc2 = dynamic_cast＜ABSTRACTCOMPONENT2*&amp;gt;(p) ;&lt;br /&gt;if (pc2 == NULL) return ;&lt;br /&gt;// do add operation&lt;br /&gt;}&lt;/p&gt;&lt;p&gt;class ConcreteLeaf1 : public AbstractLeaf1&lt;br /&gt;{&lt;br /&gt;public:&lt;br /&gt;virtual void operation() { /* do operation */ }&lt;br /&gt;} ;&lt;/p&gt;&lt;p&gt;class ConcreteLeaf2 : public AbstractLeaf1, public AbstractLeaf2&lt;br /&gt;{&lt;br /&gt;public:&lt;br /&gt;virtual void operation() { /* do operation */ }&lt;br /&gt;} ;&lt;br /&gt;}&lt;/p&gt;&lt;p&gt;客户端代码：&lt;br /&gt;｛&lt;br /&gt;using namespace DesignPattern_Composite ;&lt;/p&gt;&lt;p&gt;Component *pc1 = new ConcreteLeaf1() ;&lt;br /&gt;Component *pc2 = new ConcreteLeaf2() ;&lt;br /&gt;Component *pc3 = new Composite1() ;&lt;br /&gt;Component *pc4 = new Composite2() ;&lt;br /&gt;pc3-&amp;gt;Add(pc1) ; // ok&lt;br /&gt;pc3-&amp;gt;Add(pc2) ; // ok&lt;br /&gt;pc3-&amp;gt;Add(pc3) ; // ok&lt;br /&gt;pc3-&amp;gt;Add(pc4) ; // fail&lt;br /&gt;pc4-&amp;gt;Add(pc1) ; // fail&lt;br /&gt;pc4-&amp;gt;Add(pc2) ; // ok&lt;br /&gt;pc4-&amp;gt;Add(pc3) ; // fail&lt;br /&gt;pc4-&amp;gt;Add(pc4) ; // ok&lt;br /&gt;}&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;有两点需要注意，一是因为用了多继承，所以需要使用virtual inheritance。二是要用dynamic_cast来判断是否允许组合该组件。&lt;br /&gt;&lt;br /&gt;&lt;b&gt;五、示例代码&lt;/b&gt;&lt;/p&gt;&lt;table bgcolor="#ffffff" border="0" cellpadding="0" cellspacing="0" style="width: 600px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="font-size: 12px; color: #454545; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"&gt;&lt;p&gt;namespace DesignPattern_Composite&lt;br /&gt;{&lt;br /&gt;// class Component&lt;br /&gt;class Component&lt;br /&gt;{&lt;br /&gt;public:&lt;br /&gt;virtual void Operation() = 0 ;&lt;br /&gt;virtual void Add(Component*) {}&lt;br /&gt;} ;&lt;/p&gt;&lt;p&gt;// class Leaf&lt;br /&gt;class Leaf : public Component&lt;br /&gt;{&lt;br /&gt;public:&lt;br /&gt;virtual void Operation() {}&lt;br /&gt;} ;&lt;/p&gt;&lt;p&gt;// class Composite&lt;br /&gt;class Composite : public Component&lt;br /&gt;{&lt;br /&gt;public:&lt;br /&gt;virtual void Add(Component *p) { _list.push_back(p) ; }&lt;br /&gt;virtual void Operation()&lt;br /&gt;{&lt;br /&gt;vector&amp;lt; Component* &amp;gt;::const_iterator it ;&lt;br /&gt;for (it = _list.begin(); it != _list.end(); it++)&lt;br /&gt;(*it)-&amp;gt;Operation() ;&lt;br /&gt;}&lt;br /&gt;private:&lt;br /&gt;vector&amp;lt; Component* &amp;gt; _list ;&lt;br /&gt;} ;&lt;br /&gt;}&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;b&gt;六、实例&lt;/b&gt;&lt;/p&gt;&lt;p&gt;(1)JUnit中就用的是Composite模式。&lt;/p&gt;&lt;p align="center" style="line-height: 18px; margin-top: 5px; margin-right: auto; margin-bottom: 5px; margin-left: auto; text-indent: 0px;"&gt;&lt;img src="http://www.yesky.com/20020725/fangz20725_7.gif" style="border-style: initial; border-color: initial; width: 300px; cursor: pointer; border-width: 0px;" /&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;div id="blog_post_info_block" style="margin-top: 20px;"&gt;&lt;div id="BlogPostCategory"&gt;分类:&amp;nbsp;&lt;a href="http://www.cnblogs.com/userinterface/category/21529.html" style="color: #1a8bc8; text-decoration: none;"&gt;代码人生&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;img src="http://www.cnblogs.com/buffer/aggbug/2169285.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/buffer/archive/2011/09/06/2169285.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry></feed>
