<?xml version="1.0" encoding="utf-8" ?><rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://purl.org/rss/1.0/" 
			xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" 
			xmlns:cc="http://web.resource.org/cc/" xml:lang="ja">
<channel rdf:about="http://yuanyp.blog67.fc2.com/?xml">
<title>テック日記</title>
<link>http://yuanyp.blog67.fc2.com/</link>
<description>技術を磨くためです。＾￥＾
自分のため、皆さんのため</description>
<dc:language>ja</dc:language>
<items>
<rdf:Seq>
<rdf:li rdf:resource="http://yuanyp.blog67.fc2.com/blog-entry-8.html" />
<rdf:li rdf:resource="http://yuanyp.blog67.fc2.com/blog-entry-7.html" />
<rdf:li rdf:resource="http://yuanyp.blog67.fc2.com/blog-entry-6.html" />
<rdf:li rdf:resource="http://yuanyp.blog67.fc2.com/blog-entry-5.html" />
<rdf:li rdf:resource="http://yuanyp.blog67.fc2.com/blog-entry-4.html" />
</rdf:Seq>
</items>
</channel>
<item rdf:about="http://yuanyp.blog67.fc2.com/blog-entry-8.html">
<link>http://yuanyp.blog67.fc2.com/blog-entry-8.html</link>
<title>トランザクション管理の複雑性を克服する パート1</title>
<description> トランザクション管理の複雑性を克服する パート1The Rational Edgeトランザクション管理の複雑性を克服する パート1トランザクション・コーディネーション・サービスBioLogic Software Consulting, LLC主任ソフトウェアアーキテクトBenjamin Lieberman2006/8/23The Rational Edgeより：サービス指向のインフラの中で発生するビジネストランザクションは非常に複雑だ。それは、サービスが非同時的で、さまざまな形態
 </description>
<content:encoded>
<![CDATA[ トランザクション管理の複雑性を克服する パート1<br /><br />The Rational Edge<br /><br />トランザクション管理の複雑性を克服する パート1<br />トランザクション・コーディネーション・サービス<br /><br />BioLogic Software Consulting, LLC<br />主任ソフトウェアアーキテクト<br />Benjamin Lieberman<br /><br />2006/8/23<br /><br />The Rational Edgeより：サービス指向のインフラの中で発生するビジネストランザクションは非常に複雑だ。それは、サービスが非同時的で、さまざまな形態を取り、分散し、不透明な場合が多いためだ。本稿は、トランザクション・コーディネーションサービスがこの複雑性をどのように調整し、管理するかについて説明する。<br /><br />　 トランザクションは、業務上のあらゆるやりとりに必要なものだ。トランザクションは、特定の業務活動が隅々まで適切に遂行されるのを保証する目的で存在する。どこか1カ所でも不備が発生したら、データの一貫性を維持するため、トランザクション全体を遂行できなくしなくてはならない。また、サービス指向アーキテクチャの出現により、Webベースサービスの特性もあって、トランザクション管理の複雑性はさらに増している。サービスは非同時的で、さまざまな形態を取り、分散し、不透明な場合が多い。サービス指向アプローチの価値を企業がフル活用するためには、資源確保、業務機能調整、並行処理コントロール、そして復旧処理をはじめとするトランザクション管理の仕組みを、サービスの開発者が理解しておく必要がある。 <br /><br />　本稿は、複雑なサービス指向アーキテクチャにトランザクションをインプリメントする際の特性と問題を2回に分けて解説する。今回のパート1では、資源確保、業務機能管理、並行処理コントロール、そして障害復旧をはじめとする複雑な業務活動を整理し、コントロールできるトランザクション・コーディネーションサービス（TCS）を通してトランザクション管理を解説する。一方のパート2では、TCSの候補になるアーキテクチャを紹介する。 ]]>
</content:encoded>
<dc:subject>SCEA苦闘記</dc:subject>
<dc:date>2006-08-24T17:04:11+09:00</dc:date>
<dc:creator>袁　一頻</dc:creator>
<dc:publisher>FC2-BLOG</dc:publisher>
</item>
<item rdf:about="http://yuanyp.blog67.fc2.com/blog-entry-7.html">
<link>http://yuanyp.blog67.fc2.com/blog-entry-7.html</link>
<title></title>
<description> J2EECommon Architectures and Protocols■ Given an architecture described in terms of network layout, list benefits andpotential weaknesses associated with it.■ Role of an architect■ Architecture defined■ Architectural terms■ Architecture versus design■ Fundamentals of architecture■ Capabilities of an architecture■ Design goals of architecture■ Architecture tiers and layers■ Benefits 
 </description>
<content:encoded>
<![CDATA[ J2EE<br />Common Architectures and Protocols<br /><br />■ Given an architecture described in terms of network layout, list benefits and<br />potential weaknesses associated with it.<br /><br /><br />■ Role of an architect<br />■ Architecture defined<br />■ Architectural terms<br />■ Architecture versus design<br />■ Fundamentals of architecture<br />■ Capabilities of an architecture<br />■ Design goals of architecture<br />■ Architecture tiers and layers<br />■ Benefits and weaknesses of architecture<br />■ Protocols: HTTP, HTTPS, IIOP<br />Types of Architecture<br />	System Architecture						>>>> 60%<br />	Reference Architecture					>>>> 50%<br />	Flexible Reference Architecture				>>>> 50%<br /><br />Architectural Design and Principles<br />	Where Architecture Fits in Analysis, Design, and Development	>>>> 50%<br />Architecture vs. Design					>>>> first 50%<br />■ A system architecture document to describe your existing hardware, software, network topology, and other components.<br />■ An application architecture document to describe the application’s major structure, including a logical view of all architecturally significant components, use case components, and legacy components.<br />■ A components design guideline to describe all design guidelines and architectural decisions, explain all those decisions, and describe possible consequences if an alternative option is used. These guidelines should capture all-important base determinants that the new component design must respect to maintain the system’s architectural integrity.<br />■ An architectural prototype to evaluate new technologies, gain experience developing and deploying J2EE applications, build architectural frameworks, and address risks by measuring performance and scalability, as well as proof of concept for the project stakeholders.<br />Steps in Software Development				>>>> 50%<br />Requirement Analysis/Problem Statement<br />Object-Oriented Analysis<br />Architectural Analysis<br />design guideline(User Case, Sequence, Class, Collaboration Diagrams)<br />Object-Oriented Design<br />Architectural Design<br />Ultimately the object creation<br />■ Develop package dependency diagrams.<br />■ Decide how the classes in different package interact.<br />■ Develop deployment diagrams.<br />■ Decide where the software components will reside in deployment.<br />	<br />Architectural Terminology						>>>> 50%<br />	Abstraction						>>>><br />	Surface Area						>>>><br />	Boundaries						>>>><br />	Brittleness						>>>><br />	Capabilities, Friction, and Layering				>>>><br /><br />Principles of Architecture<br />	Layering							>>>><br />	Tiers							>>>><br />	Basic Three-Tier Java Technology Architecture			>>>>	<br />	Capabilities of an Architecture					>>>><br /><br />Creating an Architecture<br />Using Distributed Services and J2EE<br />	Enterprise JavaBeans					>>>><br />	Distributed Application Lifecycle				>>>><br />	Iterative Development/MVC					>>>><br />	Simplified Architecture and Development			>>>><br />	Component-Based Application Models				>>>><br />	Support for Client Components				>>>><br />	Support for Business Logic Components			>>>><br /><br />J2EE API’s and Certification<br />	J2EE Specification						>>>><br />	J2EE Reference Implementation				>>>><br />	Sun BluePrint Design Guidelines for J2EE			>>>><br /><br />XML and J2EE<br />	Why Use XML?						>>>><br />	Electronic Data Exchange and E-Commerce			>>>><br />	Electronic Data Interchange (EDI)				>>>><br />	Enterprise Application Integration (EAI)				>>>><br />	Software Development and XML				>>>><br />	XML Technology and the Java Platform				>>>><br /><br />Distributed Programming Services<br />	Naming and Registration					>>>><br />	Remote Method Invocation (RMI)				>>>><br />	Protocols							>>>><br />	Distributed Object Frameworks				>>>><br /><br /> ]]>
</content:encoded>
<dc:subject>SCEA苦闘記</dc:subject>
<dc:date>2006-08-23T16:00:13+09:00</dc:date>
<dc:creator>袁　一頻</dc:creator>
<dc:publisher>FC2-BLOG</dc:publisher>
</item>
<item rdf:about="http://yuanyp.blog67.fc2.com/blog-entry-6.html">
<link>http://yuanyp.blog67.fc2.com/blog-entry-6.html</link>
<title>QoSについて　参考資料その１</title>
<description> Java Enterprise System 2005Q4 - Japanese &gt;&gt; Sun Java Enterprise System 2005Q4 配備計画ガイド &gt;&gt; 3.  技術要件ソリューションライフサイクルの技術要件フェーズでは、使用パターンの分析を行い、ユースケースを特定し、提案する配備ソリューションのサービス品質要件を決定します。この章で説明する内容は、次のとおりです。「技術要件について」 「使用パターンの分析」 「ユースケース」 「サービス品質要件」 「サ
 </description>
<content:encoded>
<![CDATA[ <a href="http://docs.sun.com/app/docs/doc/819-3449/6n5ludf3s?l=ja&a=view" target="_blank">Java Enterprise System 2005Q4 - Japanese >> Sun Java Enterprise System 2005Q4 配備計画ガイド >> 3.  技術要件</a><br />ソリューションライフサイクルの技術要件フェーズでは、使用パターンの分析を行い、ユースケースを特定し、提案する配備ソリューションのサービス品質要件を決定します。<br /><br />この章で説明する内容は、次のとおりです。<br />「技術要件について」 <br />「使用パターンの分析」 <br />「ユースケース」 <br />「サービス品質要件」 <br />「サービスレベル要件」 ]]>
</content:encoded>
<dc:subject>SCEA苦闘記</dc:subject>
<dc:date>2006-08-14T11:21:44+09:00</dc:date>
<dc:creator>袁　一頻</dc:creator>
<dc:publisher>FC2-BLOG</dc:publisher>
</item>
<item rdf:about="http://yuanyp.blog67.fc2.com/blog-entry-5.html">
<link>http://yuanyp.blog67.fc2.com/blog-entry-5.html</link>
<title>GRASPパターン一覧</title>
<description> Controllerコントローラーパターン。イベント発生時の責務を割り当てる。Creator生成者パターン。インスタンス生成の責務を割り当てる。Expert情報エキスパートパターン。必要な情報を保持しているクラスに責務を割り当てる。High Cohesion 高凝縮性パターン。意味的に関係の深い機能を一つのオブジェクトに凝縮させるように責務を割り当てる。Indirection間接化パターン。クラス同士を直接結びつけずに、間接クラスを定
 </description>
<content:encoded>
<![CDATA[ <br /><font color="#000080">Controller</font><br><br />コントローラーパターン。イベント発生時の責務を割り当てる。<br><br /><font color="#000080">Creator<br><br /></font>生成者パターン。インスタンス生成の責務を割り当てる。<br><br /><font color="#000080">Expert<br><br /></font>情報エキスパートパターン。必要な情報を保持しているクラスに責務を割り当てる。<br><br /><font color="#000080">High Cohesion<br> <br /></font>高凝縮性パターン。意味的に関係の深い機能を一つのオブジェクトに凝縮させるように責務を割り当てる。<br><br /><font color="#000080">Indirection<br><br /></font>間接化パターン。クラス同士を直接結びつけずに、間接クラスを定義する。<br><br /><font color="#000080">Low Coupling<br> <br /></font>疎結合性パターン。オブジェクト同士の結合度が低くなるように責務を割り当てる。<br><br /><font color="#000080">Polymorphism<br><br /></font>多態性パターン。異なる振る舞いを行う同じ操作を定義する。<br><br /><font color="#000080">Pure Fabrication<br> <br /></font>純粋架空物パターン。人工的なクラスを生成し、責務を割り当てる。<br><br /><font color="#000080">Variation Protected<br> <br /></font>バリエーション防御パターン。将来予想されるバリエーションの増加を予想しておく。</p><br /> ]]>
</content:encoded>
<dc:subject>日記</dc:subject>
<dc:date>2006-06-26T09:32:44+09:00</dc:date>
<dc:creator>袁　一頻</dc:creator>
<dc:publisher>FC2-BLOG</dc:publisher>
</item>
<item rdf:about="http://yuanyp.blog67.fc2.com/blog-entry-4.html">
<link>http://yuanyp.blog67.fc2.com/blog-entry-4.html</link>
<title>In pursuit of code quality: Refactoring with code metricsOn-target refactoring with code metrics and the Extract Method pattern </title>
<description> Level: IntermediateAndrew Glover (aglover@stelligent.com), President, Stelligent Incorporated 30 May  2006In earlier installments of In pursuit of code quality, you learned how to use code metrics to objectively  measure code quality. This month, Andrew Glover shows you how to use those same metrics and the Extract Method pattern for targeted  refactoring.  In middle school, I had an English t
 </description>
<content:encoded>
<![CDATA[ <p>Level: Intermediate</p><p><a href="#author">Andrew Glover</a> (<a href="mailto:aglover@stelligent.com?subject=Refactoring with code metrics">aglover@stelligent.com</a>), President, Stelligent Incorporated<br /></p><p> 30 May  2006</p><blockquote>In earlier installments of <a href="http://www.ibm.com/developerworks/views/java/libraryview.jsp?search_by=code+quality:"><i>In pursuit of code quality</i></a>, you learned how to use code metrics to objectively  <br />measure code quality. This month, Andrew Glover shows you how to use those same metrics and the Extract Method pattern for targeted<br />  refactoring.</blockquote><!--START RESERVED FOR FUTURE USE INCLUDE FILES--><script language="JavaScript" type="text/javascript">  <br /><!--<br />if (document.referrer&&document.referrer!="") { <br />   // document.write(document.referrer);<br />   var q = document.referrer;<br />   var engine = q;<br />   var isG = engine.search(/google\.com/i);<br />   var searchTerms;<br />   //var searchTermsForDisplay;<br />   if (isG != -1) { <br />	   var i = q.search(/q=/);<br />	   var q2 = q.substring(i+2);<br />	   var j = q2.search(/&/);<br />	   j = (j == -1)?q2.length:j;<br />	   searchTerms = q.substring(i+2,i+2+j);<br />	   if (searchTerms.length != 0) {<br />	       searchQuery(searchTerms);<br />	       document.write("<div id=\"contents\"></div>");<br />	   }<br />   } <br />}<br />//--><br /></script><!--END RESERVED FOR FUTURE USE INCLUDE FILES--><p>In middle school, I had an English teacher who claimed that<br />"writing is rewriting what one has <i>already</i> rewritten." It<br />wasn't until college that I actually took his words to<br />heart. Not surprisingly, once I consciously embraced this practice, I<br />started to enjoy writing. I started to take pride in<br />what I was writing. I began to put real effort into how the<br />words flowed and the meaning I was trying to convey.<br><br />When I began my career as a developer, I would read technical books<br />authored by seasoned professionals and wonder why they spent so much<br />time writing about code. At the time, coding seemed like such an<br />easy job -- someone (invariably senior to me) would give me a<br />problem and I would solve it any way I could.<br><br />It wasn't until I started working on large projects with other<br />developers that I began to understand what taking my craft seriously<br />meant. It was at this point in my career that I started to consciously<br />care about the code I was writing, and even to care about the code<br /><i>others</i> were writing. I now knew that if I didn't pay attention to <br />code quality, at some point there would<br />be a late night where I'd be fishing through a mess of spaghetti looking<br />for the proverbial bad meatball.<br><br />My <i>ah ha!</i> moment came in late 1999 when I read Martin Fowler's<br />seminal book, <i>Refactoring: Improving the Design of Existing Code</i>,<br />which cataloged a series of refactoring patterns and established, thereby, a<br />common vocabulary for refactoring. Up until then, I had been refactoring my<br />code (and even other's code) without knowing it. I now started to take even more <br />pride in the code I was writing and even in what I was refactoring, for I was<br />putting real effort into how the code flowed and how it could become<br />more maintainable over time. </p><br /><br /><p><a name="N10084"><span class="atitle">What is refactoring?<br><br /></span></a>In my opinion, refactoring is the act of improving code that has <i>already been improved</i>. In essence, refactoring is a neverending<br />code-editing process that attempts to enhance the maintainability of a<br />body of code through structural improvements, <i>without</i> changing<br />the code's overall behavior. It's important to remember that refactoring<br />is markedly different from <i>rewriting</i> code.<br><br />Rewriting code alters the behavior and even the contract of code,<br />while refactoring preserves its outward interface. To a client of a<br />refactored method, there is no perceivable difference. Things work as<br />they did before, albeit better, most often because of enhanced testability<br />or an apparent performance improvement.</p><br /><br /><p><a name="N1009A"><span class="smalltitle"><b><font color="#000080">Subjective and objective refactoring</font></b><br><br /></span></a>The question then becomes <i>How do I know when I should<br />refactor?</i> The maintainability of a piece of code is arguably a<br />matter of subjectivity. Most of us would, however, find it far easier to<br />maintain something we'd written than to maintain someone else's code.<br />But therein lies the rub -- maintaining your own code throughout your<br />career is a challenging proposition at best. There are few true "code<br />cowboys," lucky enough to travel from job to job, never having to<br />maintain anyone else's code.  For most of us, having to maintain someone<br />else's code is just part of being a programmer. The means of deciding<br />whether code should be refactored is often <i>subjective</i>.<br><br />It's also possible to objectively determine whether code should be refactored, however, whether it's yours or someone else's. In <a href="#resources">previous articles in this series</a>, I've shown you <br />how to use code metrics to objectively measure code quality. In fact, <br />you can use code metrics to easily spot code that might be difficult to <br />maintain. Once you've objectively determined there's a problem in the <br />code, you can use a handy refactoring pattern to improve it.</p><br /><br /><table align="right" border="0" cellspacing="0" cellpadding="0" width="40%"><tr><td width="10"><img alt="" height="1" width="10" src="unsaved://www.ibm.com/i/c.gif"/></td><td><table border="1" cellspacing="0" cellpadding="5" width="100%"><tr><td bgcolor="#eeeeee"><br /><a name="N100B3"><b>Always run a test case!</b></a><br /><br /><p> The trick to refactoring code you haven't authored is to do so<br /><i>without making it worse</i>. One thing I learned early in my refactoring<br />journey was the importance of having a test case <i>before</i> I changed<br />anything. I learned this lesson the hard way one night as I fished<br />through my own well-laid-out collection of refactored methods, only to<br />discover that I'd inadvertently broken someone else's working code  by<br />attempting to refactor it without a corresponding test case. Please heed<br />my warning and always run a test case before you refactor! </p><br /></td></tr></table></td></tr></table><br /><br /><p><a name="N100C2"><span class="atitle"><b><font color="#000080">The Extract Method pattern</font></b><br><br /></span></a>In the years since Martin Fowler's book was published, many new refactoring<br />patterns have been cataloged; however, by far the easiest pattern to learn, and arguably still the most effective one, remains <i>Extract Method</i>. In this pattern, a logical portion of a method is<br />surgically removed and given its own method definition. The body of the<br />method removed is now replaced with a call to the newly defined method,<br />as demonstrated in the UML diagram shown in Figure 1:</p><br /><br /> <br /><br /><br /><a name="N100D0"><b>Figure 1. The Extract Method pattern in action</b></a><br /><br /><img alt="" border="0" height="100" src="extract-method.gif" width="375"/><br /><br /><br /><br /><br /><p>The Extract Method pattern provides two key benefits:</p><br /><br /><ul><br /><br /><li>The original method is now shorter and conceivably easier to comprehend.</li><br /><br /><li>The body of logic removed and placed into its own method is now easier to test.</li><br /><br /></ul><br /><br /><br /><table border="0" cellspacing="0" cellpadding="0" width="100%"><tr><td><img width="100%" src="unsaved://www.ibm.com/i/v14/rules/blue_rule.gif" height="1" alt=""/></td></tr></table><br /><br /><p><a name="N100EB"><span class="atitle"><b><font color="#000080">A cure for cyclomatic complexity</font></b></span></a></p><br /><p><b><font color="#000080">As it turns out, Extract Method is an excellent dose of medicine for<br />a method that has been infected with a high cyclomatic complexity value.<br />As you may remember, cyclomatic complexity measures the number of paths<br />through a method; therefore, it stands to reason that if you<br /><i>extract</i> some of those paths, the overall complexity of the<br />refactored method will be less.</font></b> </p><br /><br /><p><b><font color="#000080">For example, imagine that after running a code analysis tool like<br />PMD, <br />the resulting report indicates that a class contains a method with a<br />high cyclomatic complexity value, as shown in<br />Figure 2:</font></b> </p><br /> <br /><br /><br /><br /><a name="N100FC"><b>Figure 2. A cyclomatic complexity value of 23!</b></a><br /><br /><img alt="" border="0" height="80" src="pmd-cc.jpg" width="572"/><br /><br /><br /><br /><p>Upon a close visual examination of the method, it turns out that <br />it's unusually long with excessive conditional logic. As I pointed out <br />earlier in this series (see <a href="#resources">Resources</a>), this increases <br />the risk of defects within the method. Thankfully, the <code>updateContent()</code> method is not without test cases. <br />Even though the method has been deemed risky, the tests mitigate <i>some</i> of the risk. </p> <br /><br /><p>On the other hand,  the tests would have had to be<br />exceptionally well written to hit each of the 23 paths in the <code>updateContent()</code> method. In fact, a good rule of thumb would<br />indicate that <i>at least 23 tests</i> should have been written. Moreover,<br />writing a test case that can precisely isolate the eighteenth conditional in<br />the method turns out to be extremely challenging! </p><br /><br /><p><a name="N10123"><span class="smalltitle">When small is beautiful</span></a></p><br /><p> Whether or not to accurately test the 18th conditional in a<br />long method is a matter of judgment. If that logic embodies true<br />business value, however, then you'll want to test it, in which case you'll<br />get to see the Extract Method pattern at work. Minimizing<br />the risk is a simple matter of breaking up the conditional logic into<br />smaller pieces, thus creating new methods that can be easily tested. </p><br /><br /><p>For instance, the following small piece of conditional logic in the <code>updateContent()</code> method creates a status <code>String</code>. As shown in Listing 1, the logic appears easy enough to isolate: </p><br /><br /><br /><br /><a name="code1"><b>Listing 1. Conditional logic ripe for the extraction</b></a><br /><table bgcolor="#eeeeee" width="100%" cellpadding="5" cellspacing="0" border="1"><tr><td><code><pre class="section"><br /><br />//...other code above<br /><br />String retstatus = null;<br />if ( lastChangedStatus != null &amp;&amp; lastChangedStatus.size() &gt; 0 ){<br /> if ( status.getId() == ((IStatus)lastChangedStatus.get(0)).getId() ){<br />  retstatus = &quot;Change in Current status&quot;;<br /> }else{<br />  retstatus = &quot;Account Previously Changed in: &quot; + <br />    ((IStatus)lastChangedStatus.get(0)).getStatusIdentification();<br /> }<br />}else{<br />  retstatus = &quot;No Changes Since Creation&quot;;<br />}<br /><br />//...more code below<br /></pre></code></td></tr></table><br /><br /><br /><p>By extracting this bit of logic into a succinct, new method (shown in Listing 2) you've achieved two things: one, you've lowered the overall<br />complexity of the <code>updateContent()</code> method <br />by about 5; two, you've sufficiently isolated the logic so that you easily test it.</p><br /><br /><br /><br /><a name="code2"><b>Listing 2. Extract Method yields getStatus</b></a><br /><table bgcolor="#eeeeee" width="100%" cellpadding="5" cellspacing="0" border="1"><tr><td><code><pre class="section"><br /><br />private String getStatus(IStatus status, List lastChangedStatus) {<br />  String retstatus = null;<br />  if ( lastChangedStatus != null &amp;&amp; lastChangedStatus.size() &gt; 0 ){<br />    if ( status.getId() == ((IStatus)lastChangedStatus.get(0)).getId() ){<br />      retstatus = &quot;Change in Current status&quot;;<br />    }else{<br />      retstatus = &quot;Account Previously Changed in: &quot; + <br />	    ((IStatus)lastChangedStatus.get(0)).getStatusIdentification();<br />    }<br />  }else{<br />    retstatus = &quot;No Changes Since Creation&quot;;<br />  }<br />  return retstatus;<br />}<br /></pre></code></td></tr></table><br /><br /><br /><p>Now you can replace a part of the body of the <code>updateContent()</code> method with a call<br />to the newly created <code>getStatus()</code> method, as<br />shown in Listing 3:</p><br /><br /><br /><br /><a name="code3"><b>Listing 3. Calling getStatus</b></a><br /><table bgcolor="#eeeeee" width="100%" cellpadding="5" cellspacing="0" border="1"><tr><td><code><pre class="section"><br /><br />//...other code above<br /><br />String iStatus = getStatus(status, lastChangedStatus);<br /><br />//...more code below<br /></pre></code></td></tr></table><br /><br /><br /><p>Remember to run the existing tests to verify nothing has broken!</p><br /><br /><br /><table border="0" cellspacing="0" cellpadding="0" width="100%"><tr><td><img width="100%" src="unsaved://www.ibm.com/i/v14/rules/blue_rule.gif" height="1" alt=""/></td></tr></table><br /><br /><p><a name="N1016A"><span class="atitle">Testing private methods</span></a></p> <br /><p>You'll note that the new <code>getStatus()</code> method <br />defined in <a href="#code2">Listing 2</a> is declared as <code>private</code>. This creates an interesting testing challenge should you want to verify the behavior of that method <i>in isolation</i>!  There are a number of ways to approach this issue:</p> <br /><br /><ul><br /><br /><li>Make the method <code>public</code>.</li><br /><br /><li>Make the method <code>protected</code> and put the test case in the same package.</li><br /><br /><li>Make an inner class in the parent class, which is a test case.</li><br /><br /></ul><br /><br /><p> It turns out there is another option as well: leave the method as<br />declared (that is, <code>private</code>) and use the nifty<br />JUnit-addons project to test it. </p><br /><br /><p><a name="N1019D"><span class="smalltitle">The PrivateAccessor class</span></a></p> <br /><p>The JUnit-addons project has a few handy utilities that facilitate<br />testing with JUnit. One of the most useful of these is the<br /><code>PrivateAccessor</code> class, which makes testing<br /><code>private</code> methods a snap regardless of your<br />testing framework of choice. The <code>PrivateAccessor</code><br />class has no implicit dependency on JUnit, so you can use it with <br />testing frameworks such as TestNG. </p><br /><br /><p> The <code>PrivateAccessor</code>'s API is simple -- by<br />providing the name of the method (as a <code>String</code>) and its corresponding parameter types and<br />associated values (in <code>Class</code> and <code>Object</code> arrays respectively) to the <code>invoke()</code> method, the value of the invoked method is<br />returned. Under the covers, the <code>PrivateAccessor</code> class actually turns off object<br />accessibility using the Java Reflection API. Keep in mind, however, that<br />if your VM has custom security settings, the utility may not function<br />correctly.</p><br /><br /><p>In Listing 4, I call the <code>getStatus()</code> method<br />with both parameter values set to <code>null</code>. The <code>invoke()</code> method<br />returns an <code>Object</code>, hence the cast to a <code>String</code>. Also note that the <code>invoke()</code> method declares that it <code>throws Throwable</code>, so you either must catch it or<br />let your testing framework handle it, as I've done. </p><br /><br /><br /><br /><a name="code4"><b>Listing 4. Testing a private method</b></a><br /><table bgcolor="#eeeeee" width="100%" cellpadding="5" cellspacing="0" border="1"><tr><td><code><pre class="section"><br /><br />public void testGetStatus() throws Throwable{<br />  AccountAction action = new AccountAction();<br />  <br />  String value = (String)PrivateAccessor.invoke(action,<br />      &quot;getStatus&quot;, new Class[]{IStatus.class, List.class},<br />       new Object[]{null, null});<br />  <br />  assertEquals(&quot;should be No Changes Since Creation&quot;, <br />    &quot;No Changes Since Creation&quot;, value);<br />}<br /></pre></code></td></tr></table><br /><br /><br /><p>Note that the <code>invoke()</code> method is overridden to either take an <code>Object</code> instance,<br />as in Listing 4, or a <code>Class</code>, in the case that<br />the desired <code>private</code> method is also <code>static</code>. </p><br /><br /><p>Keep in mind also that using reflection to invoke <code>private</code> methods does introduce a level of<br />brittleness to the resulting tests. Should someone rename the <code>getStatus()</code> method, the above test will fail<br />miserably; however, if you test frequently, you can quickly make the appropriate fixes. </p><br /><br /><br /><p><a name="N10218"><span class="atitle">In conclusion</span></a></p> <br /><p>When battling cyclomatic complexity, keep in mind that the vast<br />majority of paths coded into an application are <i>inherent</i> to its<br />overall behavior. That is, it is quite difficult to dramatically reduce<br />the total number of paths. Refactoring only allows you to push those<br />paths into smaller sections of code, which then become easier to test.<br />Those small sections of code also become easier to maintain.</p><br /><br />&nbsp;<p><a name="resources"><span class="atitle">Resources</span></a></p><b>Learn</b><br /><ul><li>"<a href="http://www.ibm.com/developerworks/java/library/j-cq03316/"><i>In pursuit of code quality</i>: Monitoring cyclomatic complexity</a>" (Andrew Glover,<br />    developerWorks, March 2006): Learn the simple code metrics that let you <br />spot and correct risky code.<br /><br /></li><li>"<a href="http://www.ibm.com/developerworks/java/library/j-cq04256/index.html"><i>In pursuit of code quality</i>: Code quality for software architects</a>" (Andrew Glover,<br />    developerWorks, April 2006): Use coupling metrics to support your <br />system architecture.<br /><br /></li><li> <br /><a href="http://www.ibm.com/developerworks/views/java/libraryview.jsp?search_by=code+quality"><i>In pursuit of code quality</i>:</a> Read the complete series by Andrew Glover. <br /><br /><br /></li><li>"<a href="http://www.ibm.com/developerworks/java/library/j-djc01153.html">Diagnosing Java code: Design for easy code maintenance</a>" (Eric Allen,<br />    developerWorks, January 2003): Discusses the craft of writing easily maintainable code and suggests tools for<br />    refactoring.<br /><br /></li><li>"<a href="http://www.ibm.com/developerworks/java/library/j-legacytest.html">Testing legacy code</a>"<br />    (Elliotte Rusty Harold, developerWorks, April 2006): What to do when you stumble across legacy code that's never been tested.<br /><br /></li><li>"<a href="http://www.ibm.com/developerworks/java/library/j-pmd/">Zap bugs with PMD</a>"<br />    (Elliotte Rusty Harold, developerWorks, January 2005): Use PMD's built-in rules and your own custom rule sets to improve the quality of your Java code.<br /><br /></li><li><a href="http://www.amazon.com/exec/obidos/ASIN/0201485672"><i>Refactoring: Improving the Design of Existing Code</i></a> (by Martin Fowler; Addison Wesley, 1999): The essential introduction to refactoring patterns.<br /><br /></li><li><a href="http://www.ibm.com/developerworks/java/">The Java technology zone</a>: Hundreds of articles about every aspect of Java programming.</li></ul><br /><b>Get products and technologies</b><br /><ul><li><a href="http://junit-addons.sourceforge.net/">JUnit-addons</a>: A useful library for anyone using<br />    JUnit.<br /><br /></li><li><a href="http://sourceforge.net/projects/pmd/">PMD</a>: Scans Java code <br />for problems.<br /><br /></li></ul><br /><b>Discuss</b><br /><ul><li><a href="http://www.ibm.com/developerworks/forums/dw_forum.jsp?forum=812&amp;cat=10">Participate in the discussion forum</a>.<br /><br /></li><li><a href="http://www.ibm.com/developerworks/blogs/">developerWorks <br />blogs</a>: Get involved in the developerWorks community!</li></ul>&nbsp;<p><a name="author"><span class="atitle">About the author</span></a></p><table border="0" cellspacing="0" cellpadding="0" width="100%"><tr><td colspan="3"></td></tr><tr align="left" valign="top"><td><p><img alt="" height="80" name="Andrew Glover" src="http://www-106.ibm.com/developerworks/i/p-aglover.jpg" width="64" align="left"/></p></td><td><img alt="" width="4" height="5" src="unsaved://www.ibm.com/i/c.gif"/></td><td width="100%"><p>Andrew Glover is the President of <a href="http://www.stelligent.com">Stelligent Incorporated</a>, which helps companies address software quality with effective developer testing strategies and continuous integration techniques that enable teams to monitor code quality early and often. He is the co-author of <a href="http://www.wiley.com/WileyCDA/WileyTitle/productCd-047144846X,descCd-authorInfo.html">Java Testing Patterns</a> (Wiley, September 2004).</p></td></tr></table> <br /> ]]>
</content:encoded>
<dc:subject>コード品質</dc:subject>
<dc:date>2006-06-09T11:16:58+09:00</dc:date>
<dc:creator>袁　一頻</dc:creator>
<dc:publisher>FC2-BLOG</dc:publisher>
</item>
</rdf:RDF>