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

<channel>
	<title>涂0实验室 &#187; 思考</title>
	<atom:link href="http://www.sulong.info/archives/tag/%e6%80%9d%e8%80%83/feed" rel="self" type="application/rss+xml" />
	<link>http://www.sulong.info</link>
	<description>一个程序员的成长之路</description>
	<lastBuildDate>Fri, 27 Aug 2010 01:54:11 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>漫谈PHP和Java</title>
		<link>http://www.sulong.info/archives/321</link>
		<comments>http://www.sulong.info/archives/321#comments</comments>
		<pubDate>Sat, 26 Sep 2009 16:31:51 +0000</pubDate>
		<dc:creator>sulong</dc:creator>
				<category><![CDATA[程序]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[思考]]></category>
		<category><![CDATA[经验]]></category>

		<guid isPermaLink="false">http://www.sulong.info/?p=321</guid>
		<description><![CDATA[我为公司内部交流而写的PPT，谈论PHP和JAVA相关的话题。在这里查看： 漫谈PHP和Java]]></description>
			<content:encoded><![CDATA[<p>我为公司内部交流而写的PPT，谈论PHP和JAVA相关的话题。在这里查看：</p>
<p><a href="http://docs.google.com/present/view?id=dc6zf3d4_83gf7b77c4">漫谈PHP和Java</a><br/></p>
<p><iframe src="http://docs.google.com/present/embed?id=dc6zf3d4_83gf7b77c4&#038;size=m" frameborder="0" width="555" height="451"></iframe></p>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save"><img src="http://www.sulong.info/wp-content/plugins/add-to-any/share_save_171_16.gif" width="171" height="16" alt="Share/Bookmark"/></a> </p>]]></content:encoded>
			<wfw:commentRss>http://www.sulong.info/archives/321/feed</wfw:commentRss>
		<slash:comments>22</slash:comments>
		</item>
		<item>
		<title>DRY, Don&#8217;t Repeat Yourself!</title>
		<link>http://www.sulong.info/archives/231</link>
		<comments>http://www.sulong.info/archives/231#comments</comments>
		<pubDate>Wed, 01 Jul 2009 08:59:34 +0000</pubDate>
		<dc:creator>sulong</dc:creator>
				<category><![CDATA[理论]]></category>
		<category><![CDATA[思考]]></category>
		<category><![CDATA[经验]]></category>

		<guid isPermaLink="false">http://www.sulong.info/?p=231</guid>
		<description><![CDATA[DRY，就是不要写重复的代码，这也是程序设计的一个黄金准则之一。 1 引申自关注点分离 其实这一条准则，也是从关注点分离引申而来的。如果完成相同或相似功能的代码片段，在一个程序的很多地方出现，那么无疑会使包含它的代码多了一个关注点。把相同或相似的代码抽象出来，放在一个地方，这样就可以使调用者减少一个关注点，同时将所有的对同类问题的关注合并到一个地方。比如说，判断一个用户是否登录，这一功能被很多地方使用，如果把这一功能包装成函数放到一个地方，需要使用的地方只要引用一下函数就可以了，这样引用者就不用关心如何判断一个用户是否登录了。 2 好处 2.1 提高效率 同样的功能，完成一次就可以了，如果每次要使用轮子的时候，都重复发明轮子，那是对人类智慧的浪费。如果发明一个万用轮子不容易，那么发明一个够用的可以反复使用的轮子就可以了。 2.2 更易读 如过你打开一个程序的源代码，发现有大量类似又稍有差别的代码，你还有多少心情读下去吗？要读下去的话，你就得像diff工具一样去比较类似代码间的细微差别，还要揣摩它的含义。这样的代码读起来太痛苦了。因此，如果没有重复的代码，就没有这份痛苦。 2.3 更易维护 如果你用类似的算法，重复写了很多的程序，结果却发现这个算法有个错误，那你不得不小心翼翼的找到所有的这样的程序，并一个一个又一个的修正。那是一个多么无聊的工作呀。如果漏掉了，或者将其中的某些一不小心修改错了，还得回头再重新修改，那台痛苦了！所以充斥着copy&#038;paste的代码，是维护者的噩梦。 3 怎么做 程序语言和编程方法的进步，也就是人们在实践DRY的过程。要做到DRY，就是要不断的通过抽象，把重复的功能抽象并包装起来。我们先是有了函数和子程序，后来有了类和方法，等等。我知道，为了DRY，还会有新的工具和方法论被发明。]]></description>
			<content:encoded><![CDATA[<p>DRY，就是不要写重复的代码，这也是程序设计的一个黄金准则之一。</p>
<h2>1 引申自关注点分离</h2>
<p>其实这一条准则，也是从<a href="http://www.sulong.info/archives/99">关注点分离</a>引申而来的。如果完成相同或相似功能的代码片段，在一个程序的很多地方出现，那么无疑会使包含它的代码多了一个关注点。把相同或相似的代码抽象出来，放在一个地方，这样就可以使调用者减少一个关注点，同时将所有的对同类问题的关注合并到一个地方。比如说，判断一个用户是否登录，这一功能被很多地方使用，如果把这一功能包装成函数放到一个地方，需要使用的地方只要引用一下函数就可以了，这样引用者就不用关心如何判断一个用户是否登录了。</p>
<h2>2 好处</h2>
<h3>2.1 提高效率</h3>
<p>同样的功能，完成一次就可以了，如果每次要使用轮子的时候，都重复发明轮子，那是对人类智慧的浪费。如果发明一个万用轮子不容易，那么发明一个够用的可以反复使用的轮子就可以了。</p>
<h3>2.2 更易读</h3>
<p>如过你打开一个程序的源代码，发现有大量类似又稍有差别的代码，你还有多少心情读下去吗？要读下去的话，你就得像diff工具一样去比较类似代码间的细微差别，还要揣摩它的含义。这样的代码读起来太痛苦了。因此，如果没有重复的代码，就没有这份痛苦。</p>
<h3>2.3 更易维护</h3>
<p>如果你用类似的算法，重复写了很多的程序，结果却发现这个算法有个错误，那你不得不小心翼翼的找到所有的这样的程序，并一个一个又一个的修正。那是一个多么无聊的工作呀。如果漏掉了，或者将其中的某些一不小心修改错了，还得回头再重新修改，那台痛苦了！所以充斥着copy&#038;paste的代码，是维护者的噩梦。</></p>
<h2>3 怎么做</h2>
<p>程序语言和编程方法的进步，也就是人们在实践DRY的过程。要做到DRY，就是要不断的通过抽象，把重复的功能抽象并包装起来。我们先是有了函数和子程序，后来有了类和方法，等等。我知道，为了DRY，还会有新的工具和方法论被发明。</p>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save"><img src="http://www.sulong.info/wp-content/plugins/add-to-any/share_save_171_16.gif" width="171" height="16" alt="Share/Bookmark"/></a> </p>]]></content:encoded>
			<wfw:commentRss>http://www.sulong.info/archives/231/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>企业应用与游戏开发的差别</title>
		<link>http://www.sulong.info/archives/234</link>
		<comments>http://www.sulong.info/archives/234#comments</comments>
		<pubDate>Wed, 01 Jul 2009 06:24:47 +0000</pubDate>
		<dc:creator>wuwei</dc:creator>
				<category><![CDATA[程序]]></category>
		<category><![CDATA[经验]]></category>
		<category><![CDATA[思考]]></category>

		<guid isPermaLink="false">http://www.sulong.info/?p=234</guid>
		<description><![CDATA[两个领域完全不一样,包括关注点,技术,运营等..我总结了一下: 1. 企业应用有很多功能属于增删改查的类型.有的是单表操作,有的是多表的JOIN,有的可能需要些逻辑判断,但大致的基本思路是这样,一个企业应用大约逃离不出这些结构.游戏不同.没有增删改查,没有任何的模式套路!做企业应用的思路和做游戏的思路完全不同.我们部门曾经单独为游戏的后台做了机器人脚本,能自动创建对游戏的表的管理功能,而游戏的后台管理功能大体与企业应用类似,这样想来可能企业应用还是有套路可循的. 2.二者的关注点不同.企业应用关注的是功能能否实现,模块,代码写的是否秀雅,当然游戏的开发也肯定关注这个,但游戏更要关注:性能,画面和可玩性&#8230;性能包括游戏的响应速度,能否支撑玩家的巨大的并发量 等.画面也非常重要,一个好的游戏能让人有赏心悦目的感觉.同样可玩性也要挖掘出来.要让玩家玩的爽,有能从中盈利,难度比较高呢&#8230; 3.代码编写的方式不同.企业应用的思路大多可以想到.比如页面列表显示,无法是取数据,然后转换成一个VIEW在页面上显示出来.而游戏呢,逻辑性之复杂令人瞠目.这里不多说了.可能一个简单的功能,需要上千行代码&#8230;还有一系列的算法等等,同时还要考虑到编写代码后游戏的运行速度和性能&#8230; 4.做企业应用很多人习惯用模型的方式设计数据库,比如一个表代码一个对象等.这样会产生可能一个查询有涉及到5张表之多.游戏呢?一个月就会有50万条记录,如何JOIN?JOIN一次要让你必须在1秒内响应,并且线上还有1000个玩家在玩,你能行吗?不行!尽量少JOIN表,这是提高数据库效率的一个非常好的方法. 5.多用缓存.不多说了,优势是:1减少访问数据库的时间和数据库的压力 2.提高请求响应速度.等等&#8230; 还有很多&#8230;呵呵]]></description>
			<content:encoded><![CDATA[<p>两个领域完全不一样,包括关注点,技术,运营等..我总结了一下:</p>
<p>1. 企业应用有很多功能属于增删改查的类型.有的是单表操作,有的是多表的JOIN,有的可能需要些逻辑判断,但大致的基本思路是这样,一个企业应用大约逃离不出这些结构.游戏不同.没有增删改查,没有任何的模式套路!做企业应用的思路和做游戏的思路完全不同.我们部门曾经单独为游戏的后台做了机器人脚本,能自动创建对游戏的表的管理功能,而游戏的后台管理功能大体与企业应用类似,这样想来可能企业应用还是有套路可循的.</p>
<p>2.二者的关注点不同.企业应用关注的是功能能否实现,模块,代码写的是否秀雅,当然游戏的开发也肯定关注这个,但游戏更要关注:性能,画面和可玩性&#8230;性能包括游戏的响应速度,能否支撑玩家的巨大的并发量 等.画面也非常重要,一个好的游戏能让人有赏心悦目的感觉.同样可玩性也要挖掘出来.要让玩家玩的爽,有能从中盈利,难度比较高呢&#8230;</p>
<p>3.代码编写的方式不同.企业应用的思路大多可以想到.比如页面列表显示,无法是取数据,然后转换成一个VIEW在页面上显示出来.而游戏呢,逻辑性之复杂令人瞠目.这里不多说了.可能一个简单的功能,需要上千行代码&#8230;还有一系列的算法等等,同时还要考虑到编写代码后游戏的运行速度和性能&#8230;</p>
<p>4.做企业应用很多人习惯用模型的方式设计数据库,比如一个表代码一个对象等.这样会产生可能一个查询有涉及到5张表之多.游戏呢?一个月就会有50万条记录,如何JOIN?JOIN一次要让你必须在1秒内响应,并且线上还有1000个玩家在玩,你能行吗?不行!尽量少JOIN表,这是提高数据库效率的一个非常好的方法.</p>
<p>5.多用缓存.不多说了,优势是:1减少访问数据库的时间和数据库的压力 2.提高请求响应速度.等等&#8230;</p>
<p>还有很多&#8230;呵呵</p>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save"><img src="http://www.sulong.info/wp-content/plugins/add-to-any/share_save_171_16.gif" width="171" height="16" alt="Share/Bookmark"/></a> </p>]]></content:encoded>
			<wfw:commentRss>http://www.sulong.info/archives/234/feed</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>浅谈TOMCAT集群</title>
		<link>http://www.sulong.info/archives/216</link>
		<comments>http://www.sulong.info/archives/216#comments</comments>
		<pubDate>Sat, 27 Jun 2009 05:26:57 +0000</pubDate>
		<dc:creator>wuwei</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[程序]]></category>
		<category><![CDATA[思考]]></category>

		<guid isPermaLink="false">http://www.sulong.info/?p=216</guid>
		<description><![CDATA[老实说，一开始我也认为没这个必要，因为加大JVM内存就就可以了嘛，干啥要集群很多TOMCAT呢？其实不是这样的。 首先TOMCAT集群需要APACHE和TOCMAT组合在一起。APACHE作为服务端的访问入口，自动地根据TOMCAT的并发数量分配到不同的TOMCAT里。二者缺一不可。并且配置是比较麻烦的。 很多人没用到集群是因为并发数还没达到一定的程度。一般企业应用最多也就50个并发，架一个TOCMAT，内存开大点就够了。但游戏就不一样了，动不动就几百甚至1000多的并发量，一个TOMCAT吃得消吗？吃不消！通过我们的实践证明，一个TOMCAT最多支撑起150个并发数，有次我们将其开发200个，结果到了170左右TOMCAT立马崩溃。所以后来为了支撑起1000都个并发量，我们架了9个TOMCAT集群。150*9=1350，基本能满足最大的用户访问量了。 有人说还不够，加大TOMCAT的内存嘛！这么并发量不就更大了？非也！我们通过实践证明，一个TOMCAT内存到了1G以上，就起不了多大的效果了，也就是说，1G内存的TOMCAT和2G内存的TOMCAT，基本性能是一样的！哈哈 还有一点，TOMCAT是免费的哦！不花钱还能架起这么大的一个应用，够省了吧？呵呵]]></description>
			<content:encoded><![CDATA[<p>老实说，一开始我也认为没这个必要，因为加大JVM内存就就可以了嘛，干啥要集群很多TOMCAT呢？其实不是这样的。</p>
<p>首先TOMCAT集群需要APACHE和TOCMAT组合在一起。APACHE作为服务端的访问入口，自动地根据TOMCAT的并发数量分配到不同的TOMCAT里。二者缺一不可。并且配置是比较麻烦的。</p>
<p>很多人没用到集群是因为并发数还没达到一定的程度。一般企业应用最多也就50个并发，架一个TOCMAT，内存开大点就够了。但游戏就不一样了，动不动就几百甚至1000多的并发量，一个TOMCAT吃得消吗？吃不消！通过我们的实践证明，一个TOMCAT最多支撑起150个并发数，有次我们将其开发200个，结果到了170左右TOMCAT立马崩溃。所以后来为了支撑起1000都个并发量，我们架了9个TOMCAT集群。150*9=1350，基本能满足最大的用户访问量了。</p>
<p>有人说还不够，加大TOMCAT的内存嘛！这么并发量不就更大了？非也！我们通过实践证明，一个TOMCAT内存到了1G以上，就起不了多大的效果了，也就是说，1G内存的TOMCAT和2G内存的TOMCAT，基本性能是一样的！哈哈</p>
<p>还有一点，TOMCAT是免费的哦！不花钱还能架起这么大的一个应用，够省了吧？呵呵</p>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save"><img src="http://www.sulong.info/wp-content/plugins/add-to-any/share_save_171_16.gif" width="171" height="16" alt="Share/Bookmark"/></a> </p>]]></content:encoded>
			<wfw:commentRss>http://www.sulong.info/archives/216/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>软件的质量属性</title>
		<link>http://www.sulong.info/archives/200</link>
		<comments>http://www.sulong.info/archives/200#comments</comments>
		<pubDate>Wed, 17 Jun 2009 02:15:47 +0000</pubDate>
		<dc:creator>sulong</dc:creator>
				<category><![CDATA[程序]]></category>
		<category><![CDATA[思考]]></category>
		<category><![CDATA[性能]]></category>

		<guid isPermaLink="false">http://www.sulong.info/?p=200</guid>
		<description><![CDATA[1 软件的质量属性 如果要我们描述一个人，我们会说，他的年龄多少，性别是什么，姓名是什么，等等。这些年龄，性别和姓名等，就是一个人的属性。类比的，软件也有属性，本文将讨论一下和软件质量相关的一些重要的属性。 2.1 正确性(Correctness) 正确性是软件最基本，最重要的属性。他代表了这个软件能够正确的执行计算并给出用户正确的结果。如果软件不能保证正确性，那么这个软件将没有价值可言。比如，一个总是计算错误的财务软件，显然是没有任何用处的。对小型的，功能单一的软件来说，正确性是显而易见的，要么正确，要么不正确。但是对于大型的复杂的软件来说，衡量正确性的标准都相当复杂或不确定，所以正确性本身也不是个简单的是和否的问题了。需求不等于正确性，需求不仅要求正确性，还会要求其他属性，如性能等，需求也不一定要求100%的正确性，只要计算结果对于最终用户来说是可用的就可以了。 2.2 有效性 有效性是指软件能在有效的时间内给出计算结果。一个无效的软件，即便其必然能得到正确的结果，也是无价值的。比如，穷举法总是正确的，但是在解决某些问题时，穷举法并不能在有效的时间内给出结果。如果一个用来预报明天天气的软件，却要在后天才能算出明天的天气情况，即使算正确了，也是没有意义的。 2.3 可用性(Availability) 可用性和有效性是对正确性和和有效性的一个综合，一个正确而有效的软件，才是可用的软件。如果在一段里，一个软件总能在有效的时间里给出正确的结果，那么这个软件在这段时间里就是可用的。而高可用，就是说一个软件可以在相当长的时间里保持可用性。 2.4 健壮性(Robustness) 在异常状况下，软件仍能够保持可用性，被称为健壮性。如果一个软件，由于输入数据不正确，或者运行时发生了些不正常状况等，就立刻崩溃，以致于不能再工作，显然是不健壮的。相反的，在这样恶劣的情况下，仍能够工作，则是健壮的。 2.5 可靠性(Reliability) 可靠性是指一个软件能在很长的时间内保持可用。一个健壮的软件，显然能提可靠性。对于某些持续提供服务的软件来说，高可用是很重要的。比如，网络服务器，我们往往需要它7&#215;24不停的可用。通过故障恢复等措施，可以提供软件的可靠性。 2.6 容错性 容错性是指软件能够自动的纠正错误的输入，得出正确的结果。比如大部分的浏览器，都能够解析不是很严格正确的html。容错性可以提高最终用户的用户体验。 2.7 性能 直观的说，性能就是软件快不快。但是仔细考虑的话，可以把性能分成很多更细的属性。 2.7.1 效率 在完成相同的计算任务时，软件占用越少的CPU时间越少的内存空间等计算资源，性能越高。换句话说，在相同的计算资源的条件下，完成的计算任务越多，效率越高。效率就是软件利用计算资源的能力。 2.7.2 响应时间 响应是软件对用户操作作出回应的速度。用户使用软件时，犹如和人交流，快速的响应，犹如和用户对答如流，会让用户更加的开心。比如，点击开始按钮后，出现一个显示计算进度的进度条，要比立刻全屏锁定，不让用户做任何操作要好多了即使后者可以更快的完成所有的任务。 2.7.3 吞吐量 单位时间内，软件能处理的数据量，或任务量。比如，一个网络服务器，单位时间内内够处理的http请求，和生成的html的数据量。吞吐量侧重于从输入输出上衡量软件的性能。 2.7.4 负载 负载是软件能承受的访问压力的能力。同样以网络服务器举例，能同时支持越多的用户访问，负载能力就越强。负载和吞吐量不完全相同。吞吐量很高，比一定能支持很多人访问；相应的，负载很好，单位时间内的输入输出可能并不高。 2.8 可伸缩性 在不修改，或者很少修改代码的情况下，通过添加硬件计算资源就可以提高软件整体性能的能力。对于大型的服务器软件，可伸缩性是很被重视的。理想情况下，系统的计算能力能随着硬件的添加而线性增长，很可惜，没有软件能达到这一程度。大部分软件在设计之初并没有考虑到可伸缩性，根本就不可伸缩，而另一些软件，增添硬件会使性能下降，或降低可靠性。 2.9 安全性 软件保护重要资源免受非法访问或恶意攻击的能力。安全性对于某些软件来说是非常重要的，对于另外一些软件来说则不那么重要。安全是一个复杂的工程，往往和整个软件运行环境相关。 2.10 适应性 软件不需要修改，就可以在别的环境下运行的能力。适应性高的程序，在设计之初就要考虑到软件可能运行的各种计算环境，并做好相对的准备。这样在程序生成后，不需要修改就可以在不同的环境下运行。 2.11 可移植性 将软件从一个环境下迁移到另一个环境下运行的能力。为了实现可移植，要抽象出软件所依赖的计算资源，在这一抽象层之上开发。移植时，只要修改抽象层在别的环境下的实现，而不必修改其上的部分。 2.12 一致性 软件的结构一致，是指软件用相同的方式处理相同的问题，用相同的符号表示相同的概念。一致性给程序带来美感，使程序更简单。一致性差的软件，就像被混淆器混淆过，最终只能使程序失去生命力。 2.13 可读性 软件代码可以被阅读和理解的能力。除了正确和有效，可读性可能就是我们最关心的属性。可读性好的代码，即便有缺陷，还有修正的机会，相反，犹如天书一般的代码，不能进化，没有前途。一致性可以提高可读性。 2.14 [...]]]></description>
			<content:encoded><![CDATA[<h2>1 软件的质量属性</h2>
<p>如果要我们描述一个人，我们会说，他的年龄多少，性别是什么，姓名是什么，等等。这些年龄，性别和姓名等，就是一个人的属性。类比的，软件也有属性，本文将讨论一下和软件质量相关的一些重要的属性。</p>
<h2>2.1 正确性(Correctness)</h2>
<p>正确性是软件最基本，最重要的属性。他代表了这个软件能够正确的执行计算并给出用户正确的结果。如果软件不能保证正确性，那么这个软件将没有价值可言。比如，一个总是计算错误的财务软件，显然是没有任何用处的。对小型的，功能单一的软件来说，正确性是显而易见的，要么正确，要么不正确。但是对于大型的复杂的软件来说，衡量正确性的标准都相当复杂或不确定，所以正确性本身也不是个简单的是和否的问题了。需求不等于正确性，需求不仅要求正确性，还会要求其他属性，如性能等，需求也不一定要求100%的正确性，只要计算结果对于最终用户来说是可用的就可以了。</p>
<h2>2.2 有效性</h2>
<p>有效性是指软件能在有效的时间内给出计算结果。一个无效的软件，即便其必然能得到正确的结果，也是无价值的。比如，穷举法总是正确的，但是在解决某些问题时，穷举法并不能在有效的时间内给出结果。如果一个用来预报明天天气的软件，却要在后天才能算出明天的天气情况，即使算正确了，也是没有意义的。</p>
<h2>2.3 可用性(Availability)</h2>
<p>可用性和有效性是对正确性和和有效性的一个综合，一个正确而有效的软件，才是可用的软件。如果在一段里，一个软件总能在有效的时间里给出正确的结果，那么这个软件在这段时间里就是可用的。而高可用，就是说一个软件可以在相当长的时间里保持可用性。</p>
<h2>2.4 健壮性(Robustness)</h2>
<p>在异常状况下，软件仍能够保持可用性，被称为健壮性。如果一个软件，由于输入数据不正确，或者运行时发生了些不正常状况等，就立刻崩溃，以致于不能再工作，显然是不健壮的。相反的，在这样恶劣的情况下，仍能够工作，则是健壮的。</p>
<h2>2.5 可靠性(Reliability)</h2>
<p>可靠性是指一个软件能在很长的时间内保持可用。一个健壮的软件，显然能提可靠性。对于某些持续提供服务的软件来说，高可用是很重要的。比如，网络服务器，我们往往需要它7&#215;24不停的可用。通过故障恢复等措施，可以提供软件的可靠性。</p>
<h2>2.6 容错性</h2>
<p>容错性是指软件能够自动的纠正错误的输入，得出正确的结果。比如大部分的浏览器，都能够解析不是很严格正确的html。容错性可以提高最终用户的用户体验。</p>
<h2>2.7 性能</h2>
<p>直观的说，性能就是软件快不快。但是仔细考虑的话，可以把性能分成很多更细的属性。</p>
<h3>2.7.1 效率</h3>
<p>在完成相同的计算任务时，软件占用越少的CPU时间越少的内存空间等计算资源，性能越高。换句话说，在相同的计算资源的条件下，完成的计算任务越多，效率越高。效率就是软件利用计算资源的能力。</p>
<h3>2.7.2 响应时间</h3>
<p>响应是软件对用户操作作出回应的速度。用户使用软件时，犹如和人交流，快速的响应，犹如和用户对答如流，会让用户更加的开心。比如，点击开始按钮后，出现一个显示计算进度的进度条，要比立刻全屏锁定，不让用户做任何操作要好多了即使后者可以更快的完成所有的任务。</p>
<h3>2.7.3 吞吐量</h3>
<p>单位时间内，软件能处理的数据量，或任务量。比如，一个网络服务器，单位时间内内够处理的http请求，和生成的html的数据量。吞吐量侧重于从输入输出上衡量软件的性能。</p>
<h3>2.7.4 负载</h3>
<p>负载是软件能承受的访问压力的能力。同样以网络服务器举例，能同时支持越多的用户访问，负载能力就越强。负载和吞吐量不完全相同。吞吐量很高，比一定能支持很多人访问；相应的，负载很好，单位时间内的输入输出可能并不高。</p>
<h2>2.8 可伸缩性</h2>
<p>在不修改，或者很少修改代码的情况下，通过添加硬件计算资源就可以提高软件整体性能的能力。对于大型的服务器软件，可伸缩性是很被重视的。理想情况下，系统的计算能力能随着硬件的添加而线性增长，很可惜，没有软件能达到这一程度。大部分软件在设计之初并没有考虑到可伸缩性，根本就不可伸缩，而另一些软件，增添硬件会使性能下降，或降低可靠性。</p>
<h2>2.9 安全性</h2>
<p>软件保护重要资源免受非法访问或恶意攻击的能力。安全性对于某些软件来说是非常重要的，对于另外一些软件来说则不那么重要。安全是一个复杂的工程，往往和整个软件运行环境相关。</p>
<h2>2.10 适应性</h2>
<p>软件不需要修改，就可以在别的环境下运行的能力。适应性高的程序，在设计之初就要考虑到软件可能运行的各种计算环境，并做好相对的准备。这样在程序生成后，不需要修改就可以在不同的环境下运行。</p>
<h2>2.11 可移植性</h2>
<p>将软件从一个环境下迁移到另一个环境下运行的能力。为了实现可移植，要抽象出软件所依赖的计算资源，在这一抽象层之上开发。移植时，只要修改抽象层在别的环境下的实现，而不必修改其上的部分。</p>
<h2>2.12 一致性</h2>
<p>软件的结构一致，是指软件用相同的方式处理相同的问题，用相同的符号表示相同的概念。一致性给程序带来美感，使程序更简单。一致性差的软件，就像被混淆器混淆过，最终只能使程序失去生命力。</p>
<h2>2.13 可读性</h2>
<p>软件代码可以被阅读和理解的能力。除了正确和有效，可读性可能就是我们最关心的属性。可读性好的代码，即便有缺陷，还有修正的机会，相反，犹如天书一般的代码，不能进化，没有前途。一致性可以提高可读性。</p>
<h2>2.14 可扩展性</h2>
<p>在尽量不修改原有代码的基础上通过添加新的代码而修正缺陷，实现新功能的能力。扩展性要求程序在设计之初就考虑到程序的哪些地方将来可能需要扩展，并留下余地。</p>
<h2>2.15 可测试性</h2>
<p>程序对测试方法和测试工具的友好性。容易测试的程序，在变动之后才容易验证其正确性。</p>
<h2>2.16 可维护性</h2>
<p>软件投入生产后被维护的难易程度。理想状态下，软件在投入生产后不需要停止服务，只要修改少部分代码，就可以实现新的功能需求或错误修正。一致性好，可读性好，可扩展性好，可测试性好的软件拥有更好的可维护性。一个上线后不久就没人看得懂源程序，修改一个小bug就要牵一发而动全身，修改后不知道其他功能能否正常运行的软件，是维护人员的噩梦。</p>
<h2>2.17 易用性</h2>
<p>指最终使用者学习和使用软件的难以程度。</p>
<h2>3 属性间的相互影响</h2>
<p>以上列出的各属性并非相互之间没有关系的，有些属性的提高利于其它属性的提高，而有些属性的提高则会降低其他属性。比如，程序中做了很多便于用户使用的计算工作，必然会降低程序的吞吐量；为了提高代码效率而使用各种小技巧导致代码难以阅读和理解；越容易阅读的代码，越容易扩展，越容易维护，等等。具体它们之间是怎样的关系要具体问题具体分析。</p>
<h2>4 小结</h2>
<p>软件的众多属性可以分成内在和外在两大类。内在属性是用户感觉不到的，而外在属性是用户感觉得到的属性。比如正确性和响应速度是用户感觉得到的，但是可扩展性和易读性用户就不知道了。我们应当在满足外在属性要求的同时提高内在属性，不能外表光鲜，内里脏乱。不同的软件，不同的场景，对不同的属性的要求是不同的，而且这些属性也有相互冲突的，因此我们不可能兼顾所有，只能抓住主要矛盾。一般情况下，正确性，有效性和易读性是最重要的。</p>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save"><img src="http://www.sulong.info/wp-content/plugins/add-to-any/share_save_171_16.gif" width="171" height="16" alt="Share/Bookmark"/></a> </p>]]></content:encoded>
			<wfw:commentRss>http://www.sulong.info/archives/200/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>如何保证jms消息的顺序性</title>
		<link>http://www.sulong.info/archives/183</link>
		<comments>http://www.sulong.info/archives/183#comments</comments>
		<pubDate>Wed, 03 Jun 2009 03:39:58 +0000</pubDate>
		<dc:creator>sulong</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[jms]]></category>
		<category><![CDATA[思考]]></category>

		<guid isPermaLink="false">http://www.sulong.info/?p=183</guid>
		<description><![CDATA[JMS提供的queue和topic两种工作方式，其中queue能保证消息在传输中的顺序性，这是队列先入先出(first in first out)的特性。JMS本身不能保证多个队列里的消息的顺序性，比如 先放入queue1的消息m1，并不一定总是比后放入queue2的消息m2，先到达同样的目的地。 并发地发送和接收消息不能保证消息按正确顺序进入队列和被消费。比如，有两个线程分别发送创建订单和支付订单消息，由于线程运行的不确定性，即使我们按顺序先开始发送创建订单的线程，后开始支付订单的线程，如果两个线程开始时间间隔不够长，还是有可能后开始的线程先发送掉消息。同样的情况发生在并发的接收处理消息时。 那么如何保证消息的顺序性呢？ 一种方案是，乱序接收，顺序处理。也就是说，消息在发送，传输和接收过程中可能是乱序的，但消费者在接收到消息之后，并不立即处理，而是先将消息排序，然后在处理。JMS消息头部的 JMSCorrelationID可以帮助我们完成这个工作。JMSCorrelationID存放了另一个消息的id。消息的发送者，如果要保证消息的顺序性，要将后发送的消息的JMSCorrelationID设置成前一个消息的id。消费者接收消息后，如果发现其头部有JMSCorrelationID，则查看该消息是否已被处理过，如果没有，则等待该消息，至到该消息被处理后，才处理这个消息。这一工作需要发送者和接收者都记住已经发送和接收过的消息，以便于给后来的消息参考。 另一种方案是，顺序发送，顺序传输，顺序接收，顺序处理。其中传输可以由queue来保证，但是发送接收和处理则需要应用程序来控制。简单的说，直到前一个消息发送成功，才能发送后一个消息，同样的，直到前一个消息被接受和处理结束，才能接收和处理后一个消息。这样的做法无疑会降低并发带来的好处。 以上所说的方案，是用来严格控制消息的顺序性的，然而，如果消息的发送的间隔时间足够长，不需要做过多控制，也可以控制消息的顺序性。假设，一个消息正常情况下，由发送，传输，接收到处理成功，最大时间耗费是2秒，那么只要我们保证消息发送的时间隔达不低于2秒，那么这两个消息就可以被正确的处理。这一条件咋听起来很苛刻，但事实上大部分的消息都满足了。比如，同一个订单的创建，和请求支付，最快也要数秒的时间，而退款的开始和结束，可能要数天。在典型的web应用中，操作人员不可能那么快的点击系统，而系统也不可能那么快的响应。进一步的，如果两个需要顺序处理的业务事件可能在极端的时间里连续发生，我们只要在程序上控制，人为将间隔拉开，就可以保证顺序性。 在系统的各各环节控制消息的顺序，代价高昂，而带来的好处却只是针对那极少数极端情况；通过业务或程序的方式，保证消息的有效时间间隔，代价较小，也能有效保证顺序。 如果系统中有很多的间隔极端，又需要保证顺序的消息，那你就要考虑是否将这两个消息合并成一个，或则不该采用jms了。]]></description>
			<content:encoded><![CDATA[<p>JMS提供的queue和topic两种工作方式，其中queue能保证消息在传输中的顺序性，这是队列先入先出(first in first out)的特性。JMS本身不能保证多个队列里的消息的顺序性，比如 先放入queue1的消息m1，并不一定总是比后放入queue2的消息m2，先到达同样的目的地。</p>
<p>并发地发送和接收消息不能保证消息按正确顺序进入队列和被消费。比如，有两个线程分别发送创建订单和支付订单消息，由于线程运行的不确定性，即使我们按顺序先开始发送创建订单的线程，后开始支付订单的线程，如果两个线程开始时间间隔不够长，还是有可能后开始的线程先发送掉消息。同样的情况发生在并发的接收处理消息时。</p>
<p>那么如何保证消息的顺序性呢？</p>
<p>一种方案是，乱序接收，顺序处理。也就是说，消息在发送，传输和接收过程中可能是乱序的，但消费者在接收到消息之后，并不立即处理，而是先将消息排序，然后在处理。JMS消息头部的 JMSCorrelationID可以帮助我们完成这个工作。JMSCorrelationID存放了另一个消息的id。消息的发送者，如果要保证消息的顺序性，要将后发送的消息的JMSCorrelationID设置成前一个消息的id。消费者接收消息后，如果发现其头部有JMSCorrelationID，则查看该消息是否已被处理过，如果没有，则等待该消息，至到该消息被处理后，才处理这个消息。这一工作需要发送者和接收者都记住已经发送和接收过的消息，以便于给后来的消息参考。</p>
<p>另一种方案是，顺序发送，顺序传输，顺序接收，顺序处理。其中传输可以由queue来保证，但是发送接收和处理则需要应用程序来控制。简单的说，直到前一个消息发送成功，才能发送后一个消息，同样的，直到前一个消息被接受和处理结束，才能接收和处理后一个消息。这样的做法无疑会降低并发带来的好处。</p>
<p>以上所说的方案，是用来严格控制消息的顺序性的，然而，如果消息的发送的间隔时间足够长，不需要做过多控制，也可以控制消息的顺序性。假设，一个消息正常情况下，由发送，传输，接收到处理成功，最大时间耗费是2秒，那么只要我们保证消息发送的时间隔达不低于2秒，那么这两个消息就可以被正确的处理。这一条件咋听起来很苛刻，但事实上大部分的消息都满足了。比如，同一个订单的创建，和请求支付，最快也要数秒的时间，而退款的开始和结束，可能要数天。在典型的web应用中，操作人员不可能那么快的点击系统，而系统也不可能那么快的响应。进一步的，如果两个需要顺序处理的业务事件可能在极端的时间里连续发生，我们只要在程序上控制，人为将间隔拉开，就可以保证顺序性。</p>
<p>在系统的各各环节控制消息的顺序，代价高昂，而带来的好处却只是针对那极少数极端情况；通过业务或程序的方式，保证消息的有效时间间隔，代价较小，也能有效保证顺序。</p>
<p>如果系统中有很多的间隔极端，又需要保证顺序的消息，那你就要考虑是否将这两个消息合并成一个，或则不该采用jms了。</p>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save"><img src="http://www.sulong.info/wp-content/plugins/add-to-any/share_save_171_16.gif" width="171" height="16" alt="Share/Bookmark"/></a> </p>]]></content:encoded>
			<wfw:commentRss>http://www.sulong.info/archives/183/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>企业应用集成&#8211;引入ESB</title>
		<link>http://www.sulong.info/archives/169</link>
		<comments>http://www.sulong.info/archives/169#comments</comments>
		<pubDate>Mon, 11 May 2009 06:44:15 +0000</pubDate>
		<dc:creator>sulong</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[程序]]></category>
		<category><![CDATA[esb]]></category>
		<category><![CDATA[思考]]></category>
		<category><![CDATA[经验]]></category>

		<guid isPermaLink="false">http://www.sulong.info/archives/169</guid>
		<description><![CDATA[随着时间的推移，一个企业的业务会越来越复杂，企业应用越来越多，应用间交互越来越复杂。新的应用的开发，耗在集成的上的时间和精力越来越多，而且集成也成了bug最容易发生的地方。如果不能很好的处理好集成问题，开发将很难再进行下去。 如果每个应用之间直接通过jms或http连接，应用数为N，那么最坏情况下，共有N(N-1)/2个连接，随着N的增长，应用间的连接越来越多，集成越来越累。如下图所示: 这个时候使用ESB，可以是系统从网状结构改成总线结构。如下图所示： 每个应用只要做好和ESB的连接，这将大大的降低系统结构的复杂度。ESB将负责路由应用间的消息。路由功能是ESB一个强项，不通过写代码，只要改改配置文件就可以实现简单的简单的路由规则。在网状结构中，每个应用负责决定消息是否发送到什么地方。比如，如果app1需要将消息发送到app2和app3，那么他要主动的和app2,app3连接，发送去消息。而在esb结构中，app1只需要把消息发送到esb上，由esb负责将这个消息路由到app2和app3。这样应用更关心和消息相关的创建和消费的业务功能，而不用关心消息的路由，而esb只关注消息的路由，却不用关注具体的业务逻辑。这样的关注点分离是很有益的。 另一方面，esb支持众多的协议，不仅支持jms, http，还支持比如corba, esb等协议，可以方便的和应用连接上。esb还内置的消息格式的转化内容的增强等功能。这样，app1, app2可以通过不同的协议连接到esb上，而且app1发送的可以是某种二进制报文，而app2接收的却是xml，不同协议的桥接，不同消息的格式和内容的差异，都可以在esb中弥补掉。这一能力对于集成遗留系统非常很有用。 可见esb让应用系统更关注于业务逻辑，而把路由，消息格式内容的转化和不同协议的支持等功能放到统一地方，几乎就是专门为应用集成而生的。]]></description>
			<content:encoded><![CDATA[<p>随着时间的推移，一个企业的业务会越来越复杂，企业应用越来越多，应用间交互越来越复杂。新的应用的开发，耗在集成的上的时间和精力越来越多，而且集成也成了bug最容易发生的地方。如果不能很好的处理好集成问题，开发将很难再进行下去。</p>
<p>如果每个应用之间直接通过jms或http连接，应用数为N，那么最坏情况下，共有N(N-1)/2个连接，随着N的增长，应用间的连接越来越多，集成越来越累。如下图所示:</p>
<p><img src="http://www.sulong.info/wp-content/uploads/2009/05/2009-05-11-1.jpg" alt="struct_without_esb" title="struct_without_esb" width="267" height="216" class="alignnone size-full wp-image-173" /></p>
<p>这个时候使用ESB，可以是系统从网状结构改成总线结构。如下图所示：</p>
<p><img src="http://www.sulong.info/wp-content/uploads/2009/05/20090511-2.jpg" alt="esb" title="esb" width="252" height="267" class="alignnone size-full wp-image-174" /></p>
<p>每个应用只要做好和ESB的连接，这将大大的降低系统结构的复杂度。ESB将负责路由应用间的消息。路由功能是ESB一个强项，不通过写代码，只要改改配置文件就可以实现简单的简单的路由规则。在网状结构中，每个应用负责决定消息是否发送到什么地方。比如，如果app1需要将消息发送到app2和app3，那么他要主动的和app2,app3连接，发送去消息。而在esb结构中，app1只需要把消息发送到esb上，由esb负责将这个消息路由到app2和app3。这样应用更关心和消息相关的创建和消费的业务功能，而不用关心消息的路由，而esb只关注消息的路由，却不用关注具体的业务逻辑。这样的关注点分离是很有益的。</p>
<p>另一方面，esb支持众多的协议，不仅支持jms, http，还支持比如corba, esb等协议，可以方便的和应用连接上。esb还内置的消息格式的转化内容的增强等功能。这样，app1, app2可以通过不同的协议连接到esb上，而且app1发送的可以是某种二进制报文，而app2接收的却是xml，不同协议的桥接，不同消息的格式和内容的差异，都可以在esb中弥补掉。这一能力对于集成遗留系统非常很有用。</p>
<p>可见esb让应用系统更关注于业务逻辑，而把路由，消息格式内容的转化和不同协议的支持等功能放到统一地方，几乎就是专门为应用集成而生的。</p>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save"><img src="http://www.sulong.info/wp-content/plugins/add-to-any/share_save_171_16.gif" width="171" height="16" alt="Share/Bookmark"/></a> </p>]]></content:encoded>
			<wfw:commentRss>http://www.sulong.info/archives/169/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>企业应用集成&#8211;java</title>
		<link>http://www.sulong.info/archives/166</link>
		<comments>http://www.sulong.info/archives/166#comments</comments>
		<pubDate>Tue, 28 Apr 2009 07:34:24 +0000</pubDate>
		<dc:creator>sulong</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[程序]]></category>
		<category><![CDATA[http]]></category>
		<category><![CDATA[jms]]></category>
		<category><![CDATA[思考]]></category>
		<category><![CDATA[经验]]></category>

		<guid isPermaLink="false">http://www.sulong.info/?p=166</guid>
		<description><![CDATA[java企业应用最终往往运行在某种应用服务器中，比如tomcat，jboss等。部署的单元是war, jar 或者 ear文件，开始的时候，我们可能会将多个应用放到一个单元里来开发管理和部署。随着应用的增多，为了能够让每个应用能够独立的运行不受干扰，也为了开发工作能很好的安排，往往会将各应用分开，于是会有多个war, jar,或ear文件。试想一下，假设你有订单系统，产品系统，客服系统，等，如果这些应用都被放在同一个部署单元里，当需要更新客服系统时，会短暂的导致订单系统不能正常工作，而这种情况往往是不能被接受的。另外，如果客服系统非常繁忙，由于部署在同一台物理服务器上，共享硬件资源，订单系统会受到干扰，而这也不是我们想要的。将单独的应用单独打包，单独部署成为必然。那么就面临着让这些应用通信，将它们集成的问题。 与java和php之间集成相比，java与java之间的集成，不仅可以使用共享数据库，soap，或基于http的简单的文档交换，还可以使用jms，rmi等多种方案。其中jms是j2ee众多的标准中最为成功的协议之一，很少有人针对它发表过不满意见。我们在工作中就采用了jms。和http相比，它有如下优势: 为java量身定做的 jms不仅可以传输普通的字符串，还可以直接传输java对象，并和java的其它服务结合起来，接口api也符合java的使用习惯。如果用http，我们还得要考虑如何把对象序列化等问题，比较麻烦。 使用长连接 http主要用在客户端和服务器交互上，为了能让服务器支持大量的客户端，http往往都以一种无状态和短连接的方式工作。而jms主要用在java应用之间的交互，不需要支持那么多的客户端，用长连接更加适合。典型的http服务器，可能同时要给数千数万人提供服务，如果服务器和每个客户端保持一个连接，那对服务器来说，显然是一个非常大的负担。所以，通常客户端和http的一次交互完成后，连接就断开，而下次访问时，还得要重新建立连接。jms服务器面对的客户端一般只有几个，至多几十个，和每个客户端保持连接的开销是可以接受的。典型的企业可能有如下系统：订单系统，产品系统，结算系统，等等，这些系统，每个都和集中的jms服务器保持一个连接，总连接数也是很少的，所以可以保持长连接。这客户端和jms服务器通信的时候，不必每次都建立连接，减少了网络操作，提升了性能。 异步 http操作的过程是同步的，如果要使用异步的方式工作，需要程序员再做些编码工作。而jms天生就以异步的方式来工作的，不必做过多的编码。消息的生产者一旦把消息发送出去，就可以立刻返回不必等待消息的消费结果，后续的消息消费可以自动的异步执行。将不必要立刻执行的动作异步执行，可以大大降低系统的响应时间。 可靠的消息传递 在使用http通信的过程中，如果发生了网络异常，是否要做重发，以及如何重发，会是一件很痛苦的事情。jms提供了persitent的传递模式，在这种模式时，客户端代理在发送消息之前，会先把消息持久，如果发生网络异常，客户端代理会自动处理重发，而不需要应用程序关心。jms消息的唯一编号，可以有效的阻止一个消息被重复处理的问题。 在java应用集成时，jms比http更适合。成熟的jms服务器软件很多，除了ibm的mq，jboss mq, apache activemq 都是很不错的选择。]]></description>
			<content:encoded><![CDATA[<p>java企业应用最终往往运行在某种应用服务器中，比如tomcat，jboss等。部署的单元是war, jar 或者 ear文件，开始的时候，我们可能会将多个应用放到一个单元里来开发管理和部署。随着应用的增多，为了能够让每个应用能够独立的运行不受干扰，也为了开发工作能很好的安排，往往会将各应用分开，于是会有多个war, jar,或ear文件。试想一下，假设你有订单系统，产品系统，客服系统，等，如果这些应用都被放在同一个部署单元里，当需要更新客服系统时，会短暂的导致订单系统不能正常工作，而这种情况往往是不能被接受的。另外，如果客服系统非常繁忙，由于部署在同一台物理服务器上，共享硬件资源，订单系统会受到干扰，而这也不是我们想要的。将单独的应用单独打包，单独部署成为必然。那么就面临着让这些应用通信，将它们集成的问题。<br />
<br/><br />
与java和php之间集成相比，java与java之间的集成，不仅可以使用共享数据库，soap，或基于http的简单的文档交换，还可以使用jms，rmi等多种方案。其中jms是j2ee众多的标准中最为成功的协议之一，很少有人针对它发表过不满意见。我们在工作中就采用了jms。和http相比，它有如下优势:</p>
<h3>为java量身定做的</h3>
<p>jms不仅可以传输普通的字符串，还可以直接传输java对象，并和java的其它服务结合起来，接口api也符合java的使用习惯。如果用http，我们还得要考虑如何把对象序列化等问题，比较麻烦。</p>
<h3>使用长连接</h3>
<p>http主要用在客户端和服务器交互上，为了能让服务器支持大量的客户端，http往往都以一种无状态和短连接的方式工作。而jms主要用在java应用之间的交互，不需要支持那么多的客户端，用长连接更加适合。典型的http服务器，可能同时要给数千数万人提供服务，如果服务器和每个客户端保持一个连接，那对服务器来说，显然是一个非常大的负担。所以，通常客户端和http的一次交互完成后，连接就断开，而下次访问时，还得要重新建立连接。jms服务器面对的客户端一般只有几个，至多几十个，和每个客户端保持连接的开销是可以接受的。典型的企业可能有如下系统：订单系统，产品系统，结算系统，等等，这些系统，每个都和集中的jms服务器保持一个连接，总连接数也是很少的，所以可以保持长连接。这客户端和jms服务器通信的时候，不必每次都建立连接，减少了网络操作，提升了性能。</p>
<h3>异步</h3>
<p>http操作的过程是同步的，如果要使用异步的方式工作，需要程序员再做些编码工作。而jms天生就以异步的方式来工作的，不必做过多的编码。消息的生产者一旦把消息发送出去，就可以立刻返回不必等待消息的消费结果，后续的消息消费可以自动的异步执行。将不必要立刻执行的动作异步执行，可以大大降低系统的响应时间。</p>
<h3>可靠的消息传递</h3>
<p>在使用http通信的过程中，如果发生了网络异常，是否要做重发，以及如何重发，会是一件很痛苦的事情。jms提供了persitent的传递模式，在这种模式时，客户端代理在发送消息之前，会先把消息持久，如果发生网络异常，客户端代理会自动处理重发，而不需要应用程序关心。jms消息的唯一编号，可以有效的阻止一个消息被重复处理的问题。<br />
<br/></p>
<p>在java应用集成时，jms比http更适合。成熟的jms服务器软件很多，除了ibm的mq，jboss mq, apache activemq 都是很不错的选择。</p>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save"><img src="http://www.sulong.info/wp-content/plugins/add-to-any/share_save_171_16.gif" width="171" height="16" alt="Share/Bookmark"/></a> </p>]]></content:encoded>
			<wfw:commentRss>http://www.sulong.info/archives/166/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>企业应用集成&#8211;java与php</title>
		<link>http://www.sulong.info/archives/162</link>
		<comments>http://www.sulong.info/archives/162#comments</comments>
		<pubDate>Thu, 23 Apr 2009 03:18:56 +0000</pubDate>
		<dc:creator>sulong</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[程序]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[思考]]></category>
		<category><![CDATA[经验]]></category>
		<category><![CDATA[集成]]></category>

		<guid isPermaLink="false">http://www.sulong.info/?p=162</guid>
		<description><![CDATA[随着企业的发展，企业的业务种类越来越多，业务量越来越大，越来越复杂，部署在单一的服务器上的单一的应用很难再满足业务系统在可靠性，性能，易于维护和扩展等很多方面的需求。进而把企业系统拆分成很多的独立应用，部署在多台服务器上，成为必须。拆分开的多个应用并不能独立的完成所有的业务，应用间必然需要集成。用什么样的方式把各应用集成，不仅能满足系统的功能需要，还能做到易于维护，易于扩展，高性能，高可靠，就成为了一个难题。 公司最开始用php做所有的内部(指面向公司内部职员)和外部的应用（外部指面向internet用户的），之后公司开始采用java来逐步代替php来开发内部应用。所以，我们java程序不但面临着如何集成java内部的各个应用的问题，还面临着如何和php集成的问题。我们使用用过以下方法和php集成： 数据库共享： java和php使用相同的数据库，为了减少混乱，同一张表，只能由java或php其中一方负责写。这种方法使用起来直观，易用，但还是有很多的问题。 首先，java和php对数据库的一些行为是不一致的。mysql数据库的datatime类型，再插入不正确的数据时，mysql会在里面插入&#8221;0000-00-00 00:00:00&#8243;, php在读取这样的日期时没有问题，反正，他是字符串。但是java这边却会出错，应为jdbc会默认的将它转化成java.sql.Date类型，而在转化的是时候会发生异常。更大的阻力来自于php和java两个团队在使用数据库习惯上的差异。 其次，数据库共享功能不够强。比如，php完成某个业务时，需要及时通知java，但是仅通过数据库共享不好做，除非java对数据库轮询，但这样做显然很难在及时性和性能两者之间找到平衡。 再次，可扩展性差，但需要做出变更时，变更数据库显然是一件更加痛苦的事。这不仅要处理遗留的数据，还要调节两边的数据库访问程序。 所以，正是后续的项目里就没有再使用过这一方案。 SOAP： 按理说soap这种语言中立又规范化的技术应该非常适合于这种场景，但是在使用过程中还是会出现很多的问题。 首先，php和java两边对soap的理解并不一样。Java生成的布尔值在soap的xml里并表示为true或则false，但是在php看来只要不是0，都是true，所以&#8221;false&#8221;也是true。也许是php那边所使用的soap支持程序有问题，但是这个问题确实给我们带来了很多麻烦。还有一个要命的问题，就是字符集的问题，php以前一直使用gb2312和gb18030，但是soap的xml并不支持gb18030里的某些奇特字符，一旦遇到这样的字符，xml解析就失败。后来，不得不把可能出现此类字符的内容用base64编码。顺便发一下牢骚，这些奇怪的字符网网都来自于那些爱使用脑残体火星文的新新人类，这些人简直就是弱智！ 基于http的简单文档交互: 这种方法很简单，就是通过http post个xml或其它文档来实现交互。这种方式就是原始的使用http的soap，只是soap后来加了一大堆的标准（ws-*），在这些标准对我们来说没有意义，而php和java两边对标准的支持不兼容的时候，soap就成了鸡肋。后来，我们就干脆抛弃了soap，而通过我们自己的程序来发送和接收我们自定义的没有歧义的xml。目前为止，这是两边都乐意使用且很少出问题的方式。这种方式需要两边很好的配合，需要规范化的文档，否则以后只会变得混乱。 我们也曾想过使用基于java的php实现，来达到让java和php在语言级别集成，这种方法对于php遗留系统来说风险太大，而且php程序员面并不乐意生活在java的虚拟机内。也许未来这能成为一个成熟的方案。 正因为使用不同技术的应用之间的集成存在很多的问题，在实际项目中应该尽量避免。]]></description>
			<content:encoded><![CDATA[<p>随着企业的发展，企业的业务种类越来越多，业务量越来越大，越来越复杂，部署在单一的服务器上的单一的应用很难再满足业务系统在可靠性，性能，易于维护和扩展等很多方面的需求。进而把企业系统拆分成很多的独立应用，部署在多台服务器上，成为必须。拆分开的多个应用并不能独立的完成所有的业务，应用间必然需要集成。用什么样的方式把各应用集成，不仅能满足系统的功能需要，还能做到易于维护，易于扩展，高性能，高可靠，就成为了一个难题。</p>
<p>公司最开始用php做所有的内部(指面向公司内部职员)和外部的应用（外部指面向internet用户的），之后公司开始采用java来逐步代替php来开发内部应用。所以，我们java程序不但面临着如何集成java内部的各个应用的问题，还面临着如何和php集成的问题。我们使用用过以下方法和php集成：</p>
<h3>数据库共享：</h3>
<p>java和php使用相同的数据库，为了减少混乱，同一张表，只能由java或php其中一方负责写。这种方法使用起来直观，易用，但还是有很多的问题。<br />
首先，java和php对数据库的一些行为是不一致的。mysql数据库的datatime类型，再插入不正确的数据时，mysql会在里面插入&#8221;0000-00-00 00:00:00&#8243;, php在读取这样的日期时没有问题，反正，他是字符串。但是java这边却会出错，应为jdbc会默认的将它转化成java.sql.Date类型，而在转化的是时候会发生异常。更大的阻力来自于php和java两个团队在使用数据库习惯上的差异。<br />
其次，数据库共享功能不够强。比如，php完成某个业务时，需要及时通知java，但是仅通过数据库共享不好做，除非java对数据库轮询，但这样做显然很难在及时性和性能两者之间找到平衡。<br />
再次，可扩展性差，但需要做出变更时，变更数据库显然是一件更加痛苦的事。这不仅要处理遗留的数据，还要调节两边的数据库访问程序。<br />
所以，正是后续的项目里就没有再使用过这一方案。</p>
<h3>SOAP：</h3>
<p>按理说soap这种语言中立又规范化的技术应该非常适合于这种场景，但是在使用过程中还是会出现很多的问题。<br />
首先，php和java两边对soap的理解并不一样。Java生成的布尔值在soap的xml里并表示为true或则false，但是在php看来只要不是0，都是true，所以&#8221;false&#8221;也是true。也许是php那边所使用的soap支持程序有问题，但是这个问题确实给我们带来了很多麻烦。还有一个要命的问题，就是字符集的问题，php以前一直使用gb2312和gb18030，但是soap的xml并不支持gb18030里的某些奇特字符，一旦遇到这样的字符，xml解析就失败。后来，不得不把可能出现此类字符的内容用base64编码。顺便发一下牢骚，这些奇怪的字符网网都来自于那些爱使用脑残体火星文的新新人类，这些人简直就是弱智！</p>
<h3>基于http的简单文档交互:</h3>
<p>这种方法很简单，就是通过http post个xml或其它文档来实现交互。这种方式就是原始的使用http的soap，只是soap后来加了一大堆的标准（ws-*），在这些标准对我们来说没有意义，而php和java两边对标准的支持不兼容的时候，soap就成了鸡肋。后来，我们就干脆抛弃了soap，而通过我们自己的程序来发送和接收我们自定义的没有歧义的xml。目前为止，这是两边都乐意使用且很少出问题的方式。这种方式需要两边很好的配合，需要规范化的文档，否则以后只会变得混乱。</p>
<p>我们也曾想过使用基于java的php实现，来达到让java和php在语言级别集成，这种方法对于php遗留系统来说风险太大，而且php程序员面并不乐意生活在java的虚拟机内。也许未来这能成为一个成熟的方案。</p>
<p>正因为使用不同技术的应用之间的集成存在很多的问题，在实际项目中应该尽量避免。</p>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save"><img src="http://www.sulong.info/wp-content/plugins/add-to-any/share_save_171_16.gif" width="171" height="16" alt="Share/Bookmark"/></a> </p>]]></content:encoded>
			<wfw:commentRss>http://www.sulong.info/archives/162/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Java EE的不足</title>
		<link>http://www.sulong.info/archives/123</link>
		<comments>http://www.sulong.info/archives/123#comments</comments>
		<pubDate>Sun, 07 Dec 2008 15:10:12 +0000</pubDate>
		<dc:creator>sulong</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[java EE]]></category>
		<category><![CDATA[思考]]></category>

		<guid isPermaLink="false">http://www.sulong.info/?p=123</guid>
		<description><![CDATA[Java EE的发布，尤其是ejb3，让我高兴了一把。改进是显而易见的，但是还不够，经过一年的多的使用，我今天忍不住要发发牢骚。 混乱的jndi 把对象绑定到树形结构的目录上，易于查找和使用，这本来是一个非常好的想法，但是偏偏被搞的非常复杂。在同一个服务器内，你能看到的jndi的形式可能有 /a/b, java:a/b,java:com/env/a/b, 甚至a/b。为什么JCP那帮人就不能把这个名称统一一下呢？部署在应用服务器上的组件，可以有一个jndi，但是Java EE偏偏没有定义将组件映射到一个什么样的jndi名字上，于是在glassfish下，默认的数据源的jndi名是java:/jdbc/db，在 jboss下则是java:/db，就算是ejb，在不同的应用服务器上被部署后都会被分配给不同的名字。@Resource可以把jndi资源注入到组件中，但是在引用组件时却可以通过两个名字，如：@Resource(name=&#8221;a/b&#8221;) @Resource(mappedName=&#8221;a/b&#8221;)，好讨厌！什么时候jndi能够被统一起来，java EE在易用性上一定会进一大步！ 半吊子的依赖注入 当我听到可以通过@Resource @EJB注入资源时，我非常高兴，那岂不是意味着Java 应用服务器，一下子就变成了个spring bean容器了？但是最终的结果很令人失望，因为你只能注入有jndi名字的东西，而且只能将它注入到指定的几种组件中，这样的限制一下子把好好的依赖注入给废了。通过jndi去找组件，比通过spring bean的名字找bean要难多了，而且我们确实需要将组件注入到某个普通的类里面。这样的限制最终导致了在实际项目中，很少会用到Java EE本身的依赖注入功能。 classloader的噩梦 相同的一个类，被不同的classloader载入，那么在jvm中这两个类就不是同一个类。classloader的这一机制有它的道理，比如提高安全性，但是会产生一些很奇怪的问题。假设有两个classloader, cl1和cl2，这两个classloader都载入了同一个class，比如 A.class，其中cl1的A.class实例化了一个对象a1, 那么，当你试图把a1 cast成 cl2的A.class的类型的时候，就会发生ClassCastException，尽管cl1的A.class和cl2的A.class是同一个 class。J2ee规定了每个ear内的library必须能被ear内的每个成员共享，容器生成的ejb的stub也必须能在ear内被共享。通常要实现这个功能，只要给这个ear分配一个classloader，并由这个classloader载入需要被整个ear内共享的class，而ear内的 war,和ejb-jar则由这个ear的classloader的子classloader载入。有了这一机制，在ear内部，ejb的local接口可以被正常的使用而不会出现问题。但是如果跨越ear调用ejb的local接口，就会出现诸如ClassloaderException的异常。跨越 ear使用jpa也会遇到类似的问题。Java EE没有给出统一的解决方案，不同的服务器给出了不同的方案，但还没有一个解决方案算是真正的优美。 MDB不能消费远程的消息 ejb2的时代，同样作为ejb，message driven bean 远不像会话bean和实体bean那样有那么多负面评论。MDB确实很好用，唯一的不足就是没有统一和简单的方法可以让mdb监听远程的jms消息。我对此感到非常纳闷，既然Java EE的标准已经统一了那么多，为何不多进一步，也统一一下如何让MDB访问远程JMS？ 或许Java EE标准的制定有太多的政治因素了，那些专家们总是再制造一些半成品。]]></description>
			<content:encoded><![CDATA[<p>Java EE的发布，尤其是ejb3，让我高兴了一把。改进是显而易见的，但是还不够，经过一年的多的使用，我今天忍不住要发发牢骚。</p>
<h2>混乱的jndi</h2>
<p>把对象绑定到树形结构的目录上，易于查找和使用，这本来是一个非常好的想法，但是偏偏被搞的非常复杂。在同一个服务器内，你能看到的jndi的形式可能有 /a/b, java:a/b,java:com/env/a/b, 甚至a/b。为什么JCP那帮人就不能把这个名称统一一下呢？部署在应用服务器上的组件，可以有一个jndi，但是Java EE偏偏没有定义将组件映射到一个什么样的jndi名字上，于是在glassfish下，默认的数据源的jndi名是java:/jdbc/db，在 jboss下则是java:/db，就算是ejb，在不同的应用服务器上被部署后都会被分配给不同的名字。@Resource可以把jndi资源注入到组件中，但是在引用组件时却可以通过两个名字，如：@Resource(name=&#8221;a/b&#8221;) @Resource(mappedName=&#8221;a/b&#8221;)，好讨厌！什么时候jndi能够被统一起来，java EE在易用性上一定会进一大步！</p>
<h2>半吊子的依赖注入</h2>
<p>当我听到可以通过@Resource @EJB注入资源时，我非常高兴，那岂不是意味着Java 应用服务器，一下子就变成了个spring bean容器了？但是最终的结果很令人失望，因为你只能注入有jndi名字的东西，而且只能将它注入到指定的几种组件中，这样的限制一下子把好好的依赖注入给废了。通过jndi去找组件，比通过spring bean的名字找bean要难多了，而且我们确实需要将组件注入到某个普通的类里面。这样的限制最终导致了在实际项目中，很少会用到Java EE本身的依赖注入功能。</p>
<h2>classloader的噩梦</h2>
<p>相同的一个类，被不同的classloader载入，那么在jvm中这两个类就不是同一个类。classloader的这一机制有它的道理，比如提高安全性，但是会产生一些很奇怪的问题。假设有两个classloader, cl1和cl2，这两个classloader都载入了同一个class，比如 A.class，其中cl1的A.class实例化了一个对象a1, 那么，当你试图把a1 cast成 cl2的A.class的类型的时候，就会发生ClassCastException，尽管cl1的A.class和cl2的A.class是同一个 class。J2ee规定了每个ear内的library必须能被ear内的每个成员共享，容器生成的ejb的stub也必须能在ear内被共享。通常要实现这个功能，只要给这个ear分配一个classloader，并由这个classloader载入需要被整个ear内共享的class，而ear内的 war,和ejb-jar则由这个ear的classloader的子classloader载入。有了这一机制，在ear内部，ejb的local接口可以被正常的使用而不会出现问题。但是如果跨越ear调用ejb的local接口，就会出现诸如ClassloaderException的异常。跨越 ear使用jpa也会遇到类似的问题。Java EE没有给出统一的解决方案，不同的服务器给出了不同的方案，但还没有一个解决方案算是真正的优美。</p>
<h2>MDB不能消费远程的消息</h2>
<p>ejb2的时代，同样作为ejb，message driven bean 远不像会话bean和实体bean那样有那么多负面评论。MDB确实很好用，唯一的不足就是没有统一和简单的方法可以让mdb监听远程的jms消息。我对此感到非常纳闷，既然Java EE的标准已经统一了那么多，为何不多进一步，也统一一下如何让MDB访问远程JMS？</p>
<p>或许Java EE标准的制定有太多的政治因素了，那些专家们总是再制造一些半成品。</p>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save"><img src="http://www.sulong.info/wp-content/plugins/add-to-any/share_save_171_16.gif" width="171" height="16" alt="Share/Bookmark"/></a> </p>]]></content:encoded>
			<wfw:commentRss>http://www.sulong.info/archives/123/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>数据迁移经验</title>
		<link>http://www.sulong.info/archives/116</link>
		<comments>http://www.sulong.info/archives/116#comments</comments>
		<pubDate>Thu, 25 Sep 2008 17:01:07 +0000</pubDate>
		<dc:creator>sulong</dc:creator>
				<category><![CDATA[程序]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[思考]]></category>
		<category><![CDATA[经验]]></category>

		<guid isPermaLink="false">http://www.sulong.info/?p=116</guid>
		<description><![CDATA[做关系型数据库数据迁移的时候，为了加快速度，要注意以下几点。 充分利用数据库的能力 关系型数据库被设计成善于做查找，比较，排序等操作。在大数据量的时候，重新写个程序去对数据做查找排序等，效率往往比不过数据库。所以在数据迁移的时 候，应该尽量将此类操作交给数据库来完成。另外数据库往往都有自己的一些工具，比如导入导出工具，如果你的迁移过程要做类似的工作，也应当交给数据库来完 成。假如你要取出数据库里的一些数据，将格式做些转换，再插入到另一个数据库。你可以写个程序读一条，转换一条，写一条，但是这样很慢，还不如把数据导出 成csv等文件，然后再对文本处理生成新的另一个数据库的导入文件，然后再用另一个数据库的导入工具导入。我曾经做过这样的工作，将数据从sql server 2000迁移到 mysql，要对数据做些简单的格式转换，前一种方案用时40分钟，而后一种只要一分钟。 减少IO操作 现代计算机的CPU，总线和内存的速度都远超过各种IO的速度，所以减少IO操作就可以大幅提升数据迁移时的速度。使用连接池重复使用连接，减少新建连接 的次数可以减少IO操作。使用缓存将可能会被多次查询的数据缓存起来，减少查询数据库次数，可以显著减少IO操作。将中间结果缓存到内存或临时表中，非常 有用。最近在工作中遇到的数据迁移，通过大量的应用内存缓存，成功的将数据迁移时间有原来的近一周缩短到一个小时。 注意索引 也许你在做数据迁移时的很多查询操作是平时用不到的，所以并没有适合于做迁移查询的索引，那么你一定要记得在迁移前加上它。同样，需要被插入数据的表的索引还是先删掉吧，迁移完后再加上。 经常维护数据 不完整的数据，在迁移过程中是最让人头痛的。平时经常清理数据中的垃圾，如果垃圾成山了，数据迁移将是恶梦。]]></description>
			<content:encoded><![CDATA[<p>做关系型数据库数据迁移的时候，为了加快速度，要注意以下几点。</p>
<h3>充分利用数据库的能力</h3>
<p>关系型数据库被设计成善于做查找，比较，排序等操作。在大数据量的时候，重新写个程序去对数据做查找排序等，效率往往比不过数据库。所以在数据迁移的时 候，应该尽量将此类操作交给数据库来完成。另外数据库往往都有自己的一些工具，比如导入导出工具，如果你的迁移过程要做类似的工作，也应当交给数据库来完 成。假如你要取出数据库里的一些数据，将格式做些转换，再插入到另一个数据库。你可以写个程序读一条，转换一条，写一条，但是这样很慢，还不如把数据导出 成csv等文件，然后再对文本处理生成新的另一个数据库的导入文件，然后再用另一个数据库的导入工具导入。我曾经做过这样的工作，将数据从sql server 2000迁移到 mysql，要对数据做些简单的格式转换，前一种方案用时40分钟，而后一种只要一分钟。</p>
<h3>减少IO操作</h3>
<p>现代计算机的CPU，总线和内存的速度都远超过各种IO的速度，所以减少IO操作就可以大幅提升数据迁移时的速度。使用连接池重复使用连接，减少新建连接 的次数可以减少IO操作。使用缓存将可能会被多次查询的数据缓存起来，减少查询数据库次数，可以显著减少IO操作。将中间结果缓存到内存或临时表中，非常 有用。最近在工作中遇到的数据迁移，通过大量的应用内存缓存，成功的将数据迁移时间有原来的近一周缩短到一个小时。</p>
<h3>注意索引</h3>
<p>也许你在做数据迁移时的很多查询操作是平时用不到的，所以并没有适合于做迁移查询的索引，那么你一定要记得在迁移前加上它。同样，需要被插入数据的表的索引还是先删掉吧，迁移完后再加上。</p>
<h3>经常维护数据</h3>
<p>不完整的数据，在迁移过程中是最让人头痛的。平时经常清理数据中的垃圾，如果垃圾成山了，数据迁移将是恶梦。</p>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save"><img src="http://www.sulong.info/wp-content/plugins/add-to-any/share_save_171_16.gif" width="171" height="16" alt="Share/Bookmark"/></a> </p>]]></content:encoded>
			<wfw:commentRss>http://www.sulong.info/archives/116/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>软件开发真理之关注点分离</title>
		<link>http://www.sulong.info/archives/99</link>
		<comments>http://www.sulong.info/archives/99#comments</comments>
		<pubDate>Fri, 25 Jul 2008 10:04:06 +0000</pubDate>
		<dc:creator>sulong</dc:creator>
				<category><![CDATA[程序]]></category>
		<category><![CDATA[思考]]></category>
		<category><![CDATA[经验]]></category>

		<guid isPermaLink="false">http://www.sulong.info/?p=99</guid>
		<description><![CDATA[如果说软件开发有什么真理的话，我想，那一定就是SOC（Separation of concerns，中文翻译叫关注点分离）。SOC原则，就是在软件开发中，通过各种手段，将问题的各个关注点分开。我已经记不得第一次在什么时候什么地方听说这一原则的，当时看一下就忘掉了。可是随着对软件开发的体会的加深，SOC这个概念不断的在我的脑海中浮现，以致于我把它当作软件开发的真理！ 问题太过于复杂，要解决问题需要关注的点太多，而程序员的能力是有限的，不能同时关注于问题的各个方面。正如程序员的记忆力相对于计算机知识来说那么有限一样，程序员解决问题的能力相对于要解决的问题的复杂性也是一样的非常有限。计算机知识太多而且不断进化，计算机程序也太复杂，而且还在不断的复杂化。记得有一本记算机图书中，用这样一个例子来对比程序和传统行业复杂性的差别有多大，说一架精密的波音客机，所有的部件加在一起，总共只有2万个，而GCC编译器，光全局变量就有40万之多，可见程序有多复杂。另一方面，人类的注意力所能同时关注的点又是相当的少的。举个简单的例子，一般人很难同时左右手分别划圆划方，就是因为我们的大脑很难同时关注于两只手，让两只手分别做自己的事。因此，做为普通人的程序员面对这种复杂性时，必须采用某些方法把问题分解成若干部分，这样程序员可以同一时刻只关注于问题的某些方面或部分，如果分解后的部分还是太复杂，那就再划分下去，直到使复杂问题变成一个个的简单问题。这就是关注点分离原则。这一准则，并不是计算机界的发明，只不过在计算机界显得更加的重要。 实现关注点分离的方法主要有两种，一种是标准化，另一种是抽象与包装。 标准化就是制定一套标准，让使用者都遵守它，将人们的行为统一起来，这样使用标准的人就不用担心别人会有很多种不同的实现，使自己的程序不能和别人的配合。Java EE就是一个标准的大集合。如果所有的应用服务器的开发者和应用的开发者都按照标准来做，那么应用开发者就不用关心不同的应用服务器有什么差别，服务器的开发者也不用担心应用开发者开发的应用有什么差别。每个开发都只需要关注于标准本身和他所在做的事情就行了。就像是开发镙丝钉的人只专注于开发镙丝钉就行了，而不用关注镙帽是怎么生产的，反正镙帽和镙丝钉按标来就一定能合得上。也就是因为标准具有这样的威力，所有计算机界有很多标准。 不断地把程序的某些部分抽像差包装起来，也是实现关注点分离的好方法。一旦一个函数被抽像出来并实现了，那么使用函数的人就不用关心这个函数是如何实现的，同样的，一旦一个类被抽像并实现了，类的使用者也不用再关注于这个类的内部是如何实现的。诸如组件，分层，面向服务，等等这些概念都是在不同的层次上做抽像和包装，以使得使用者不用关心它的内部实现细节。 每一个程序员都应当理解SOC，并在实践中遵循这一真理。当你在编程的过程中，一时搞不清程序的每一个细节，你可以只关注于主干，把程序的主干写出来，再逐一关注没个分支。这是一种自上而下的方法。如果主干也搞不清，那可以先关注于分支，写出分支，再不断地组合这些分支成为主干，这是一种自下而上的方法。时刻考虑着，是不是要把这一段程序抽像成一个方法，或者类，是不是那样会更好。如果不这样去想去做，要么面对问题无从下手，写不出什么来，要么只会写出面条似的拖沓冗长的代码。不会用SOC，摆在面前的永远是复杂得不能解决的问题。]]></description>
			<content:encoded><![CDATA[<p>如果说软件开发有什么真理的话，我想，那一定就是SOC（Separation of concerns，中文翻译叫关注点分离）。SOC原则，就是在软件开发中，通过各种手段，将问题的各个关注点分开。我已经记不得第一次在什么时候什么地方听说这一原则的，当时看一下就忘掉了。可是随着对软件开发的体会的加深，SOC这个概念不断的在我的脑海中浮现，以致于我把它当作软件开发的真理！</p>
<p>问题太过于复杂，要解决问题需要关注的点太多，而程序员的能力是有限的，不能同时关注于问题的各个方面。正如程序员的记忆力相对于计算机知识来说那么有限一样，程序员解决问题的能力相对于要解决的问题的复杂性也是一样的非常有限。计算机知识太多而且不断进化，计算机程序也太复杂，而且还在不断的复杂化。记得有一本记算机图书中，用这样一个例子来对比程序和传统行业复杂性的差别有多大，说一架精密的波音客机，所有的部件加在一起，总共只有2万个，而GCC编译器，光全局变量就有40万之多，可见程序有多复杂。另一方面，人类的注意力所能同时关注的点又是相当的少的。举个简单的例子，一般人很难同时左右手分别划圆划方，就是因为我们的大脑很难同时关注于两只手，让两只手分别做自己的事。因此，做为普通人的程序员面对这种复杂性时，必须采用某些方法把问题分解成若干部分，这样程序员可以同一时刻只关注于问题的某些方面或部分，如果分解后的部分还是太复杂，那就再划分下去，直到使复杂问题变成一个个的简单问题。这就是关注点分离原则。这一准则，并不是计算机界的发明，只不过在计算机界显得更加的重要。</p>
<p>实现关注点分离的方法主要有两种，一种是标准化，另一种是抽象与包装。</p>
<p>标准化就是制定一套标准，让使用者都遵守它，将人们的行为统一起来，这样使用标准的人就不用担心别人会有很多种不同的实现，使自己的程序不能和别人的配合。Java EE就是一个标准的大集合。如果所有的应用服务器的开发者和应用的开发者都按照标准来做，那么应用开发者就不用关心不同的应用服务器有什么差别，服务器的开发者也不用担心应用开发者开发的应用有什么差别。每个开发都只需要关注于标准本身和他所在做的事情就行了。就像是开发镙丝钉的人只专注于开发镙丝钉就行了，而不用关注镙帽是怎么生产的，反正镙帽和镙丝钉按标来就一定能合得上。也就是因为标准具有这样的威力，所有计算机界有很多标准。</p>
<p>不断地把程序的某些部分抽像差包装起来，也是实现关注点分离的好方法。一旦一个函数被抽像出来并实现了，那么使用函数的人就不用关心这个函数是如何实现的，同样的，一旦一个类被抽像并实现了，类的使用者也不用再关注于这个类的内部是如何实现的。诸如组件，分层，面向服务，等等这些概念都是在不同的层次上做抽像和包装，以使得使用者不用关心它的内部实现细节。</p>
<p>每一个程序员都应当理解SOC，并在实践中遵循这一真理。当你在编程的过程中，一时搞不清程序的每一个细节，你可以只关注于主干，把程序的主干写出来，再逐一关注没个分支。这是一种自上而下的方法。如果主干也搞不清，那可以先关注于分支，写出分支，再不断地组合这些分支成为主干，这是一种自下而上的方法。时刻考虑着，是不是要把这一段程序抽像成一个方法，或者类，是不是那样会更好。如果不这样去想去做，要么面对问题无从下手，写不出什么来，要么只会写出面条似的拖沓冗长的代码。不会用SOC，摆在面前的永远是复杂得不能解决的问题。</p>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save"><img src="http://www.sulong.info/wp-content/plugins/add-to-any/share_save_171_16.gif" width="171" height="16" alt="Share/Bookmark"/></a> </p>]]></content:encoded>
			<wfw:commentRss>http://www.sulong.info/archives/99/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>会struts+spring+hibernate就可以做java架构师了吗？</title>
		<link>http://www.sulong.info/archives/92</link>
		<comments>http://www.sulong.info/archives/92#comments</comments>
		<pubDate>Wed, 09 Jul 2008 09:42:28 +0000</pubDate>
		<dc:creator>sulong</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[思考]]></category>

		<guid isPermaLink="false">http://www.sulong.info/?p=92</guid>
		<description><![CDATA[最近公司又在招人，头安排我对一些应聘者做电话面试，让我遇到了不少华而不实的家伙。这些家伙的简历上密密麻麻会写了很多项目经验，都说自己做过需求做过架构，有项目管理经验。但是细细问下去，你会很失望，有些人会把hibernate 一级缓存和二级缓存搞混，有些人声称自己从来没有用过hibernate的二级缓存，有些人简历上写了一大堆模块，实际上只做了其中一两个，还有些人号称精通J2EE，却不知ejb3是何物！而这些人也只是用struts + spring + hibernate做过一些开发，而且并不能深入理解spring和hibernate的工作细节。 我不相信对基础工具不熟悉的人能做个架构师。我也不相信只会用struts+spring+hibernate的就可以做架构师。我更不相信架构师是高于程序员之上，只用画画图，写写文档，放放PPT，动动嘴皮子就可以做得了的。那些声称不想编码，只想做管理做架构的人，是不折不扣的妄想者。 做架构师的首要条件是基础扎实，连jdk里的api都不熟悉的家伙，是不可能做架构师的。要做架构师，还要能对新技术敏感，只围着自己的小圈子转，不看着未来世界的家伙，只能落后于这个领域，更别谈做架构。做架构师还得要大量编码，不写程序，还能算是程序员吗？不写程序，你做的架构会越来越没有根基。 用struts+spring+hibernate做过几个项目就可以做java架构师了吗？做梦吧！]]></description>
			<content:encoded><![CDATA[<p>最近公司又在招人，头安排我对一些应聘者做电话面试，让我遇到了不少华而不实的家伙。这些家伙的简历上密密麻麻会写了很多项目经验，都说自己做过需求做过架构，有项目管理经验。但是细细问下去，你会很失望，有些人会把hibernate 一级缓存和二级缓存搞混，有些人声称自己从来没有用过hibernate的二级缓存，有些人简历上写了一大堆模块，实际上只做了其中一两个，还有些人号称精通J2EE，却不知ejb3是何物！而这些人也只是用struts + spring + hibernate做过一些开发，而且并不能深入理解spring和hibernate的工作细节。</p>
<p>我不相信对基础工具不熟悉的人能做个架构师。我也不相信只会用struts+spring+hibernate的就可以做架构师。我更不相信架构师是高于程序员之上，只用画画图，写写文档，放放PPT，动动嘴皮子就可以做得了的。那些声称不想编码，只想做管理做架构的人，是不折不扣的妄想者。</p>
<p>做架构师的首要条件是基础扎实，连jdk里的api都不熟悉的家伙，是不可能做架构师的。要做架构师，还要能对新技术敏感，只围着自己的小圈子转，不看着未来世界的家伙，只能落后于这个领域，更别谈做架构。做架构师还得要大量编码，不写程序，还能算是程序员吗？不写程序，你做的架构会越来越没有根基。</p>
<p>用struts+spring+hibernate做过几个项目就可以做java架构师了吗？做梦吧！</p>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save"><img src="http://www.sulong.info/wp-content/plugins/add-to-any/share_save_171_16.gif" width="171" height="16" alt="Share/Bookmark"/></a> </p>]]></content:encoded>
			<wfw:commentRss>http://www.sulong.info/archives/92/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>AOP简介，理解AOP</title>
		<link>http://www.sulong.info/archives/70</link>
		<comments>http://www.sulong.info/archives/70#comments</comments>
		<pubDate>Thu, 21 Feb 2008 02:18:14 +0000</pubDate>
		<dc:creator>sulong</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[程序]]></category>
		<category><![CDATA[AOP]]></category>
		<category><![CDATA[思考]]></category>

		<guid isPermaLink="false">http://www.sulong.info/archives/70</guid>
		<description><![CDATA[AOP简介 一． AOP字面意思 AOP = Aspect Oriented Programming 中文意为： 面向切面编程 要掌握AOP就得从aspect，即切面，入手，理解什么是切面，为什么要切面，如何使用切面。 二． 没有AOP的日子 OOP = Object Oriented Programming 面向对象的编程。 兴起于上个世纪九十年代的面向对象编程理念，仍旧是现在编程思想的主流。面向对象的核心思想是抽像问题域的模型成对象，用程序去模拟对象以解决问题。但是在软件系统中还存在着一些问题，它们不易于，或者不适合于用面向对象地方式来解决，比如事务，安全，日志等。看下面： public class Tool1 &#123; &#160; &#160; public void doSomething&#40;&#41; &#123; &#160; &#160; &#160; &#160; System.out.println&#40;&#34;I am doing...&#34;&#41;; &#160; &#160; &#125; &#125; public class Tool2 &#123; &#160; &#160; public void doSomething &#40;&#41; &#123; &#160; &#160; &#160; [...]]]></description>
			<content:encoded><![CDATA[<p>AOP简介</p>
<h3>一． AOP字面意思</h3>
<p>AOP = Aspect Oriented Programming 中文意为： 面向切面编程</p>
<p>要掌握AOP就得从aspect，即切面，入手，理解什么是切面，为什么要切面，如何使用切面。</p>
<h3>二． 没有AOP的日子</h3>
<p>OOP = Object Oriented Programming 面向对象的编程。</p>
<p>兴起于上个世纪九十年代的面向对象编程理念，仍旧是现在编程思想的主流。面向对象的核心思想是抽像问题域的模型成对象，用程序去模拟对象以解决问题。但是在软件系统中还存在着一些问题，它们不易于，或者不适合于用面向对象地方式来解决，比如事务，安全，日志等。看下面：</p>
<div class="codecolorer-container java default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;"><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> Tool1 <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> doSomething<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Asystem+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">System</span></a>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;I am doing...&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> Tool2 <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> doSomething <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Asystem+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">System</span></a>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;I am do some other things...&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> Main<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">void</span> main<span style="color: #009900;">&#40;</span><a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Astring+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">String</span></a><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> args<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; Tool1 t1 <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Tool1<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; Tool2 t2 <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Tool2<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; t1.<span style="color: #006633;">doSomething</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; t2. <span style="color: #006633;">doSomething</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span></div></div>
<p><strong>例1</strong></p>
<p>这个程序很简单，容易看得懂。现在新的要求来了，要求在执行Tool1和Tool2的两个方法前后说一句话。如果用过程式的编程方法，我们只要改一下main方法，让它变成这样，看例2：</p>
<div class="codecolorer-container java default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;"><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> Main<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">void</span> main<span style="color: #009900;">&#40;</span><a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Astring+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">String</span></a><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> args<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; Tool1 t1 <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Tool1<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; Tool2 t2 <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Tool2<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Asystem+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">System</span></a>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Going to do something...&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; t1.<span style="color: #006633;">doSomething</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Asystem+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">System</span></a>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Did something...&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Asystem+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">System</span></a>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Going to do something...&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; t2. <span style="color: #006633;">doSomething</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Asystem+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">System</span></a>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Did something...&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span></div></div>
<p><strong>例2</strong></p>
<p>很好，实现目标了，但这存在以下问题：</p>
<ul>
<li> 如果还有其它不是main的调用者使用Tool1和Tool2，我们需要改动所有调用者代码</li>
<li> 完成同样的事情却将代码散落在多个地方，复制粘贴不是一个编程好习惯</li>
</ul>
<p>下面我们来解决这两个问题。为了解决第一个问题，我们可以把代码改动由调用者转移到被调用者里，如：</p>
<div class="codecolorer-container java default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;"><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> Tool1 <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> doSomething<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Asystem+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">System</span></a>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Going to do something...&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Asystem+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">System</span></a>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;I am doing...&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Asystem+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">System</span></a>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Did something...&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> Tool2 <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> doSomething <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Asystem+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">System</span></a>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Going to do something...&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Asystem+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">System</span></a>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;I am do some other things...&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Asystem+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">System</span></a>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Did something...&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> Main<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">void</span> main<span style="color: #009900;">&#40;</span><a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Astring+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">String</span></a><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> args<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; Tool1 t1 <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Tool1<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; Tool2 t2 <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Tool2<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; t1.<span style="color: #006633;">doSomething</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; t2. <span style="color: #006633;">doSomething</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span></div></div>
<p><strong>例3</strong></p>
<p>好，这样就不需要改变第个调用者的代码了。但是为了实现同样的功能，还是用了太多的代码，好，我们利用伟大的面向对向的能力吧！</p>
<div class="codecolorer-container java default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;"><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">abstract</span> <span style="color: #000000; font-weight: bold;">class</span> abstractTool <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> doSomething<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Asystem+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">System</span></a>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Going to do something...&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; doSomethingReally<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Asystem+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">System</span></a>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Did something...&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000000; font-weight: bold;">abstract</span> <span style="color: #000066; font-weight: bold;">void</span> doSomethingReally<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><br />
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> Tool1 <span style="color: #000000; font-weight: bold;">extends</span> abstractTool <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> doSomethingReally<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Asystem+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">System</span></a>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;I am doing...&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> Tool2 <span style="color: #000000; font-weight: bold;">extends</span> abstractTool <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> doSomethingReally<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Asystem+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">System</span></a>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;I am do some other things...&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> Main<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">void</span> main<span style="color: #009900;">&#40;</span><a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Astring+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">String</span></a><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> args<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; Tool1 t1 <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Tool1<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; Tool2 t2 <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Tool2<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; t1.<span style="color: #006633;">doSomething</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; t2.<span style="color: #006633;">doSomething</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span></div></div>
<p><strong>例4</strong></p>
<p>好了，这样实现新功能的代码被集在了一个抽象类的方法里了，没有在散落开来，易于维护了。这样的方案是不是就是完美的了呢？不，还不够，它存在着一个严重问题，</p>
<ul>
<li> 必须得修改被调用者的代码</li>
<li> 强迫被调用者继承于某个类，这样它将不能再继承其它类</li>
</ul>
<p>这样做显然很不灵活，假如还有Tool3 Tool4 Tooln…，它们有一些需要这样的功能，有一些不需要，甚至于有时有一些需要，有时有一些不需要，怎么办？我们只好每次变动时都做这样的修改，那太痛苦了。好吧，还有更好的方案吗？也许一开始设计得就有些问题吧？嗯，是的，我们采用工厂模式吧，面向接口编程吧！于是就有了下面的代码：</p>
<div class="codecolorer-container java default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;"><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">interface</span> Tool <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> doSomeThing<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> Tool1 <span style="color: #000000; font-weight: bold;">implements</span> Tool <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> doSomethingReally<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Asystem+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">System</span></a>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;I am doing...&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> Tool2 <span style="color: #000000; font-weight: bold;">implements</span> Tool <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> doSomethingReally<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Asystem+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">System</span></a>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;I am do some other things...&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> ToolProxy <span style="color: #000000; font-weight: bold;">implements</span> Tool<span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">private</span> Tool tool<span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> ToolProxy<span style="color: #009900;">&#40;</span>tool<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">tool</span> <span style="color: #339933;">=</span>tool<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> doSomething<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Asystem+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">System</span></a>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Going to do something...&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">tool</span>.<span style="color: #006633;">doSomething</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Asystem+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">System</span></a>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Did something...&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> ToolFactory <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> Tool getTool<span style="color: #009900;">&#40;</span><a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Astring+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">String</span></a> type<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Tool1&quot;</span>.<span style="color: #006633;">equals</span><span style="color: #009900;">&#40;</span>type<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">new</span> ToolProxy<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> Tool1<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #000000; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Tool2&quot;</span>.<span style="color: #006633;">equals</span><span style="color: #009900;">&#40;</span>type<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">new</span> ToolProxy<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> Tool2<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> Main<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">void</span> main<span style="color: #009900;">&#40;</span><a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Astring+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">String</span></a><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> args<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; Tool t1 <span style="color: #339933;">=</span> ToolFactory.<span style="color: #006633;">getTool</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Tool1&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; Tool t2 <span style="color: #339933;">=</span> ToolFactory.<span style="color: #006633;">getTool</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Tool2&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; t1.<span style="color: #006633;">doSomething</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; t2.<span style="color: #006633;">doSomething</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span></div></div>
<p><strong>例5</strong></p>
<p>接口使被调用者不再需要继承于某个类，也使得调用者和被调用者之间解耦。工厂负责组装类，我们可以在工厂里实现通过xml来配置等功能。ToolProxy代理类把新功能性代码集中在一起，便于管理。可惜这个方案还是有些问题的，假如我们不能改动被调用代码，不能强制人家实现某个接口呢？好吧，我们再使用一点花招吧，看下面代码：</p>
<div class="codecolorer-container java default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;"><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">interface</span> Tool <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> doSomeThing<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><br />
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> Tool1Wrapper <span style="color: #000000; font-weight: bold;">implements</span> Tool <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> Tool1 tool1<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> Tool1Wrapper<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; tool1 <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Tool1<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> doSomething<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; tool1.<span style="color: #006633;">doSomething</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> Tool2Wrapper <span style="color: #000000; font-weight: bold;">implements</span> Tool <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> Tool2 tool2<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> Tool2Wrapper<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; tool2 <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Tool2<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> doSomething<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; tool2.<span style="color: #006633;">doSomething</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> Tool1<span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> doSomething<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Asystem+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">System</span></a>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;I am doing...&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> Tool2<span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> doSomething<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Asystem+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">System</span></a>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;I am do some other things...&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> ToolProxy <span style="color: #000000; font-weight: bold;">implements</span> Tool<span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">private</span> Tool tool<span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> ToolProxy<span style="color: #009900;">&#40;</span>tool<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">tool</span> <span style="color: #339933;">=</span>tool<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> doSomething<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Asystem+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">System</span></a>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Going to do something...&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">tool</span>.<span style="color: #006633;">doSomething</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Asystem+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">System</span></a>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Did something...&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> ToolFactory <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> Tool getTool<span style="color: #009900;">&#40;</span><a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Astring+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">String</span></a> type<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Tool1&quot;</span>.<span style="color: #006633;">equals</span><span style="color: #009900;">&#40;</span>type<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">new</span> ToolProxy<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> Tool1Wrapper<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #000000; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Tool2&quot;</span>.<span style="color: #006633;">equals</span><span style="color: #009900;">&#40;</span>type<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">new</span> ToolProxy<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> Tool2Wrapper<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> Main<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">void</span> main<span style="color: #009900;">&#40;</span><a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Astring+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">String</span></a><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> args<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; Tool t1 <span style="color: #339933;">=</span> ToolFactory.<span style="color: #006633;">getTool</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Tool1&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; Tool t2 <span style="color: #339933;">=</span> ToolFactory.<span style="color: #006633;">getTool</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Tool2&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; t1.<span style="color: #006633;">doSomething</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; t2.<span style="color: #006633;">doSomething</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span></div></div>
<p><strong>例6</strong></p>
<p>当你看完这段代码后，如果你想要抓狂，那就抓吧，我能够理解。为了实现这点新功能，我们做了如此大的努力！是不是这样就结束了呢？这就是最终的完美方案了吗？显然还不够：</p>
<ul>
<li> 代码太长</li>
<li> 如果有多个类，就需要写多个Wrapper类</li>
<li> 如果有多个接口，就需要写多个Proxy类</li>
</ul>
<p>如果这样的代码就能够让你满意，看来你不是足够懒惰的程序员，你很勤快，愿意为实现这样的功能敲打出一堆代码。但是伟大的懒惰程序员们并不没有停下来。</p>
<h3>三． AOP是对OOP的补充</h3>
<p>当写完上面的代码后，我们该静下来想一想，我们到底想要对程序做什么，为什么会这样麻烦呢？</p>
<p>我们想要什么？我们想要就是能在程序的调用者和被调用者之间切开一个面，加入新的功能！上面的例子，我们就是想在调用Tool1和Tool2的doSomething()方法时，将调用过程切开一个面，分别在进入和出来时放入两句代码而已。而现在的程序语言恰恰缺少这样把调用过程切开的能力，所以我们需要新的语言，新的能力！这个编程的思想就是AOP，这种能力就是AOP的能力，能够这样做的语言就是AOP的语言。</p>
<p>AOP是对OOP的一个补充，正是OOP缺少了这样的能力，而人们又有这样的需要，所以才会有AOP。AOP并不能代替OOP，正如OOP不能代替过程式编程一样。</p>
<h3>四． 理解AOP的语义</h3>
<p>AOP中最关键的就是aspect，即切面。切面是以前的语言没有定义的新的概念。要理解切面，就要理解切面几个要素：</p>
<p>1. 切谁 即，对谁的调用会被切开，我们想要加入的新的功能正是针对于这个被切的对象的。</p>
<p>2. 切什么地方 被调用者会可能有多个被外部访问的出入口，为了实现我们的功能，需要被切的那个出入口。</p>
<p>3. 添加什么样的功能 将程序切开，目的是在被切开的地方加入新的功能。</p>
<p>理想状况下，所有的对象都能被切，不管这个对象是什么类型的，是不是final的，是不是nested的等；对象的所有地方都能切，不管是在构建时，调用方法时，调用属性时，调用前，调用后等；任意功能都能添加，切开之后，做什么都可以。</p>
<p>AOP有各种不同的实现，不同实现的能力之间的区别就可以通过上面的三条来衡量。功能最强的AspectJ，可以对任意对象的创建，方法调用，属性调用时做切面，加入任意功能。但是一般情况下我们不需要那么强的能力，能够实现对象的方法调用的切入，就已经够用了，spring里大量使用了这样的能力。</p>
<p>为了使用的方便，一般对方法的切入，分为以下几种：</p>
<p>1. Before 在方法调用前执行，不能控制返回值</p>
<p>2. After 在方法调用后执行，可以控制返回值</p>
<p>3. Throw 在方法异常退出时执行</p>
<p>4. Around 兼有以上三种的能力</p>
<h3>五． AOP 实现原理举例</h3>
<p>实现AOP有很多种不同方法，大体上可以分为三类：</p>
<h4>1. 修改由源程序生的class文件，加入新功能</h4>
<p>这一类的代表是AspectJ项目。它在java语言的基础上添加的新的语言和语法。AspectJ有自己的编译器，它会在调用java的编译器生成class文件后，修改class文件。这种方法实现的AOP是最高效的，因为功能的添加是在编译器就加入了，也是功能最强的，所有的地方都可以切入，缺点是需要学习新的语法和需要额外的编译步骤。</p>
<h4>2. 动态生成类的子类，通过方法覆盖来添加新的功能</h4>
<p>Spring使用cglib在运行时生成类的子类来实现一部分AOP。比如对于上面例子中的Tool1类，spring可以在运行时动态生成一个新的类，类似于:</p>
<div class="codecolorer-container java default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;"><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> Tool1$<span style="color: #cc66cc;">4535354</span> <span style="color: #000000; font-weight: bold;">extends</span> Tool1<span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> doSomething <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Asystem+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">System</span></a>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Going to do something...&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">super</span>.<span style="color: #006633;">doSomething</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Asystem+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">System</span></a>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Did something...&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span></div></div>
<p><strong>例7</strong></p>
<p>这种方法需要被调用对象的类是可以被继承的，方法是可以被覆盖的，还好这一条基本上都能满足，因为大部情况下我们面对的都是普通的java bean。</p>
<h4>3. 借助于接口和动态代理类，添加新功能。</h4>
<pre>Spring在处理带有接口的类的时候采用这种方式。JDK里有一个类java.lang.reflect.Proxy 可以动态地生</pre>
<pre>成一个实现了某个接口的代理类。例如，spring实现了一个类似于下面的类：</pre>
<div class="codecolorer-container java default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;"><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> ProxyFactory <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Aobject+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">Object</span></a> getProxy<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">Class</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> interfaces,<br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Aobject+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">Object</span></a> target<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Aobject+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">Object</span></a> proxy <span style="color: #339933;">=</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Aproxy+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">Proxy</span></a>.<span style="color: #006633;">newProxyInstance</span><span style="color: #009900;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; target.<span style="color: #006633;">getClass</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getClassLoader</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; interfaces,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">new</span> MyInvocationHandler<span style="color: #009900;">&#40;</span>target<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">return</span> proxy<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000000; font-weight: bold;">class</span> MyInvocationHandler <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">private</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Aobject+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">Object</span></a> target<span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> MyInvocationHandler<span style="color: #009900;">&#40;</span><a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Aobject+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">Object</span></a> target<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">target</span> <span style="color: #339933;">=</span> target<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Aobject+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">Object</span></a> invoke<span style="color: #009900;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Aobject+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">Object</span></a> proxy, <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Amethod+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">Method</span></a> method, <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Aobject+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">Object</span></a><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> args<span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">throws</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Athrowable+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">Throwable</span></a> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Asystem+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">System</span></a>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Going to do something...&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Aobject+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">Object</span></a> o <span style="color: #339933;">=</span> method.<span style="color: #006633;">invoke</span><span style="color: #009900;">&#40;</span>target, args<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Asystem+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">System</span></a>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Did something...&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">return</span> o<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span></div></div>
<pre></pre>
<pre>进一步的，我们还可以修改MyInvocationHanlder使其动态化，在invoke方法里执行抽像化的before after</pre>
<pre>around throw 等建议，这里就写了。有了这个动态代理类，我们就可以不用实现很多的Proxy类了。</pre>
<h3>六． AOP的标准</h3>
<p>为了能够统一对AOP使用的术语和API，国际上出现了AOP相关的组织，比如项目<strong>aopalliance</strong>等。Spring在使用的aop时就采用这个项目制定的api。关于标准的内容，可以自行去查看相关资料。</p>
<h3>七． 在spring中使用AOP</h3>
<p>Spring里大量使用AOP，为了能更简单地表达AOP，可以通过xml或annotation对AOP进行描述。详细请看spring的手册。</p>
<div class="codecolorer-container xml default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;"><div class="xml codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;tx:advice</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;daoTxAdvice&quot;</span> <span style="color: #000066;">transaction-manager</span>=<span style="color: #ff0000;">&quot;transactionManager&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;tx:attributes<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;tx:method</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;find*&quot;</span> <span style="color: #000066;">read-only</span>=<span style="color: #ff0000;">&quot;true&quot;</span> <span style="color: #000066;">propagation</span>=<span style="color: #ff0000;">&quot;REQUIRED&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;tx:method</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;check*&quot;</span> <span style="color: #000066;">read-only</span>=<span style="color: #ff0000;">&quot;true&quot;</span> <span style="color: #000066;">propagation</span>=<span style="color: #ff0000;">&quot;REQUIRED&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;tx:method</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;*&quot;</span> <span style="color: #000066;">propagation</span>=<span style="color: #ff0000;">&quot;REQUIRED&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/tx:method<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/tx:method<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
<br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;aop:config<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;aop:pointcut</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;daoOperation&quot;</span> <span style="color: #000066;">expression</span>=<span style="color: #ff0000;">&quot;execution(public * com.**.dao.*Dao.*(..))&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;/aop:pointcut<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;aop:advisor</span> <span style="color: #000066;">advice-ref</span>=<span style="color: #ff0000;">&quot;daoTxAdvice&quot;</span> <span style="color: #000066;">pointcut-ref</span>=<span style="color: #ff0000;">&quot;daoOperation&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;/aop:advisor<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
<br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;aop:aspect</span> <span style="color: #000066;">ref</span>=<span style="color: #ff0000;">&quot;permissionCheckBean&quot;</span> <span style="color: #000066;">order</span>=<span style="color: #ff0000;">&quot;0&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;aop:pointcut</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;permissionCheckPointCut&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/aop:pointcut<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>expression=&quot;execution(public String com.**.action.*Action.execute*()) &quot; /<span style="color: #ddbb00;">&amp;gt;</span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;aop:around</span> <span style="color: #000066;">method</span>=<span style="color: #ff0000;">&quot;checkPermission&quot;</span> <span style="color: #000066;">arg-names</span>=<span style="color: #ff0000;">&quot;pjp &quot;</span> <span style="color: #000066;">pointcut-ref</span>=<span style="color: #ff0000;">&quot;permissionCheckPointCut&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;/aop:around<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/aop:aspect<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/aop:config<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/tx:method<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;/tx:attributes<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;/tx:advice<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></div></div>
<p><strong>例9</strong></p>
<p>上面的配置中&lt;aop:pointcut&gt;标签定义了一个bean,它能够说明切什么对象的什么地方。比如，expression=&#8221;execution(public String com.**.action.*Action.execute*()) and @annotation(requirePermission) 说明在对方公开的反回值为String的，包名符使表达式com.liba.**.action的，类名符合*Action的，方法名以execute开头的，无参数的，这样的方法进行切入。然后&lt;aop:around&gt;标签则表达了，对于上面那样的方法以around方式切入，切入后，在切开的地方执行permissionCheckBean的 checkPermission方法。</p>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save"><img src="http://www.sulong.info/wp-content/plugins/add-to-any/share_save_171_16.gif" width="171" height="16" alt="Share/Bookmark"/></a> </p>]]></content:encoded>
			<wfw:commentRss>http://www.sulong.info/archives/70/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>新项目时间表突然提前了三个月</title>
		<link>http://www.sulong.info/archives/20</link>
		<comments>http://www.sulong.info/archives/20#comments</comments>
		<pubDate>Mon, 22 Oct 2007 12:43:27 +0000</pubDate>
		<dc:creator>sulong</dc:creator>
				<category><![CDATA[生活]]></category>
		<category><![CDATA[程序]]></category>
		<category><![CDATA[思考]]></category>

		<guid isPermaLink="false">http://sulong.info/archives/20</guid>
		<description><![CDATA[上周我们IT部门的头突然找我到会议室说上面要我们明年三月就把一个频道的项目做完，这样整个时间表一下子向前提前了三个月。本来这三个月是我悠闲地学习新知识研究架构设计等的时候，现在一下子没了，要硬着头皮上了。而这个时候，公司IT部做新项目的开发人员其实就我一个人（还有一个是从PHP转过来的，做实验的……）。唉，做软件，尤其是在公司里为别人做软件，从来都是老板说了算。我的头是公司的CTO，但是仍旧不能劝服老板，因为他不能理解从一堆没有注释设计糟糕的php代码里提取逻辑，从200多张堆砌出来的已经错误的数据库表中提取数据，是一件多么困难的事呀！]]></description>
			<content:encoded><![CDATA[<p>上周我们IT部门的头突然找我到会议室说上面要我们明年三月就把一个频道的项目做完，这样整个时间表一下子向前提前了三个月。本来这三个月是我悠闲地学习新知识研究架构设计等的时候，现在一下子没了，要硬着头皮上了。而这个时候，公司IT部做新项目的开发人员其实就我一个人（还有一个是从PHP转过来的，做实验的……）。唉，做软件，尤其是在公司里为别人做软件，从来都是老板说了算。我的头是公司的CTO，但是仍旧不能劝服老板，因为他不能理解从一堆没有注释设计糟糕的php代码里提取逻辑，从200多张堆砌出来的已经错误的数据库表中提取数据，是一件多么困难的事呀！</p>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save"><img src="http://www.sulong.info/wp-content/plugins/add-to-any/share_save_171_16.gif" width="171" height="16" alt="Share/Bookmark"/></a> </p>]]></content:encoded>
			<wfw:commentRss>http://www.sulong.info/archives/20/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
