<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title type="text">博客园_在软件中体悟人生  在人生中感悟软件</title><subtitle type="text">专注Web项目设计、实现和管理</subtitle><id>http://feed.cnblogs.com/blog/u/39287/rss</id><updated>2012-03-30T01:30:34Z</updated><author><name>王景</name><uri>http://www.cnblogs.com/a311300/</uri></author><generator>feed.cnblogs.com</generator><link rel="alternate" type="text/html" href="http://www.cnblogs.com/a311300/"/><link rel="self" type="application/atom+xml" href="http://feed.cnblogs.com/blog/u/39287/rss"/><entry><id>http://www.cnblogs.com/a311300/archive/2012/02/13/2349264.html</id><title type="text">Cassandra在Windows上安装及使用方法[转]</title><summary type="text">Cassandra的安装、配置及基本的使用方法</summary><published>2012-02-13T05:39:00Z</published><updated>2012-02-13T05:39:00Z</updated><author><name>王景</name><uri>http://www.cnblogs.com/a311300/</uri></author><link rel="alternate" href="http://www.cnblogs.com/a311300/archive/2012/02/13/2349264.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/a311300/archive/2012/02/13/2349264.html"/><content type="html">&lt;div&gt;&lt;div&gt;&lt;span style="font-size: 24pt; "&gt;一、安装&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size: 18pt; "&gt;1、安装cassandra&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &lt;span style="font-size: 14pt; "&gt;1.1 下载安装程序&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="white-space:pre"&gt;&lt;/span&gt;在http://cassandra.apache.org/下载Cassandra的安装程序;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &lt;span style="font-size: 14pt; "&gt;1.2 安装配置&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="white-space:pre"&gt;&lt;/span&gt;1)解压下载后的程序apache-cassandra-0.7.3-bin.tar.gz到某个目录，如d:\cassandra；&lt;/div&gt;&lt;div&gt;&lt;span style="white-space:pre"&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="white-space:pre"&gt;&lt;/span&gt;2)修改conf目录下配置文件&lt;/div&gt;&lt;div&gt;&lt;span style="white-space:pre"&gt;&lt;/span&gt;&amp;nbsp; &amp;nbsp; A)使用记事本打开cassandra.yaml文件，修改如下参数：&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="white-space:pre"&gt;&lt;/span&gt; &amp;nbsp; &amp;nbsp;data_file_directories:&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &lt;span style="white-space:pre"&gt;&lt;/span&gt;- /var/lib/cassandra/data&lt;/div&gt;&lt;div&gt;&lt;span style="white-space:pre"&gt;&lt;/span&gt; &amp;nbsp; &amp;nbsp;为 - d:\cassandra\data&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;span style="white-space:pre"&gt;&lt;/span&gt; &amp;nbsp; &amp;nbsp;注意：-后面需要有空格&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="white-space:pre"&gt;&lt;/span&gt; &amp;nbsp; &amp;nbsp;commitlog_directory: /var/lib/cassandra/commitlog&lt;/div&gt;&lt;div&gt;&lt;span style="white-space:pre"&gt;&lt;/span&gt; &amp;nbsp; &amp;nbsp;为：commitlog_directory: d:\cassandra\commitlog&lt;/div&gt;&lt;div&gt;&lt;span style="white-space:pre"&gt;&lt;/span&gt; &amp;nbsp; &amp;nbsp;saved_caches_directory: /var/lib/cassandra/saved_caches&lt;/div&gt;&lt;div&gt;&lt;span style="white-space:pre"&gt;&lt;/span&gt; &amp;nbsp; &amp;nbsp;为：saved_caches_directory: d:\cassandra\saved_caches&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="white-space:pre"&gt;&lt;/span&gt; &amp;nbsp;B)使用记事本打开log4j-server.properties文件，修改如下参数：&lt;/div&gt;&lt;div&gt;&lt;span style="white-space:pre"&gt;&lt;/span&gt; &amp;nbsp; &amp;nbsp;log4j.appender.R.File=/var/log/cassandra/system.log&lt;/div&gt;&lt;div&gt;&lt;span style="white-space:pre"&gt;&lt;/span&gt; &amp;nbsp; &amp;nbsp;为：log4j.appender.R.File=D:\Cassandra\logs&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size: 18pt; "&gt;2、安装JRE&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; 2.1 下载安装程序&lt;/div&gt;&lt;div&gt;&lt;span style="white-space:pre"&gt;&lt;/span&gt;在http://www.oracle.com/technetwork/java/javase/downloads/index.html上下载jre的安装程序；&lt;/div&gt;&lt;div&gt;&lt;span style="white-space:pre"&gt;&lt;/span&gt;jre和jdk区别：jre只是java环境，jdk包含了开发工具和jre；&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; 2.2 直接双击执行jre-6u25-windows-i586.exe进行安装，默认安装在C:\Program Files\Java\jre6目录即可；&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size: 18pt; "&gt;3、配置环境变量&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; 3.1 打开windows的环境变量配置窗口&lt;/div&gt;&lt;div&gt;&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;span style="white-space:pre"&gt;&lt;/span&gt;鼠标右键点击我的电脑，选择属性，在弹出界面点击【高级】页签，再点击【环境变量】按钮；&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; 3.2 配置JAVA_HOME环境变量&lt;/div&gt;&lt;div&gt;&lt;span style="white-space:pre"&gt;&lt;/span&gt;在&amp;#8220;系统变量&amp;#8221;添加JAVA_HOME，点击【系统变量】下方的【新建】按钮，输入&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 变量名:JAVA_HOME&lt;/div&gt;&lt;div&gt;&amp;nbsp;&lt;span style="white-space:pre"&gt;&lt;/span&gt; &amp;nbsp;变量值:C:\Program Files\Java\jre6&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; 3.3 配置Cassandra_HOME环境变量&lt;/div&gt;&lt;div&gt;&lt;span style="white-space:pre"&gt;&lt;/span&gt;在&amp;#8220;系统变量&amp;#8221;添加Cassandra_HOME，点击【系统变量】下方的【新建】按钮，输入&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 变量名:Cassandra_HOME&lt;/div&gt;&lt;div&gt;&amp;nbsp;&lt;span style="white-space:pre"&gt;&lt;/span&gt; &amp;nbsp;变量值:D:\Cassandra\apache-cassandra-0.7.3&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size: 18pt; "&gt;4、启动Cassandra&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp; 开始运行中敲入cmd回车打开命令窗口，敲入cd D:\Cassandra\apache-cassandra-0.7.3\bin回车，敲入d:回车，转到D:\Cassandra\apache-cassandra-0.7.3\bin目录后，直接敲入cassandra就可以启动cassandra服务了，如下：&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;D:\Cassandra\apache-cassandra-0.7.3\bin&amp;gt;cassandra&lt;/div&gt;&lt;div&gt;Starting Cassandra Server&lt;/div&gt;&lt;div&gt;&amp;nbsp;INFO 09:33:34,375 Logging initialized&lt;/div&gt;&lt;div&gt;&amp;nbsp;INFO 09:33:34,390 Heap size: 1070399488/1070399488&lt;/div&gt;&lt;div&gt;&amp;nbsp;INFO 09:33:34,390 JNA not found. Native methods will be disabled.&lt;/div&gt;&lt;div&gt;&amp;nbsp;INFO 09:33:34,406 Loading settings from file:/D:/Cassandra/apache-cassandra-0.7.3/conf/cassandra.yaml&lt;/div&gt;&lt;div&gt;&amp;nbsp;INFO 09:33:34,562 DiskAccessMode 'auto' determined to be standard, indexAccessMode is standard&lt;/div&gt;&lt;div&gt;&amp;nbsp;INFO 09:33:34,765 Creating new commitlog segment d:\cassandra\commitlog\CommitLog-1306200814765.log&lt;/div&gt;&lt;div&gt;&amp;nbsp;INFO 09:33:34,781 Couldn't detect any schema definitions in local storage.&lt;/div&gt;&lt;div&gt;&amp;nbsp;INFO 09:33:34,781 Found table data in data directories. Consider using JMX to call org.apache.cassandra.service.StorageService.loadSchemaFromYaml().&lt;/div&gt;&lt;div&gt;&amp;nbsp;INFO 09:33:34,796 No commitlog files found; skipping replay&lt;/div&gt;&lt;div&gt;&amp;nbsp;INFO 09:33:34,828 Upgrading to 0.7. Purging hints if there are any. Old hints will be snapshotted.&lt;/div&gt;&lt;div&gt;&amp;nbsp;INFO 09:33:34,828 Cassandra version: 0.7.3&lt;/div&gt;&lt;div&gt;&amp;nbsp;INFO 09:33:34,828 Thrift API version: 19.4.0&lt;/div&gt;&lt;div&gt;&amp;nbsp;INFO 09:33:34,843 Loading persisted ring state&lt;/div&gt;&lt;div&gt;&amp;nbsp;INFO 09:33:34,843 Starting up server gossip&lt;/div&gt;&lt;div&gt;&amp;nbsp;INFO 09:33:34,843 switching in a fresh Memtable for LocationInfo at CommitLogContext(file='d:\cassandra\commitlog\CommitLog-1306200814765.log', position=700)&amp;nbsp;&lt;/div&gt;&lt;p&gt;&amp;nbsp;INFO 09:33:34,859 Enqueuing flush of Memtable-LocationInfo@31556811(227 bytes,4 operations)&lt;/p&gt;&lt;div&gt;&amp;nbsp;INFO 09:33:34,859 Writing Memtable-LocationInfo@31556811(227 bytes, 4 operations)&lt;/div&gt;&lt;div&gt;&amp;nbsp;INFO 09:33:35,656 Completed flushing d:\cassandra\data\system\LocationInfo-f-1-Data.db (335 bytes)&lt;/div&gt;&lt;div&gt;&amp;nbsp;WARN 09:33:35,718 Generated random token 152144483071909207899303400696660552068. Random tokens will result in an unbalanced ring; see http://wiki.apache.org/cassandra/Operations&lt;/div&gt;&lt;div&gt;&amp;nbsp;INFO 09:33:35,718 switching in a fresh Memtable for LocationInfo at CommitLogContext(file='d:\cassandra\commitlog\CommitLog-1306200814765.log', position=996)&lt;/div&gt;&lt;div&gt;&amp;nbsp;INFO 09:33:35,718 Enqueuing flush of Memtable-LocationInfo@22975191(53 bytes, 2operations)&lt;/div&gt;&lt;div&gt;&amp;nbsp;INFO 09:33:35,734 Writing Memtable-LocationInfo@22975191(53 bytes, 2 operations)&lt;/div&gt;&lt;div&gt;&amp;nbsp;INFO 09:33:35,828 Completed flushing d:\cassandra\data\system\LocationInfo-f-2-Data.db (163 bytes)&lt;/div&gt;&lt;div&gt;&amp;nbsp;INFO 09:33:35,843 Will not load MX4J, mx4j-tools.jar is not in the classpath&lt;/div&gt;&lt;div&gt;&amp;nbsp;INFO 09:33:35,890 Binding thrift service to localhost/127.0.0.1:9160&lt;/div&gt;&lt;div&gt;&amp;nbsp;INFO 09:33:35,890 Using TFastFramedTransport with a max frame size of 15728640bytes.&lt;/div&gt;&lt;div&gt;&amp;nbsp;INFO 09:33:35,890 Listening for thrift clients...&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size: 24pt; "&gt;二、使用&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size: 18pt; "&gt;1、连接Cassandra服务&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; 开始运行中敲入cmd回车进入命令窗口，敲入cd D:\Cassandra\apache-cassandra-0.7.3\bin后，在敲入d:回车转到bin目录中&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; 敲入cassandra-cli命令回车，直接敲入如下命令可以连接到本机已经启动的cassandra数据库&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;--cassandra默认为9160端口，注意后面需要有;结束&lt;/div&gt;&lt;div&gt;connect localhost/9160;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size: 18pt; "&gt;2、创建keyspace&lt;/span&gt;&lt;/div&gt;&lt;div&gt;create keyspace keyspace1;&lt;/div&gt;&lt;div&gt;use keyspace1;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size: 18pt; "&gt;3、创建column family&lt;/span&gt;&lt;/div&gt;&lt;div&gt;create column family Standard1 with column_type = 'Standard' and comparator = 'BytesType';&lt;/div&gt;&lt;div&gt;describe keyspace keyspace1;&lt;/div&gt;&lt;div&gt;list standard1;&lt;/div&gt;&lt;div&gt;drop column family standard1;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;--必须指定column_type和comparator&lt;/div&gt;&lt;div&gt;create column family cf1 with column_type = 'Standard' and comparator = 'BytesType';&lt;/div&gt;&lt;div&gt;create column family cf2 with column_type = 'Standard' and comparator = 'UTF8Type' and rows_cached = 10000;&lt;/div&gt;&lt;div&gt;create column family Super1 with column_type=Super and comparator=BytesType;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;--设置列值&lt;/div&gt;&lt;div&gt;set cf1['key_1']['column_1']='value_1';&lt;/div&gt;&lt;div&gt;set cf1['key_1']['column_2']='value_2';&lt;/div&gt;&lt;div&gt;set cf1['key_2']['column_1']='value_3';&lt;/div&gt;&lt;div&gt;set cf1['key_2']['column_2']='value_4';&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;--设置列值&lt;/div&gt;&lt;div&gt;set cf2['key_1']['column_1']='value_1';&lt;/div&gt;&lt;div&gt;set cf2['key_1']['column_2']='value_2';&lt;/div&gt;&lt;div&gt;set cf2['key_2']['column_1']='value_3';&lt;/div&gt;&lt;div&gt;set cf2['key_2']['column_2']='value_4';&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;set super1['key_1']['column_1']='value_1';&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;get cf2['key_2']['column_2']; &amp;nbsp;--提示错误Column family Super1 may only contain SuperColumns&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;--取列值&lt;/div&gt;&lt;div&gt;get cf1['key_1'];&lt;/div&gt;&lt;div&gt;--计数&lt;/div&gt;&lt;div&gt;count &amp;nbsp;cf1['key_1'];&lt;/div&gt;&lt;div&gt;count &amp;nbsp;cf1['key_2'];&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;--取列值&lt;/div&gt;&lt;div&gt;get cf1['key_1']['column_1'];&lt;/div&gt;&lt;div&gt;--删除列值&lt;/div&gt;&lt;div&gt;del cf1['key_1']['column_1'];&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;list cf2[key_1:];&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;---二级索引的使用&lt;/div&gt;&lt;div&gt;1、定义：在Cassandra中，对列值(column values)的索引叫做"二级索引"，它与列簇(column families)中对key的&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;索引不同。二级索引允许我们对列值进行查询，并且在读取和写入的时候不会引起操作阻塞。&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;2、使用方法：&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;create keyspace demo;&lt;/div&gt;&lt;div&gt;use demo;&lt;/div&gt;&lt;div&gt;--注意大小写,索引birth_date&lt;/div&gt;&lt;div&gt;create column family users with comparator=UTF8Type and column_metadata=&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;[{column_name:full_name,validation_class:UTF8Type},&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;{column_name:birth_date,validation_class:LongType,index_type:KEYS}];&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;--插入数据：&lt;/div&gt;&lt;div&gt;set users[a][full_name]='a';&lt;/div&gt;&lt;div&gt;set users[a][birth_date]=1977;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;set users[b][full_name]='b';&lt;/div&gt;&lt;div&gt;set users[b][birth_date]=1978;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;set users[c][full_name]='c';&lt;/div&gt;&lt;div&gt;set users[c][birth_date]=1979;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;set users[d][full_name]='d';&lt;/div&gt;&lt;div&gt;set users[d][birth_date]=1977;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;--查询birth_date=1977的数据：&lt;/div&gt;&lt;div&gt;get users where birth_date=1977;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;--查询结果如下：&lt;/div&gt;&lt;div&gt;[default@demo] get users where birth_date=1977;&lt;/div&gt;&lt;div&gt;-------------------&lt;/div&gt;&lt;div&gt;RowKey: a&lt;/div&gt;&lt;div&gt;=&amp;gt; (column=birth_date, value=1977, timestamp=1306733443578000)&lt;/div&gt;&lt;div&gt;=&amp;gt; (column=full_name, value=a, timestamp=1306733438406000)&lt;/div&gt;&lt;div&gt;-------------------&lt;/div&gt;&lt;div&gt;RowKey: d&lt;/div&gt;&lt;div&gt;=&amp;gt; (column=birth_date, value=1977, timestamp=1306733577125000)&lt;/div&gt;&lt;div&gt;=&amp;gt; (column=full_name, value=d, timestamp=1306733572687000)&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;2 Rows Returned.&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;--多个二级索引使用&lt;/div&gt;&lt;div&gt;set users[a][card_no]='111';&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;--更新列簇users设置card_no和birth_date都索引&lt;/div&gt;&lt;div&gt;update column family users with comparator=UTF8Type and column_metadata=&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;[{column_name:full_name,validation_class:UTF8Type},&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;{column_name:birth_date,validation_class:LongType,index_type:KEYS},&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;{column_name:card_no,validation_class:UTF8Type,index_type:KEYS}];&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;--查询证件号码为111的列&lt;/div&gt;&lt;div&gt;get users where card_no='111';&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;get users where card_no='111' and birth_date=1977;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;--虽然full_name没有索引，但是也能够查出结果&lt;/div&gt;&lt;div&gt;get users where card_no='111' and birth_date=1977 and full_name='a';&lt;/div&gt;&lt;div&gt;get users where card_no='111' and full_name='a';&lt;/div&gt;&lt;div&gt;get users where birth_date=1977 and full_name='a';&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;--如果仅仅通过full_name查询则出错&lt;/div&gt;&lt;div&gt;get users where full_name='a';&lt;/div&gt;&lt;div&gt;--结果如下：&lt;/div&gt;&lt;div&gt;[defualt@demo] get users where full_name='a';&lt;/div&gt;&lt;div&gt;No indexed columns present in index clause with operator EQ&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;--退出&lt;/div&gt;&lt;div&gt;quit;&lt;/div&gt;&lt;/div&gt;&lt;img src="http://www.cnblogs.com/a311300/aggbug/2349264.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/a311300/archive/2012/02/13/2349264.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/a311300/archive/2011/09/14/2176354.html</id><title type="text">程序员的经验之谈-生活与工作(转)</title><summary type="text">程序员生活经验谈</summary><published>2011-09-14T08:15:00Z</published><updated>2011-09-14T08:15:00Z</updated><author><name>王景</name><uri>http://www.cnblogs.com/a311300/</uri></author><link rel="alternate" href="http://www.cnblogs.com/a311300/archive/2011/09/14/2176354.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/a311300/archive/2011/09/14/2176354.html"/><content type="html">&lt;span class="Apple-style-span" style="word-spacing: 0px; font: medium Arial,Microsoft Yahei,Simsun,sans-serif; text-transform: none; color: rgb(0,0,0); text-indent: 0px; white-space: normal; letter-spacing: normal; border-collapse: separate; orphans: 2; widows: 2; webkit-border-horizontal-spacing: 0px; webkit-border-vertical-spacing: 0px; webkit-text-decorations-in-effect: none; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px"&gt;&lt;span class="Apple-style-span" style="font-size: 12px; color: rgb(108,108,108); line-height: 21px; font-family: Arial, Helvetica, sans-serif, 宋体; text-align: left"&gt; &lt;h3 class="title" style="word-break: break-all; line-height: normal! important"&gt;程序员的经验之谈-生活与工作(转)&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div style="margin: 10px 0px; word-break: break-all; line-height: normal! important"&gt;&lt;em style="word-break: break-all; line-height: normal! important"&gt;展望未来，总结过去10年的程序员生涯，给程序员小弟弟小妹妹们的一些总结性忠告&lt;/em&gt;&lt;/div&gt;&lt;div style="margin: 10px 0px; word-break: break-all; line-height: normal! important"&gt;走过的路，回忆起来是那么曲折，把自己的一些心得体会分享给程序员兄弟姐妹们，虽然时代在变化，但是很可能你也会走我已经做过的10年的路程，有些心得体会你可以借鉴一下，觉得说得有道理的你就接纳，觉得说得没道理的，你就抛弃，以下是我发自内心的，给大家的忠告，特别是针对那些小弟弟妹妹们。&lt;/div&gt;&lt;div style="margin: 10px 0px; word-break: break-all; line-height: normal! important"&gt;&lt;/div&gt;&lt;div style="margin: 10px 0px; word-break: break-all; line-height: normal! important"&gt;&lt;strong style="word-break: break-all; line-height: normal! important"&gt;01. 自己的户口档案、养老保险、医疗保险、住房公积金一定要保管好。&lt;/strong&gt;&lt;/div&gt;&lt;div style="margin: 10px 0px; word-break: break-all; line-height: normal! important"&gt;由于程序员行业每年跳槽一次，我不隐瞒大家，我至少换过5个以上的单位，这期间跳来跳去，甚至是城市都换过3个。还好户口没丢掉，其他都已经是乱了，好几个城市里，都有交过三金，甚至是一个程序的2个区里交的都有，那些东西，10年后，会变得很重要。你买房子若有公积金，可以取出来，贷款利率也会比较低一些，有孩子了，还需要上学，生病了还需要医疗保险。&lt;/div&gt;&lt;div style="margin: 10px 0px; word-break: break-all; line-height: normal! important"&gt;特别是买房子时，你要商业贷款与公积金贷款的利率差别还是很大，有可能会有10万的差距。你平时都注意这些，会给你带来的损失会最小，例如每个月缴纳300元的公积金，公司也缴纳300元，你一个月能存下来600元，一年就是7200元，10年就是72000元。我以前都忽视了这些，到我需要买房子时，公积金里可能只有几千元，10年很快就过去了，结果我没能存下来多少公积金，医疗保险，养老金等更别提了，都已经稀里糊涂了，这些损失10年累加起来，是很庞大的数字，大家要注意，跳槽换工作时也要保护好自身的利益，现在房价很贵，你可能是跟我一样，大山里出来打拼的娃子，家里也没有丰厚的积蓄，只有靠自己拼搏，买房子是&lt;a style="color: rgb(0,0,0); word-break: break-all; line-height: normal! important; text-decoration: underline" onclick="javascript:tagshow(event, '%C8%CB%C9%FA');" href="http://www.cnblogs.com/a311300/admin/javascript:;" target="_self"&gt;&lt;u style="word-break: break-all; line-height: normal! important"&gt;&lt;strong style="word-break: break-all; line-height: normal! important"&gt;人生&lt;/strong&gt;&lt;/u&gt;&lt;/a&gt;的一件大事，等你到了10年，才想到这个事情，已经晚了，特别是孩子要上学，上幼儿园等，需要户口啥的都要齐全。&lt;/div&gt;&lt;div style="margin: 10px 0px; word-break: break-all; line-height: normal! important"&gt;&lt;/div&gt;&lt;div style="margin: 10px 0px; word-break: break-all; line-height: normal! important"&gt;&lt;strong style="word-break: break-all; line-height: normal! important"&gt;02. 不要轻易换笔记本电脑，不要跟潮流，不要买过多的电子产品，不要过于频繁的更换手机。&lt;/strong&gt;&lt;/div&gt;&lt;div style="margin: 10px 0px; word-break: break-all; line-height: normal! important"&gt;这方面我的经验教训也是惨痛的。我大概前后购买过5-6个笔记本，以前的都是1万多元一台，最近买的是一台是1万多给女朋友的，自己买了一台是7500元左右，手机大概换过接近10个了，这些钱加起来也足够有10万以上了，你可能一不小心就购买了这些电子产品，但是时间长了，你一回过头来想想，你为什么赚得也不少，但是为什么还是那么穷，是因为你购买这些电子产品花费了过多的金钱了，平时笔记本啥的贵重物品要保护好，我一个同事不小心丢了2台笔记本电脑，接近2万的损失啊，你净赚2万，不是那么容易的，这个窟窿不是开玩笑的，我曾经也被人偷了一个崭新的笔记本，损失1.5万左右，更糟糕的是最新的代码也丢被偷了。&lt;/div&gt;&lt;div style="margin: 10px 0px; word-break: break-all; line-height: normal! important"&gt;&lt;/div&gt;&lt;div style="margin: 10px 0px; word-break: break-all; line-height: normal! important"&gt;&lt;strong style="word-break: break-all; line-height: normal! important"&gt;03. 这年代外语、学历、职称、驾驶证还是蛮重要的。&lt;/strong&gt;&lt;/div&gt;&lt;div style="margin: 10px 0px; word-break: break-all; line-height: normal! important"&gt;想找高薪，外资&lt;a style="color: rgb(0,0,0); word-break: break-all; line-height: normal! important; text-decoration: underline" onclick="javascript:tagshow(event, '%C6%F3%D2%B5');" href="http://www.cnblogs.com/a311300/admin/javascript:;" target="_self"&gt;&lt;u style="word-break: break-all; line-height: normal! important"&gt;&lt;strong style="word-break: break-all; line-height: normal! important"&gt;企业&lt;/strong&gt;&lt;/u&gt;&lt;/a&gt;是正确的选择，在同样的打工里，外资企业的收入普遍是高的，我就想不明白，我们的赚钱能力怎么就比不过人家了，社会不断发展，将来可能去外国就像串门一样了，也说不定的，外语好将来的就业机会也会更多更广一些。&lt;/div&gt;&lt;div style="margin: 10px 0px; word-break: break-all; line-height: normal! important"&gt;学历并不代表啥，但是学历也是敲门砖，例如有300个应聘者，那至少重点本科以下的，统统不看了，因为实在是来不及看了，你再厉害也被挡在机会的门外了，同样有时候你想改行什么的，职称也很重要，最起码评个中级职称，说不定还有机会能进入大学或者政府部门还是有可能性。&lt;/div&gt;&lt;div style="margin: 10px 0px; word-break: break-all; line-height: normal! important"&gt;若有充裕的时间，应该把驾驶证考了，因为你越到后面越忙与工作家庭，没机会学车了也说不定的，平时也别光顾拼命工作，工作10年后你才发现，原来身边的人都至少硕士学历了，你被社会自动淘汰了，我现在就有这个感觉，虽然我带过很多硕士，他们的就业机会比我还好，经常能进入名牌企业，我也一直进不去。&lt;/div&gt;&lt;div style="margin: 10px 0px; word-break: break-all; line-height: normal! important"&gt;&lt;/div&gt;&lt;div style="margin: 10px 0px; word-break: break-all; line-height: normal! important"&gt;&lt;strong style="word-break: break-all; line-height: normal! important"&gt;04. 不要谈过多的女朋友，谈女朋友要看准，下手要稳准狠。&lt;/strong&gt;&lt;/div&gt;&lt;div style="margin: 10px 0px; word-break: break-all; line-height: normal! important"&gt;我谈过2个女朋友，平均每个女朋友身上的开支前后大概会有10万左右，还好我不用谈第3个女朋友了，若投资失误，那也是很残忍的，谈女朋友也会消耗很多时间精力、还会消耗很多金钱，实话的讲的确是这样的，人家女孩子也值钱啊，凭什么就那么轻易的跟你啊，我跟第一个朋友分手时，我的生活至少是倒退了3-4年，一切从零开始，一切从头开始，我劝大家谈女朋友是人生最大的一笔买卖，投资失误会有惨痛的后果，不仅仅是金钱上的损失，更会有精神、心灵上的沉重打击，大家要学会珍惜女朋友，要学会哄好女朋友，让老婆开心每一天，虽然鱼儿上钩了，不用再下鱼饵了，偶尔也别忘记放点米，这个鱼要是脱钩了，那不是开玩笑的。&lt;/div&gt;&lt;div style="margin: 10px 0px; word-break: break-all; line-height: normal! important"&gt;&lt;/div&gt;&lt;div style="margin: 10px 0px; word-break: break-all; line-height: normal! important"&gt;&lt;strong style="word-break: break-all; line-height: normal! important"&gt;05. 工作不要更换得太过于频繁，选好了行业方向最好别更换太频繁。&lt;/strong&gt;&lt;/div&gt;&lt;div style="margin: 10px 0px; word-break: break-all; line-height: normal! important"&gt;换工作，换行业方向，就像熊掰苞米一样的道理，有时候是丢了芝麻捡西瓜，有时候是丢了西瓜捡芝麻，这个道理我就不多讲了，大家都应该能明白的。&lt;/div&gt;&lt;div style="margin: 10px 0px; word-break: break-all; line-height: normal! important"&gt;&lt;/div&gt;&lt;div style="margin: 10px 0px; word-break: break-all; line-height: normal! important"&gt;&lt;strong style="word-break: break-all; line-height: normal! important"&gt;06. 要对身边的人好，要得到老板的信任、同事的认可及支持、珍惜良好的工作环境。&lt;/strong&gt;&lt;/div&gt;&lt;div style="margin: 10px 0px; word-break: break-all; line-height: normal! important"&gt;有个朋友的QQ名字很有意思，&amp;#8220;只爱陌生人&amp;#8221;，陌生人是很有意思，但是最关键时刻，还是需要靠非陌生人，你每天跟同事一起生活，要维系好身边的人。你的成功与失败，往往是你身边的30-40个人决定的。你就是世界首富，他身边也是那么不超过100个人的在左右着他的生活，当你工作10年了，没一个老板信任你，没几个要好的同事朋友，那你惨了，你在这个世界上已经是很孤单了，你的收入，其实大多是来自这些身边的朋友给你介绍的生意，不大会网上掉几个馅饼的。&lt;/div&gt;&lt;div style="margin: 10px 0px; word-break: break-all; line-height: normal! important"&gt;现在你身边的人有可能在不久的将来，给你提供很多好机会。&lt;/div&gt;&lt;div style="margin: 10px 0px; word-break: break-all; line-height: normal! important"&gt;&lt;/div&gt;&lt;div style="margin: 10px 0px; word-break: break-all; line-height: normal! important"&gt;&lt;strong style="word-break: break-all; line-height: normal! important"&gt;07. 钱很重要，但是生活质量比钱还重要，工作是很重要，但是家人比工作还重要。&lt;/strong&gt;&lt;/div&gt;&lt;div style="margin: 10px 0px; word-break: break-all; line-height: normal! important"&gt;钱不是万能的，但是没钱是万万不能的。钱赚了，身体夸了，全送给医院了，钱赚了，身心疲惫了，人活着为了啥？不就为了开开心心生活嘛？工作重要，但是失去了家人的爱，失去了女朋友，失去了老婆孩子，那这个工作有啥用了？工作很容易就换了，家人是换不了的，老婆不是想换就换的，孩子不是想换就换的，连自己的家庭都不负责的人，怎么可能对公司负责呢？我一直是这个观念，来面试时觉得工作更重要的，我们一般不录取的，那太假了，或者太不懂事了。&lt;/div&gt;&lt;div style="margin: 10px 0px; word-break: break-all; line-height: normal! important"&gt;&lt;/div&gt;&lt;div style="margin: 10px 0px; word-break: break-all; line-height: normal! important"&gt;&lt;strong style="word-break: break-all; line-height: normal! important"&gt;08. 工作累了，也别太贪玩，有时候还是需要多想想如何才能赚钱。&lt;/strong&gt;&lt;/div&gt;&lt;div style="margin: 10px 0px; word-break: break-all; line-height: normal! important"&gt;时间一晃就过去了，工作累了是可以适当放松，但是别太贪玩，10年很容易就过去了，10年后你要买房子，要娶老婆，要买车子，要生娃娃，身体也会变得脆弱一些，需要良好的生活习惯，也经不起通宵了，通宵一次，你要低迷好几天才能缓过劲儿来，跟20刚出头完全不一样了，用钱的地方多了去了，父母也会变得更老一些，可能也需要你的照顾，整个家子都指望你赚钱，别到了这个时候，你才意识到赚钱是那么的重要，更何况现在城市的房价，动不动就是100万，加上按揭的利息，你很可能需要支付150万。还可能需要装修，买车子。可能你身上的压力是200万。别觉得谈钱就俗，你要学会赚钱，要有个需要赚钱的良好意识，当然你出身富裕家庭，就不用考虑这些因素了。&lt;/div&gt;&lt;div style="margin: 10px 0px; word-break: break-all; line-height: normal! important"&gt;&lt;/div&gt;&lt;div style="margin: 10px 0px; word-break: break-all; line-height: normal! important"&gt;&lt;strong style="word-break: break-all; line-height: normal! important"&gt;09. 每天一点点进步，每月一点点积累，要敬业要爱业，我们给别人提供的也是服务。&lt;/strong&gt;&lt;/div&gt;&lt;div style="margin: 10px 0px; word-break: break-all; line-height: normal! important"&gt;总有一天，你也会有累的时候，你也会有老的时候，这时候，你要靠啥呢？就要靠你平时的积累，你10年的积累，可以打倒很多竞争对手，他们再厉害，再怎么样，也很难抵得过你10年的积累，特别是后面5-10年的积累，成果会很明显，前面的1-5年，算是做&lt;a style="color: rgb(0,0,0); word-break: break-all; line-height: normal! important; text-decoration: underline" onclick="javascript:tagshow(event, '%C8%ED%BC%FE');" href="http://www.cnblogs.com/a311300/admin/javascript:;" target="_self"&gt;&lt;u style="word-break: break-all; line-height: normal! important"&gt;&lt;strong style="word-break: break-all; line-height: normal! important"&gt;软件&lt;/strong&gt;&lt;/u&gt;&lt;/a&gt;的入门吧，除非你有高人指点，那可能2-3年就可以修成正果，软件在将来还是会值钱的，以为生活会越来越智能化，越来越数字化，软件的需求还是很有前途，最起码未来的10-20年里不用太担心失业问题了。&lt;/div&gt;&lt;div style="margin: 10px 0px; word-break: break-all; line-height: normal! important"&gt;&lt;/div&gt;&lt;div style="margin: 10px 0px; word-break: break-all; line-height: normal! important"&gt;&lt;strong style="word-break: break-all; line-height: normal! important"&gt;10. 对程序员来讲，开发思想、架构、代码就是财富，别老丢弃你的劳动成果，要学会保护你的劳动成果。&lt;/strong&gt;&lt;/div&gt;&lt;div style="margin: 10px 0px; word-break: break-all; line-height: normal! important"&gt;我大概7-8年前的代码都在手上，经常改进来改进去，维护来维护去，在一定的程度上，让我生活轻松了不少，因为我不用什么都从头来过，我只要痛苦一次，以后就要反复重复利用，软件的价值在于重复利用，而不是每个东西，都从头开发，那永远也是辛苦的程序员，这个生活质量就别提了，不管自己的代码丑还是拿不出手，要学会精心维护，每天改进一点点，每个月一个小进步，每年一个大进步，多年的积累是宝贵的，这个早晚也会给你带来丰厚的收益。&lt;/div&gt;&lt;div style="margin: 10px 0px; word-break: break-all; line-height: normal! important"&gt;&lt;/div&gt;&lt;div style="margin: 10px 0px; word-break: break-all; line-height: normal! important"&gt;&lt;strong style="word-break: break-all; line-height: normal! important"&gt;11. 当程序员要防止原地踏步，不是工作年限长了，经验就丰富了，能力就强了，年纪越大工作越难找。&lt;/strong&gt;&lt;/div&gt;&lt;div style="margin: 10px 0px; word-break: break-all; line-height: normal! important"&gt;我有一个朋友跟我开玩笑，工作5年的人，可能能力差距会很大，为什么呢？因为第一年他们干的事情都是一样的，都写程序了，2个人可能由于价值观不一样，5年后差距会很大，甚至是大到无法追赶的程度，为啥？因为还有机会的因素在里面，有的人干了5年，还是在原地踏步，天天只会写那些添加、删除、修改的代码。那你得注意了，需要不断的提高自己，才是硬道理。例如你会SQLServer，那要试着学习Oracle， 你是做C/S的，那得需要提高到B/S的，你是做单机软件的，那得需要提高到网络软件，你只关注自己的工作的，需要学会&lt;a style="color: rgb(0,0,0); word-break: break-all; line-height: normal! important; text-decoration: underline" onclick="javascript:tagshow(event, '%B9%DC%C0%ED');" href="http://www.cnblogs.com/a311300/admin/javascript:;" target="_self"&gt;&lt;u style="word-break: break-all; line-height: normal! important"&gt;&lt;strong style="word-break: break-all; line-height: normal! important"&gt;管理&lt;/strong&gt;&lt;/u&gt;&lt;/a&gt;，关心他人的工作。你是当程序员的，要试着提高当项目经理、部门经理，公司的总监等等，人有野心有目标才会不断进步，最俗的为了多赚钱，提高工作职位工作岗位，工作单位，也是可以理解的。&lt;/div&gt;&lt;div style="margin: 10px 0px; word-break: break-all; line-height: normal! important"&gt;年纪越大工作越难找，例如3-4千的工作是随便找找，玩一样，但是你30过后，最起码要找月薪上1万的工作，这样的工作是机会也少，一般小公司也给不起，还得找个好公司才可以，好公司又不是天天招聘人，天天缺好的工作岗位，说不好听点儿，小公司的老板才赚多少啊？他来钱也很不容易的，小池塘就不好容得下大鲨鱼了。&lt;/div&gt;&lt;div style="margin: 10px 0px; word-break: break-all; line-height: normal! important"&gt;&lt;/div&gt;&lt;div style="margin: 10px 0px; word-break: break-all; line-height: normal! important"&gt;&lt;strong style="word-break: break-all; line-height: normal! important"&gt;12.当创业的收入比打工还少时，那就别创业，要找比自己能力强的人创业，你不会吃亏。&lt;/strong&gt;&lt;/div&gt;&lt;div style="margin: 10px 0px; word-break: break-all; line-height: normal! important"&gt;创业的收入，比打工还少，那就是瞎扯蛋，恶搞。创业的真正意思并不是要你去吃苦没钱赚，那是忽悠无知的人的。当你创业时的收入，比打工还多，那你可以考虑创业，没有工资什么的，股份啥的，都是瞎扯蛋。&lt;/div&gt;&lt;div style="margin: 10px 0px; word-break: break-all; line-height: normal! important"&gt;不要跟自己能力还弱的人一起创业，那损失最大的，很可能就是你，要创业，也要找比自己强的人一起创业，最起码赚不到钱，还能学到不少。不会有过多的损失。别热血一沸腾就创业了，创业了，也别烧自己的钱，家人的钱，那是很不抗烧的，没几下几十万就烧干了。&lt;/div&gt;&lt;div style="margin: 10px 0px; word-break: break-all; line-height: normal! important"&gt;其实打工，也是创业的开始，每个月都能拿到钱，还可以学到知识，什么公司的股份都是空话，没几个小公司能成功，开起来了也走不了3年就分家了，都忽悠小孩子玩的，除非真的有科技含量或者是客户资源的，否则股份是一文钱不值的，就算创业每个月也按时拿工资才是硬道理。&lt;/div&gt;&lt;div style="margin: 10px 0px; word-break: break-all; line-height: normal! important"&gt;&lt;/div&gt;&lt;div style="margin: 10px 0px; word-break: break-all; line-height: normal! important"&gt;&lt;strong style="word-break: break-all; line-height: normal! important"&gt;13. 未来的生活节奏会更快，生活压力会更大，竞争会更激烈，社会服务体系会更完善。&lt;/strong&gt;&lt;/div&gt;&lt;div style="margin: 10px 0px; word-break: break-all; line-height: normal! important"&gt;在未来，我们享受良好的服务的同时，也会为别人提供更良好的服务，需要在技能上还是服务质量上的要求会更高更严格。平时要注意提高自己，不要被时代淘汰掉，我从小的朋友，一波又一波被社会无情的淘汰了，很小的时候，我出生在大草原与大山的交界处，我小时候的玩伴，还在大山里，我跟着家人杀出来了，我小学、中学、大学、工作上的、这10年，我一直很坚强的拼搏下来，很不容易的在杭州立住脚了，说实话，参加工作后的十年，也是不断拼搏，不断提高的十年。&lt;/div&gt;&lt;p&gt;&lt;strong style="font-size: 14pt"&gt;感觉很朴实的话，给新程序员朋友带来经验，和有经验的朋友交流交流曾经经历过的生活。&lt;/strong&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/a311300/aggbug/2176354.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/a311300/archive/2011/09/14/2176354.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/a311300/archive/2011/05/29/2062351.html</id><title type="text">设计模式目录</title><summary type="text">装饰者模式 Decorator 应用场景 -- 灵活地扩充对象的功能 推荐文章: “小猪逃命”游戏诠释装饰者模式 来杯咖啡例子讲述装饰者模式</summary><published>2011-05-29T13:51:00Z</published><updated>2011-05-29T13:51:00Z</updated><author><name>王景</name><uri>http://www.cnblogs.com/a311300/</uri></author><link rel="alternate" href="http://www.cnblogs.com/a311300/archive/2011/05/29/2062351.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/a311300/archive/2011/05/29/2062351.html"/><content type="html">&lt;p&gt;&lt;strong&gt;装饰者模式 Decorator&lt;/strong&gt;&lt;/p&gt; &lt;p&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; &lt;strong&gt;灵活地扩充对象的功能&lt;/strong&gt;&lt;/p&gt; &lt;p&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;strong&gt;&lt;a href="http://www.cnblogs.com/a311300/archive/2011/05/29/2062339.html"&gt;“小猪逃命”游戏诠释装饰者模式&lt;/a&gt;&amp;nbsp; &lt;a href="http://www.cnblogs.com/justinw/archive/2007/06/11/779356.html"&gt;来杯咖啡例子讲述装饰者模式&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/a311300/aggbug/2062351.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/a311300/archive/2011/05/29/2062351.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/a311300/archive/2011/05/29/2062339.html</id><title type="text">设计模式 &amp;ndash; Decorator &amp;ndash; 装饰模式[转]</title><summary type="text">“装饰模式（Decorator）”又名“包装模式（Wrapper）”，通常用来灵活地扩充对象的功能。在此之前我们可以通过类的继承来扩充父类的功能，但这种继承方式缺乏灵活性，并且会导到子类数量的快速膨胀。恰当地使用装饰模式我们会轻松实现在控制子类数量的基础上，灵活地实现对象功能的扩展。装饰模式比类的继承更灵活。 例子：1、墙上挂画（Terrylee的例子）：一个画可以挂在墙上，但通常我们会把这张画镶...</summary><published>2011-05-29T13:37:00Z</published><updated>2011-05-29T13:37:00Z</updated><author><name>王景</name><uri>http://www.cnblogs.com/a311300/</uri></author><link rel="alternate" href="http://www.cnblogs.com/a311300/archive/2011/05/29/2062339.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/a311300/archive/2011/05/29/2062339.html"/><content type="html">&lt;p&gt;“装饰模式（Decorator）”又名“包装模式（Wrapper）”，&lt;strong&gt;通常用来灵活地扩充对象的功能&lt;/strong&gt;。&lt;br&gt;在此之前我们可以通过类的继承来扩充父类的功能，但这种继承方式缺乏灵活性，并且会导到子类数量的快速膨胀。恰当地使用装饰模式我们会轻松实现在控制子类数量的基础上，灵活地实现对象功能的扩展。装饰模式比类的继承更灵活。 &lt;p&gt;&lt;strong&gt;例子：&lt;/strong&gt;&lt;br&gt;&lt;strong&gt;1、墙上挂画（Terrylee的例子）：&lt;/strong&gt;一个画可以挂在墙上，但通常我们会把这张画镶上画框，蒙上玻璃，然后再挂在墙上。这里的画框和玻璃就是对画的装饰，装饰后成为一个物体，后来实际挂在墙上的是画框。 &lt;p&gt;&lt;img border="0" src="http://hiphotos.baidu.com/hins%5Fpan/pic/item/814ce5d26bbff26e960a162a.jpg"&gt; &lt;p&gt;&lt;strong&gt;2、“小猪逃命”游戏：&lt;/strong&gt;一只小猪和一只灰狼，小猪最多5条命，灰狼每咬到小猪一次，小猪就要少一条命，小猪的任务是要逃过灰狼的追咬到猪栏。在逃的过程中小猪可以吃到三种苹果，吃“红苹果”可以给小猪加上保护罩，吃“绿苹果”可以加快小猪奔跑速度，吃“黄苹果”可以使猪趟着水跑。小猪如果吃多种苹果的话，小猪可以拥有多种苹果提供的功能。&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 这个例子如果用类的继承来实现的话那可就麻烦了，你需要为小猪派生3*2*1=6个子类（有保护罩的小猪，奔跑速度加快的小猪，会趟水的小猪，既有保护罩又会趟水的小猪，奔跑速度快且会趟水的小猪，有保护罩且奔跑速度快的小猪，有保护罩、奔跑速度快且会趟水的小猪），当小猪吃到不同的苹果，你就把小猪换成相应的子类实例（好麻烦）。如果有四种苹果的话那你要为小猪派生4*3*2*1=24个子类，如果有五种苹果......“子类复子类，子类何其多”。&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 如果使用装饰模式的那就不用派生诸多子类了，当小猪每吃到一个苹果，我们就用装饰模式给小猪加一个动态增加一个新功能即可。 &lt;p&gt;&lt;strong&gt;结构图：&lt;/strong&gt; &lt;p&gt;&lt;img border="0" src="http://hiphotos.baidu.com/hins%5Fpan/pic/item/9df38010db2bf44ab8127b2a.jpg"&gt; &lt;p&gt;&lt;strong&gt;抽象构件（Component）角色&lt;/strong&gt;：给出一个抽象接口，以规范准备接收附加责任的对象和抽象装饰器。&lt;br&gt;&lt;strong&gt;具体构件（ConcreteComponent）角色&lt;/strong&gt;：定义一个将要接收附加责任的类。&lt;br&gt;&lt;strong&gt;抽象装饰（Decorator）角色&lt;/strong&gt;：持有一个构件（Component）对象的实例，以用来对它进行装饰，并定义一个与抽象构件接口一致的接口。&lt;br&gt;&lt;strong&gt;具体装饰（Concrete Decorator）角色&lt;/strong&gt;：负责给构件对象"加上"附加的功能。 &lt;p&gt;&lt;strong&gt;结构图代码：&lt;/strong&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //抽象构件，定义了具体构件和抽象装饰要实现的方法&lt;br&gt;interface Component&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; void Operation();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //定义具体构件&lt;br&gt;class ConcreteComponent&lt;strong&gt; : Component&lt;/strong&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void Operation()&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine("ConcreteComponent Operation");&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //定义抽象装饰者。抽象装饰者也实现了抽象构件的接口&lt;br&gt;abstract class Decorator &lt;strong&gt;: Component&lt;br&gt;&lt;/strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //把一个抽象构件作为抽象装饰的成员变量。&lt;br&gt;&lt;strong&gt;protected Component comp&lt;/strong&gt;;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //在抽象装饰者的构造函数中为抽象构件初始化。&lt;br&gt;public Decorator(Component c)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.comp = c;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //还未实现的接口的方法。&lt;br&gt;public abstract void &lt;strong&gt;Operation&lt;/strong&gt;();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //具体装饰者A，继承自抽象装饰。&lt;br&gt;class ConcreteDecoratorA : Decorator&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; private string &lt;strong&gt;addedState&lt;/strong&gt;; //具体装饰者中新增的成员变量&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public ConcreteDecoratorA(Component c) : base(c) { }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public string &lt;strong&gt;AddedState&lt;/strong&gt; //具体装饰者中新增的属性&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; set&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&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; addedState = value;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //具体装饰者实现了接口中定义的方法&lt;br&gt;public override void Operation()&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&lt;strong&gt;comp.Operation();&lt;/strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //可以调用原构件对象的Operation方法。&lt;br&gt;Console.WriteLine("ConcreteDecoratorA Operation {0}",addedState);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //具体装饰者B，继承自抽象装饰。&lt;br&gt;class ConcreteDecoratorB&lt;strong&gt; : Decorator&lt;/strong&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public ConcreteDecoratorB(Component c) : base(c) { }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public override void Operation()&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&lt;strong&gt;comp.Operation();&lt;/strong&gt; //可以调用原构件对象的Operation方法。&lt;br&gt;Console.WriteLine("ConcreteDecoratorB Operation ");&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 具体装饰者实现了接口中定义的方法&lt;br&gt;public void &lt;strong&gt;AddedBehavior&lt;/strong&gt;()&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine("This is Added Behavior");&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;class Client&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public static void Main()&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp; //原生的具体构件&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ConcreteComponent cc = new ConcreteComponent();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cc.Operation();&lt;br&gt;//把原生的具体构件用具体装饰者A进行一次包装&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ConcreteDecoratorA cda = new ConcreteDecoratorA(&lt;strong&gt;cc&lt;/strong&gt;);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cda.AddedState = "Decorator OK ";&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cda.Operation();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //把原生的具体构件用具体装饰者B进行一次包装&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ConcreteDecoratorB cdb = new ConcreteDecoratorB(&lt;strong&gt;cc&lt;/strong&gt;);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cdb.AddedBehavior();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cdb.Operation();&lt;br&gt;//把被A包装完的具体构件再用用具体装饰者B进行二次包装&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ConcreteDecoratorB cdbcda = new ConcreteDecoratorB(&lt;strong&gt;cda&lt;/strong&gt;);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cdbcda.Operation();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 运行结果 &lt;p&gt;&lt;img border="0" src="http://hiphotos.baidu.com/hins%5Fpan/pic/item/55d90a1112b27ba6c2ce792a.jpg"&gt; &lt;p&gt;说明：&lt;br&gt;&lt;strong&gt;Decorator与Component之间既是Is a...的继承关系，又是Has a...的组合关系。使用具体装饰类(ConcreteDecorator)来装饰具体构件对象(ConcreteComponent)，装饰完的对象依旧是个Component类型。&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Decorator模式解决的是类的功能的多向扩展，而不是单纯的类的继承。&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Decorator模式提供了比继承更灵活的功能扩展，通过使用不同具体装饰对构件对象的排列组合地包装，能够不同功能的组合。&lt;br&gt;&lt;/strong&gt;&lt;br&gt;&lt;strong&gt;小猪逃命游戏示意代码：&lt;/strong&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //抽象构件，小猪和装饰者的共同抽象接口&lt;br&gt;interface IUnit&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int Count { get;} //属性，取出小猪现有几条命&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; void move();&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //方法，小猪跑的方法&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; void attacked(); //方法，小猪被攻击的方法&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //具体构件，小猪类&lt;br&gt;class Pig &lt;strong&gt;: IUnit&lt;br&gt;&lt;/strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; private int pigCounts = 5;&amp;nbsp;&amp;nbsp; //一共有5条命&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public int &lt;strong&gt;Count&lt;/strong&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; get&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&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; return pigCounts;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void &lt;strong&gt;move&lt;/strong&gt;()&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine("The Pig Is Moving......");&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void &lt;strong&gt;attacked&lt;/strong&gt;()&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&lt;strong&gt;pigCounts--;&lt;/strong&gt; //小猪受到攻击后，减一条命。&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine("The Pig Count Is :{0}", pigCounts); //显示小猪还剩下几条命&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //&lt;strong&gt;抽象装饰类，&lt;/strong&gt;用来装饰小猪的抽象类&lt;br&gt;abstract class &lt;strong&gt;PigDecorator : IUnit&lt;br&gt;&lt;/strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&lt;strong&gt;protected IUnit pig;&amp;nbsp;&amp;nbsp; &lt;/strong&gt; //小猪作为装饰类的成员变量&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public PigDecorator(IUnit iu) //在构造函数中为成员变量初始化&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; pig = iu;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public int Count&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; get&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&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; return pig.Count;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public abstract void move();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public abstract void attacked();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //给小猪加上保护罩&lt;br&gt;class ProtectedPig&lt;strong&gt; : PigDecorator&lt;br&gt;&lt;/strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public ProtectedPig(IUnit u)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : base(u)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public override void move()&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&lt;strong&gt;pig.move();&lt;/strong&gt; //调用小猪跑的方法。让小猪跑&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public override void&lt;strong&gt; attacked()&lt;br&gt;&lt;/strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;//重写小猪被攻击的方法，这里被攻击后&lt;strong&gt;生命值不减少&lt;/strong&gt;。直接显示小猪剩的命。&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine("The Pig Count Is :{0}", pig.Count);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //让小猪跑快的装饰器&lt;br&gt;class FasterPig &lt;strong&gt;: PigDecorator&lt;br&gt;&lt;/strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public FasterPig(IUnit u)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : base(u)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public override void move()&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;//重写小猪跑的方法，让它跑得更快。&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine("The Pig Is Moving Faster Now......");&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public override void attacked()&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&lt;strong&gt;pig.attacked();&lt;/strong&gt; //当小猪被攻击时，调用小猪被攻击的方法。&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //让小猪会游泳的装饰器&lt;br&gt;class SwimPig &lt;strong&gt;: PigDecorator&lt;br&gt;&lt;/strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public SwimPig(IUnit u)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : base(u)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public override void move()&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; pig.move(); //调用小猪跑的方法。&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public override void attacked()&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; pig.attacked(); //调用小猪被攻击的方法&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;//给小猪加上会游泳的功能&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void &lt;strong&gt;swim()&lt;/strong&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine("The Pig Can Swim Now ......");&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //红苹果类&lt;br&gt;class RedApple&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public ProtectedPig change(IUnit u)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp; //用保护罩装饰器来包装小猪。&lt;br&gt;&lt;strong&gt;ProtectedPig p = new ProtectedPig(u);&lt;br&gt;&lt;/strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return p;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //绿苹果&lt;br&gt;class GreenApple&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public FasterPig change(IUnit u)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;//让跑快的装饰器来包装小猪&lt;br&gt;&lt;strong&gt;FasterPig p = new FasterPig(u);&lt;br&gt;&lt;/strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return p;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //黄苹果&lt;br&gt;class YellowApple&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //用游泳的装饰器来包装小猪&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public SwimPig change(IUnit u)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&lt;strong&gt;SwimPig p = new SwimPig(u);&lt;br&gt;&lt;/strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return p;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //灰狼类&lt;br&gt;class Monster&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;//攻击小猪的方法&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void attack(IUnit u)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&lt;strong&gt;u.attacked();&lt;/strong&gt; //调用小猪被攻击的方法。&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;class Client&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public static void Main(string[] args)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; IUnit pig1 = new Pig();//一只原生的小猪&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Monster m = new Monster();&amp;nbsp; //一只灰狼&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; pig1.move(); //小猪开始跑&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //灰狼攻击小猪，调用小猪被攻击的方法，小猪生命减1并显示剩余的生命。&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; m.attack(pig1);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; RedApple r = new RedApple();&amp;nbsp;&amp;nbsp; //出现一只红苹果&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; pig1 = r.change(pig1); //小猪吃到红苹果，红苹果把小猪用“保护罩”装饰成“受保护的小猪”&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; pig1.move();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; m.attack(pig1); //此时灰狼再咬小猪的时候，发现小猪由于已经被“保护罩”装饰，并未减少生命力&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; GreenApple g = new GreenApple();&amp;nbsp;&amp;nbsp;&amp;nbsp; //出现一只绿苹果&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; pig1 = g.change(pig1); //有“保护罩”的小猪又吃了一个绿苹果，此时小猪既有“保护罩”装饰，又有“快速奔跑”装饰。&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; pig1.move(); //显示小猪正在快速奔跑&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; m.attack(pig1); //小猪受到攻击，生命力仍不减少。&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; YellowApple y = new YellowApple();//出现一只黄苹果&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; pig1 = y.change(pig1); //“保护罩”“快速奔跑”的小猪又加上了“会游泳”这个包装。&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ((SwimPig)pig1).move();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ((SwimPig)pig1).swim();&amp;nbsp; //小猪在游泳&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; m.attack(pig1); //小猪受到攻击生命力仍不减&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Decorator模式采用对象组合而非继承的手法，实现了在运行时动态的扩展对象功能的能力，而且可以根据需要扩展多个功能，避免了单独使用继承带来的“灵活性差”和“多子类衍生问题”。同时它很好地符合面向对象设计原则中“优先使用对象组合而非继承”和“开放-封闭”原则。(车延禄) &lt;p&gt;&amp;nbsp; &lt;p&gt;DotNet中的例子：&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 缓冲流(BufferedStream) &lt;p&gt;&lt;img border="0" src="http://hiphotos.baidu.com/hins%5Fpan/pic/item/e49c8efc53a3211fd7887d2a.jpg"&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; EnterpriseLibrary中的CommandWrapper &lt;p&gt;&lt;img border="0" src="http://hiphotos.baidu.com/hins%5Fpan/pic/item/f1da993e343417987c1e712a.jpg"&gt;&lt;img src="http://www.cnblogs.com/a311300/aggbug/2062339.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/a311300/archive/2011/05/29/2062339.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/a311300/archive/2011/05/25/2057459.html</id><title type="text">&amp;lt;&amp;lt;一线架构师实践指南&amp;gt;&amp;gt;读书笔记之二----PA阶段</title><summary type="text">1.在架构设计之初,就全盘考虑架构设计要重点支持的关键质量目标. 2.在第一时间就判断关键质量之间有没有冲突关系,并制定权衡取舍策略.冲突关系见质量属性关系矩阵. 架构师需要把握需求技能的缺失.软件架构师不必是需求捕获专家,也不必是编写&lt;&lt;软件需求规格说明书&gt;&gt;的专家,但他一定应在需求分类、需求折衷和需求变更的研究方面的专家，否则他和优秀的架构师相比就输在了起跑线上。 功能需求、质量属性及约束共同...</summary><published>2011-05-25T14:33:00Z</published><updated>2011-05-25T14:33:00Z</updated><author><name>王景</name><uri>http://www.cnblogs.com/a311300/</uri></author><link rel="alternate" href="http://www.cnblogs.com/a311300/archive/2011/05/25/2057459.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/a311300/archive/2011/05/25/2057459.html"/><content type="html">&lt;p&gt;1.在架构设计之初,就全盘考虑架构设计要重点支持的关键质量目标.&lt;/p&gt; &lt;p&gt;2.在第一时间就判断关键质量之间有没有冲突关系,并制定权衡取舍策略.冲突关系见质量属性关系矩阵.&lt;/p&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/a311300/201105/201105252233238013.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/a311300/201105/201105252233251752.png" width="383" height="296"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;架构师需要把握需求技能的缺失.软件架构师不必是需求捕获专家,也不必是编写&amp;lt;&amp;lt;软件需求规格说明书&amp;gt;&amp;gt;的专家,但他一定应在需求分类、需求折衷和需求变更的研究方面的专家，否则他和优秀的架构师相比就输在了起跑线上。&lt;/p&gt; &lt;p&gt;功能需求、质量属性及约束共同决定了架构。对这3类需求的把握是否到位、设计决策是否对路，是架构设计成败的关键所在！&lt;/p&gt; &lt;p&gt;可以使用需求分类法和二维需求观与ADMEMS矩阵方法分析。&lt;/p&gt; &lt;table border="1" cellspacing="1" cellpadding="2" width="569"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td valign="top" width="100"&gt;&amp;nbsp;&lt;/td&gt; &lt;td valign="top" width="100"&gt;功能&lt;/td&gt; &lt;td valign="top" width="122"&gt;质量&lt;/td&gt; &lt;td valign="top" width="240"&gt;约束&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign="top" width="100"&gt;业务级需求&lt;/td&gt; &lt;td valign="top" width="100"&gt;* 适应业务变化&lt;/td&gt; &lt;td valign="top" width="122"&gt;* 4个月交付上线&lt;/td&gt; &lt;td valign="top" width="240"&gt;* 严格执行人行统一规定的利率&lt;br&gt;* 与原有行长办公系统集成&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign="top" width="100"&gt;用户级需求&lt;/td&gt; &lt;td valign="top" width="100"&gt;* 利率调整功能&lt;/td&gt; &lt;td valign="top" width="122"&gt;&amp;nbsp;&lt;/td&gt; &lt;td valign="top" width="240"&gt;* 分所操作人员水平不高&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign="top" width="100"&gt;开发级需求&lt;/td&gt; &lt;td valign="top" width="100"&gt;&amp;nbsp;&lt;/td&gt; &lt;td valign="top" width="122"&gt;* 可修改性&lt;br&gt;* 可扩展性&lt;br&gt;* 互操作性&lt;/td&gt; &lt;td valign="top" width="240"&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;p&gt;作者提出在PA阶段，使用以ADMEMS矩阵为核心的“四步法”：&lt;/p&gt; &lt;p&gt;1、需求结构化&lt;/p&gt; &lt;p&gt;2、分析约束影响&lt;/p&gt; &lt;p&gt;3、确定关键质量&lt;/p&gt; &lt;p&gt;4、确定关键功能&lt;/p&gt;&lt;img src="http://www.cnblogs.com/a311300/aggbug/2057459.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/a311300/archive/2011/05/25/2057459.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/a311300/archive/2011/05/25/2057426.html</id><title type="text">大数据量简单数据查询设计思考</title><summary type="text">今天去面试一家企业,出了一道题,说他们的数据格式是以不同企业、产品类型、产品、批次、编码的形式需要存储，但是量级在10亿以上。问什么样的方式进行检索最快。希望提升性能。另外，支持多种角度，比如按企业、按产品类型、按具体的编码等角度查询。都希望尽快出结果。 对于这种结构明晰的数据，我觉得是有一定的规则可循的。比如按照以下格式： 企业（8位码）+产品类型（6位码）+产品编号（8位码）+批次（5位吗）...</summary><published>2011-05-25T14:17:00Z</published><updated>2011-05-25T14:17:00Z</updated><author><name>王景</name><uri>http://www.cnblogs.com/a311300/</uri></author><link rel="alternate" href="http://www.cnblogs.com/a311300/archive/2011/05/25/2057426.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/a311300/archive/2011/05/25/2057426.html"/><content type="html">&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 今天去面试一家企业,出了一道题,说他们的数据格式是以不同企业、产品类型、产品、批次、编码的形式需要存储，但是量级在10亿以上。问什么样的方式进行检索最快。希望提升性能。另外，支持多种角度，比如按企业、按产品类型、按具体的编码等角度查询。都希望尽快出结果。&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 对于这种结构明晰的数据，我觉得是有一定的规则可循的。比如按照以下格式：&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 企业（8位码）+产品类型（6位码）+产品编号（8位码）+批次（5位吗）+编码（15~35位码），这样可以对所以数据进行规范化。并对这些数据进行索引。&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 如果是按照企业查询，那么仅对前八位进行查询即可。当然对所有企业也会有单独的存储或者建立单独的索引。&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 如果是知道企业和产品，则可以定位前22位。当然对于产品类型与产品的关联也会进行单独的索引。&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 如果知道具体的编码，则更方便，直接查询23位以后的若干位。&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 然后将定义规则的统一码，放到Cassandra中，并以统一码为key值。那么定位起来是相当快的。Cassandra对于一次写入，多次读取的场景是很适合的。并且数量级在50亿以下。性能上没有问题,facebook做过测试。在此量级下，性能是很快速的。&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 在Cassandra的value中，可以存储一定的查询信息，也可以存储对应具体的存储位置。这样更利于具体数据的定位。&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 具体数据的存储，可以按照横纵向划分后的固定格式，存储到关系型数据库中。&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 当然，对于数字的某个区间，应该还有更快的查询方法，还有优化的潜质。欢迎大家拍砖。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/a311300/aggbug/2057426.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/a311300/archive/2011/05/25/2057426.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/a311300/archive/2011/05/22/2053877.html</id><title type="text">&amp;lt;&amp;lt;一线架构师实践指南&amp;gt;&amp;gt;读书笔记之一----总体概览</title><summary type="text">一个好的架构师需要有质疑精神。不仅需要形成自己的方法体系，而且需要去质疑。这样才能挖掘出潜在的问题和非功能需求。另外这种独立思考，善于观查，善于总结的特性，让作者针对架构师碰到的问题提出了一个方法体系概念.并针对时间轴,提出先分阶段，然后在各阶段用不同的视图（视图理解为角度）来分析。不同的视图可以发现不同的问题，对于问题的解决有不同的方法，而解决问题的方法不只一种。且各种方法可以独立，也可以形成...</summary><published>2011-05-22T14:21:00Z</published><updated>2011-05-22T14:21:00Z</updated><author><name>王景</name><uri>http://www.cnblogs.com/a311300/</uri></author><link rel="alternate" href="http://www.cnblogs.com/a311300/archive/2011/05/22/2053877.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/a311300/archive/2011/05/22/2053877.html"/><content type="html">&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 一个好的架构师需要有质疑精神。不仅需要形成自己的方法体系，而且需要去质疑。这样才能挖掘出潜在的问题和非功能需求。另外这种独立思考，善于观查，善于总结的特性，让作者针对架构师碰到的问题提出了一个方法体系概念.并针对时间轴,提出先分阶段，然后在各阶段用不同的视图（视图理解为角度）来分析。不同的视图可以发现不同的问题，对于问题的解决有不同的方法，而解决问题的方法不只一种。且各种方法可以独立，也可以形成前置后置关联，也可以组合。既可以形成单独的方法论也可以组成方法体系。&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 作者提出自己的ADMEMS（Architectural Design Method has been Extended to Method System）架构设计方法已经扩展到方法体系。在这个方法体系中，主要是3个阶段，1个贯穿环节。即：&lt;/p&gt; &lt;p&gt;从需求到&lt;/p&gt; &lt;p&gt;-〉Pre-architecture 阶段（简称PA阶段）&lt;/p&gt; &lt;p&gt;-〉Conceptual Architecture 阶段（简称CA阶段）&lt;/p&gt; &lt;p&gt;-&amp;gt; Refined Architecture 阶段（简称RA阶段）&lt;/p&gt; &lt;p&gt;-&amp;gt; 架构&lt;/p&gt; &lt;p&gt;一个贯彻环节，指的是对非功能目标的考虑。&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;PA阶段：&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;目标：全面理解需求。&lt;/p&gt; &lt;p&gt;方法：ADMEMS矩阵（需求层次-需求方面矩阵）。帮助架构师告别需求列表的陈旧方式，顺利过渡到二维需求观，借此避免遗漏需求。并进一步理清需求间关系和发现衍生需求。&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/a311300/201105/201105222254226074.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/a311300/201105/20110522225424336.png" width="409" height="311"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;&lt;strong&gt;CA阶段：&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;概念架构 不等于 理想化架构。所以，必须考虑包括功能、质量、约束在内的所有方面的需求。&lt;/p&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/a311300/201105/201105222254275089.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/a311300/201105/201105222254298479.png" width="402" height="284"&gt;&lt;/a&gt; &lt;/p&gt; &lt;blockquote style='border:2px solid #EFEFEF;color:#333333;padding:5px 10px;'&gt; &lt;p&gt;&lt;strong&gt;RA阶段：&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;细化架构是相对于概念架构而言的。总体方法为5视图方法。&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/a311300/201105/20110522225430855.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/a311300/201105/201105222254312085.png" width="398" height="219"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;一个贯穿环节：持续关注非功能需求：“目标--场景--决策”表方法。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/a311300/aggbug/2053877.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/a311300/archive/2011/05/22/2053877.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/a311300/archive/2011/05/20/2051770.html</id><title type="text">[转]Apache Cassandra在Windows下安装、运行</title><summary type="text">大名鼎鼎的Apache Cassandra是Java写的NoSQL数据库，所以可夸平台是必然性，在Windows XP下运行绝对不是问题，只需要： 1.下载、安装 Sun Java JDK 6.0+， 2.下载、解压 Cassandra后可直接运行，下载地址 点击这里， 3.在CMD窗口下输入 set CASSANDRA_HOME=x:\you_cassandra_dir，或者在Windows系统...</summary><published>2011-05-20T02:49:00Z</published><updated>2011-05-20T02:49:00Z</updated><author><name>王景</name><uri>http://www.cnblogs.com/a311300/</uri></author><link rel="alternate" href="http://www.cnblogs.com/a311300/archive/2011/05/20/2051770.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/a311300/archive/2011/05/20/2051770.html"/><content type="html">&lt;p&gt;大名鼎鼎的Apache Cassandra是Java写的NoSQL数据库，所以可夸平台是必然性，在Windows XP下运行绝对不是问题，只需要：&lt;br&gt;&amp;nbsp; 1.下载、安装 Sun Java JDK 6.0+， &lt;p&gt;&amp;nbsp; 2.下载、解压 Cassandra后可直接运行，下载地址 点击&lt;a href="http://apache.freelamp.com/cassandra/0.6.1/apache-cassandra-0.6.1-bin.tar.gz"&gt;这里&lt;/a&gt;， &lt;p&gt;&amp;nbsp; 3.在CMD窗口下输入 set CASSANDRA_HOME=x:\you_cassandra_dir，或者在Windows系统中&lt;strong&gt;设置环境变量&lt;/strong&gt;，如果不设置将会提示如下错误信息：&lt;br&gt;Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/cassandra/&lt;br&gt;cli/CliMain Caused by: java.lang.ClassNotFoundException: org.apache.cassandra.cli.CliMain。所以切记，运行Cassandra必须先设置一下系统环境变量。 &lt;p&gt;&amp;nbsp; 4.双击 bin\cassandra.bat启动服务器端，服务器端启动效果如图所示：&lt;br&gt;&lt;img alt="http://www.javabloger.com/images/article_pic/2010-04/cassandra6-windows-1.png" src="http://www.javabloger.com/images/article_pic/2010-04/cassandra6-windows-1.png"&gt; &lt;p&gt;5.双击bin\cassandra-cli.bat运行，进入客户端程序，输入 connect localhost/9160 命令连接服务器，查看keyspaces，再查看具体keyspace详细信息，运行效果如图所示：&lt;br&gt;&lt;img alt="http://www.javabloger.com/images/article_pic/2010-04/cassandra6-windows-2.png" src="http://www.javabloger.com/images/article_pic/2010-04/cassandra6-windows-2.png"&gt; &lt;p&gt;–end– &lt;img src="http://www.cnblogs.com/a311300/aggbug/2051770.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/a311300/archive/2011/05/20/2051770.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/a311300/archive/2011/05/03/2035247.html</id><title type="text">收集需求</title><summary type="text">收集需求是为实现项目目标而定义并记录干系人的需求的过程。仔细掌握和管理项目需求与产品需求，对促进项目成功有重要作用。需求是指发起人、客户和其他干系人的已量化且记录下来的需要与期望。项目一旦开始，就应该足够详细地探明、分析和记录这些需求，以便日后进行测量。收集需求旨在定义和管理客户期望。需求是工作分解结构的基础。成本、进度和质量规划也都要在这些需求的基础上进行。需求开发始于对项目章程（见4.1.3...</summary><published>2011-05-03T05:58:00Z</published><updated>2011-05-03T05:58:00Z</updated><author><name>王景</name><uri>http://www.cnblogs.com/a311300/</uri></author><link rel="alternate" href="http://www.cnblogs.com/a311300/archive/2011/05/03/2035247.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/a311300/archive/2011/05/03/2035247.html"/><content type="html">&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 收集需求是为实现项目目标而定义并记录干系人的需求的过程。仔细掌握和管理项目需求与产品需求，对促进项目成功有重要作用。需求是指发起人、客户和其他干系人的已量化且记录下来的需要与期望。项目一旦开始，就应该足够详细地探明、分析和记录这些需求，以便日后进行测量。收集需求旨在定义和管理客户期望。需求是工作分解结构的基础。成本、进度和质量规划也都要在这些需求的基础上进行。需求开发始于对项目章程（见4.1.3.1 节）和干系人登记册（见10.1.3.1 节）中相关信息的分析。 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/a311300/201105/20110503135546940.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="]UT(A)J4X]~$UKF7$BI~LK5" border="0" alt="]UT(A)J4X]~$UKF7$BI~LK5" src="http://images.cnblogs.com/cnblogs_com/a311300/201105/201105031355479969.jpg" width="379" height="221"&gt;&lt;/a&gt; &lt;p&gt;许多组织把需求分为项目需求和产品需求。项目需求包括商业需求、项目管理需求、交付需求等。产品需求则包括技术需求、安全需求、性能需求等。 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/a311300/201105/201105031356088870.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="%{VHSZT_7]9D($_6N1RR%PI" border="0" alt="%{VHSZT_7]9D($_6N1RR%PI" src="http://images.cnblogs.com/cnblogs_com/a311300/201105/201105031356166898.jpg" width="412" height="252"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;上图显示了收集需求过程的输入、工具与技术和输出.&lt;/p&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/a311300/201105/201105031356304640.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="SOP}$${WFQX($7TJ$]4$[}0" border="0" alt="SOP}$${WFQX($7TJ$]4$[}0" src="http://images.cnblogs.com/cnblogs_com/a311300/201105/201105031356311999.jpg" width="411" height="273"&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;收集需求：输入&lt;br&gt;&lt;/strong&gt;1．项目章程&lt;br&gt;可从项目章程中了解总体项目需求以及关于项目产品的总体描述，并据此制定详细的产品需求。项目章程已在4.1 节讨论。&lt;br&gt;2．干系人登记册&lt;br&gt;干系人登记册可用来识别那些能提供详细的项目和产品需求信息的干系人。干系人登记册将在10.1 节讨论。 &lt;p&gt;&lt;strong&gt;收集需求：工具与技术&lt;br&gt;&lt;/strong&gt;1．访谈&lt;br&gt;访谈是一种通过与干系人直接交谈，来获得信息的正式或非正式方法。访谈的典型做法是向被访者提出预设和即兴的问题，并记录他们的回答。通常采取“一对一”的形式，但也可以有多个被访者和/或多个访问者共同参与。访谈有经验的项目参与者、干系人和主题专家，有助于识别和定义项目可交付成果的特征和功能。 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/a311300/201105/201105031356586029.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="~22C7F3C1(L3U5SJ3Q]RHJ6" border="0" alt="~22C7F3C1(L3U5SJ3Q]RHJ6" src="http://images.cnblogs.com/cnblogs_com/a311300/201105/201105031357031139.jpg" width="314" height="269"&gt;&lt;/a&gt; &lt;p&gt;2．焦点小组会议&lt;br&gt;焦点小组会议是把预先选定的干系人和主题专家集中在一起，了解他们对所提议产品、服务或成果的期望和态度。由一位受过训练的主持人引导大家进行互动式讨论。焦点小组会议往往比“一对一”的访谈更热烈。 &lt;p&gt;3．引导式研讨会&lt;br&gt;通过邀请主要的跨职能干系人一起参加会议，引导式研讨会对产品需求进行集中讨论与定义。研讨会是快速定义跨职能需求和协调干系人差异的重要技术。由于群体互动的特点，被有效引导的研讨会有助于建立信任、促进关系、改善沟通，从而有利于参加者达成一致意见。该技术的另一好处是，能够比单项会议更快地发现和解决问题。 &lt;p&gt;例如，在软件开发行业，就有一种被称为“联合应用开发（或设计）（Joint Application Development，JAD）”的引导式研讨会。这种研讨会注重把用户和开发团队集中在一起，来改进软件开发过程。在制造行业，则使用“质量功能展开（Quality Function Deployment，QFD）”这种引导式研讨会，来帮助确定新产品的关键特征。QFD 从收集客户需求（又称“顾客声音”）开始，然后客观地对这些需求进行分类和排序，并为实现这些需求而设置目标。 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/a311300/201105/20110503135707121.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="LOZBK~%SEWABP(@6SSCRA2N" border="0" alt="LOZBK~%SEWABP(@6SSCRA2N" src="http://images.cnblogs.com/cnblogs_com/a311300/201105/201105031357108428.jpg" width="333" height="218"&gt;&lt;/a&gt; &lt;p&gt;4．群体创新技术&lt;br&gt;可以组织一些群体活动来识别项目和产品需求。下面是一些常用的群体创新技术：&lt;br&gt; 头脑风暴法。用来产生和收集对项目需求与产品需求的多种创意的一种技术。&lt;/p&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/a311300/201105/20110503135715691.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="L%_[X$M67LQ(MQRG1W}}`~8" border="0" alt="L%_[X$M67LQ(MQRG1W}}`~8" src="http://images.cnblogs.com/cnblogs_com/a311300/201105/201105031357192803.jpg" width="299" height="212"&gt;&lt;/a&gt;&lt;br&gt; 名义小组技术。通过投票来排列最有用的创意，以便进行进一步的头脑风暴或优先排序。名义小组技术是头脑风暴法的深化应用。&lt;br&gt; 德尔菲技术。由一组选定的专家回答问卷，并对每一轮需求收集的结果再给出反馈。专家的答复只能交给主持人，以保持匿名状态。&lt;br&gt; 概念/思维导图。把从头脑风暴中获得的创意，用一张简单的图联系起来，以反映这些创意之间的共性与差异，从而引导出新的创意。&lt;/p&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/a311300/201105/201105031357202322.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="B[)KJ`08KA]5{3FN@BWB4B8" border="0" alt="B[)KJ`08KA]5{3FN@BWB4B8" src="http://images.cnblogs.com/cnblogs_com/a311300/201105/20110503135722488.jpg" width="303" height="211"&gt;&lt;/a&gt;&lt;br&gt; 亲和图。这种技术可以将大量创意分类，以便审查和分析。 &lt;p&gt;5．群体决策技术&lt;br&gt;群体决策就是为达成某种期望结果而对多个未来行动方案进行评估。&lt;br&gt;群体决策技术可用来开发产品需求，以及对产品需求进行归类和优先排序。&lt;br&gt;达成群体决策的方法很多，例如：&lt;br&gt; 一致同意。每个人都同意某个行动方案。&lt;br&gt; 大多数原则。获得群体中50%以上的人的支持。&lt;br&gt; 相对多数原则。根据群体中相对多数者的意见做出决定，即便未能获得一部分人的支持。&lt;br&gt; 独裁。某一个人为群体做出决策。&lt;br&gt;在需求收集过程中，几乎可采用上述任何一种决策方法进行群体决策。 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/a311300/201105/201105031357233944.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="U3MU$5{K`S_I$VF`SS)SLW3" border="0" alt="U3MU$5{K`S_I$VF`SS)SLW3" src="http://images.cnblogs.com/cnblogs_com/a311300/201105/201105031357245240.jpg" width="369" height="222"&gt;&lt;/a&gt; &lt;p&gt;6．问卷调查&lt;br&gt;问卷调查是指通过设计书面问题，向为数众多的受访者快速收集信息。如果受众众多、需要快速完成调查，并想要使用统计分析法，就适宜采用问卷和/或调查方法。&lt;/p&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/a311300/201105/201105031357282925.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="I7_]@$(F`K9)`0UXR}IX3F1" border="0" alt="I7_]@$(F`K9)`0UXR}IX3F1" src="http://images.cnblogs.com/cnblogs_com/a311300/201105/201105031357302727.jpg" width="368" height="230"&gt;&lt;/a&gt; &lt;p&gt;7．观察&lt;br&gt;观察是指直接观察个人在各自的环境中如何开展工作和实施流程。当产品使用者难以或不愿说明他们的需求时，就特别需要通过观察来了解细节。观察，也称为“工作跟踪”，通常由观察者从外部来观察使用者的工作。观察也可以由“参与观察者（Participant observer）”进行。“参与观察者”需要实际执行一个流程或程序，体验该流程或程序是如何实施的，以便挖掘出隐藏的要求。&lt;/p&gt; &lt;p&gt;8．原型法&lt;br&gt;原型法是指在实际制造产品之前，先造出该产品的实用模型，并据此征求对需求的反馈意见。原型是有形的实物，它使干系人有机会体验最终产品的模型，而不是只讨论抽象的需求陈述。原型法符合渐进明细的理念，因为原型需要重复经过制作、试用、反馈、修改等过程。在经过足够的重复之后，就可以从原型中获得足够完整的需求，并进而进入设计或制造阶段。 &lt;p&gt;&lt;strong&gt;收集需求：输出&lt;/strong&gt; &lt;p&gt;1．需求文件&lt;br&gt;需求文件描述各种单一的需求将如何满足与项目相关的业务需求。一开始，可能只有概括性的需求，然后随着信息的增加而逐步细化。只有明确的（可测量和可测试的）、可跟踪的、完整的、相互协调的，且主要干系人愿意认可的需求，才能作为基准。需求文件的格式多种多样，既可以是一份按干系人和优先级分类列出全部需求的简单文件，也可以是一份包括内容提要、细节描述和附件等的详细文件。&lt;br&gt;需求文件的组成部分包括（但不限于）：&lt;br&gt; 业务需求或需抓住的机遇，描述当前局面的不足以及启动项目的原因；&lt;br&gt; 可跟踪的业务目标和项目目标；&lt;br&gt; 功能要求，描述业务流程、信息以及与产品的内在联系。可采用适当的方式，如写成文本式需求清单或制作出模型，也可以同时采用&lt;br&gt;这两种方法；&lt;br&gt; 非功能性要求，如服务水平、绩效、安全、防护、合规性、保障能力、保留／清除等；&lt;br&gt; 质量要求；&lt;br&gt; 验收标准；&lt;br&gt; 体现组织指导原则的业务规则；&lt;br&gt; 对组织其他领域的影响，如呼叫中心、销售队伍、技术团队； &lt;p&gt;&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt; 对执行组织内部或外部团体的影响；&lt;br&gt; 对支持和培训的需求；&lt;br&gt; 与需求有关的假设条件和制约因素。 &lt;p&gt;2．需求管理计划&lt;/p&gt; &lt;p&gt;需求管理计划描述在整个项目生命周期内如何分析、记录和管理需求。生命周期各阶段间的关系（见2.1.3.2 节）对如何管理需求有很大影响。项目经理必须为项目选择最有效的阶段间关系，并记录在需求管理计划中。需求管理计划的许多内容都是基于该种关系的。&lt;br&gt;需求管理计划的内容包括（但不限于）：&lt;br&gt; 如何规划、跟踪和汇报各种需求活动；&lt;br&gt; 配置管理活动，例如，如何启动产品、服务或成果的变更，如何分析其影响，如何进行跟踪和汇报，以及谁有权批准变更；&lt;br&gt; 需求排序过程；&lt;br&gt; 产品测量指标及使用这些指标的理由；&lt;br&gt; 需求跟踪结构，即：哪些需求属性将列入跟踪矩阵，并可在其他哪些项目文件中追踪到这些需求。 &lt;p&gt;3．需求跟踪矩阵&lt;br&gt;需求跟踪矩阵是一张连接需求与需求源的表格，以便在整个项目生命周期中对需求进行跟踪。需求跟踪矩阵把每一个需求与业务目标或项目目标联系起来，有助于确保每一个需求都具有商业价值。它为人们在整个项&lt;br&gt;目生命周期中跟踪需求提供了一种方法，有助于确保需求文件所批准的每一项需求在项目结束时都得到实现。最后，需求跟踪矩阵为管理产品范围变更提供了框架。&lt;br&gt;跟踪需求的过程包括（但不限于）：&lt;br&gt; 从需求到业务需要、机会、目的和目标；&lt;br&gt; 从需求到项目目标；&lt;br&gt; 从需求到项目范围／WBS 中的可交付成果；&lt;br&gt; 从需求到产品设计；&lt;br&gt; 从需求到产品开发；&lt;br&gt; 从需求到测试策略和测试脚本；&lt;br&gt; 从宏观需求到详细需求。&lt;br&gt;应在需求跟踪矩阵中记录各项需求的相关属性。这些属性有助于明确各项需求的关键信息。需求跟踪矩阵中的典型属性包括：独特的识别标志、需求的文字描述、收录该需求的理由、所有者、来源、优先级别、版本、现状（如活跃中、已取消、已推迟、新增加、已批准）和实现日期。为确保干系人满意，可能需增加的补充属性包括：稳定性、复杂程度和验收标准。 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/a311300/201105/201105031357328036.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="T@]~E7L6G[N5)$61%IIQO(T" border="0" alt="T@]~E7L6G[N5)$61%IIQO(T" src="http://images.cnblogs.com/cnblogs_com/a311300/201105/201105031357581641.jpg" width="454" height="291"&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/a311300/aggbug/2035247.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/a311300/archive/2011/05/03/2035247.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/a311300/archive/2011/05/03/2035139.html</id><title type="text">采购管理计划</title><summary type="text">采购管理计划描述如何管理从编制采购文件直到合同收尾的各个采购过程。采购管理计划可包括如下内容： 拟采用的合同类型； 风险管理事项； 是否需要编制独立估算，以及是否应把独立估算作为评价标准； 如果执行组织设有采购、发包或采办部门，项目管理团队可独自采取的行动； 标准化的采购文件（如需要）； 如何管理多个供应商； 如何协调采购工作与项目的其他工作，如制定进度计划与报告项目绩效； 可能影响采购工作的制约...</summary><published>2011-05-03T04:33:00Z</published><updated>2011-05-03T04:33:00Z</updated><author><name>王景</name><uri>http://www.cnblogs.com/a311300/</uri></author><link rel="alternate" href="http://www.cnblogs.com/a311300/archive/2011/05/03/2035139.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/a311300/archive/2011/05/03/2035139.html"/><content type="html">&lt;p&gt;采购管理计划描述如何管理从编制采购文件直到合同收尾的各个采购过程。采购管理计划可包括如下内容： &lt;p&gt; 拟采用的合同类型；&lt;br&gt; 风险管理事项；&lt;br&gt; 是否需要编制独立估算，以及是否应把独立估算作为评价标准；&lt;br&gt; 如果执行组织设有采购、发包或采办部门，项目管理团队可独自采取的行动；&lt;br&gt; 标准化的采购文件（如需要）；&lt;br&gt; 如何管理多个供应商；&lt;br&gt; 如何协调采购工作与项目的其他工作，如制定进度计划与报告项目绩效；&lt;br&gt; 可能影响采购工作的制约因素和假设条件；&lt;br&gt; 如何确定采购工作所需的提前时间，以便与项目进度计划相协调；&lt;br&gt; 如何进行自制或外购决策，并把该决策与估算活动资源和制定进度计划等过程联系在一起；&lt;br&gt; 如何在每个合同中规定合同可交付成果的进度日期，以便与进度计划编制和进度控制过程相协调；&lt;br&gt; 如何识别对履约担保或保.&lt;/p&gt;&lt;img src="http://www.cnblogs.com/a311300/aggbug/2035139.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/a311300/archive/2011/05/03/2035139.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry></feed>
