![]() |
連載
|
|
|
|
Back Issue
|
||||||||||||||
|
前回は、プロジェクトの進ちょくを管理するトラッキング・システムの一部のコードを示し、そのコードに対してCompositeパターンを導くための準備段階のリファクタリングを行った。引き続き、今回はさらに本格的なリファクタリングを施していこう。
■リファクタリング1:オブジェクトとして表現可能な「じか書きされた子要素」の識別
今回まず着目するのは、前回のリストで示した、次のようなコードで記述している、じか書きされたツリー構造の「じか書きされた子要素」である。
xml.Append("<task");
xml.Append(" no=\"");
xml.Append(task.No.ToString());
xml.Append("\"");
xml.Append(" storyNo=\"");
xml.Append(task.StoryNo.ToString());
xml.Append("\">");
これを、オブジェクトによって構造化されたツリー構造へ置き換えるためには、段階を踏んでリファクタリングを行っていく必要がある。
最初のステップとして、このじか書きされたツリー構造の「じか書きされた子要素」をオブジェクトとして識別することから始めよう。ここで、識別されたオブジェクトはCompositeパターンのLeaf(単純要素)として振る舞うことになる。
XML文書の各エレメントは、名前と値を持ち、属性を指定できることが分かっている。そこでまずは、各エレメントを表現するElementクラスを想定し、それをテストする次のようなシンプルなテスト・コードを作成してみた。これはテスト駆動開発のアプローチであり、ここではいつものように、新しく追加するクラスが必要とする機能の設計をテスト・ファーストで行っていく。
なお本稿のコードは、前回と同様に、新しく追加した部分は青色、削除した部分は赤色で示している。
|
|
| 新しく作成されたElementクラスのテスト・クラス(C#) | |
そして、このテスト・コードを記述した段階で、ElementクラスがLeaf(単純要素)として振る舞えるように、次のような設計を行った。
(1)コンストラクタで名前を指定する
(2)AddAttributeメソッドで属性を追加できる
(3)Contentプロパティで値を設定できる
(4)ToStringメソッドで内容を出力できる
上記のテスト・コードをパスさせるためのElementクラスの実装コードはこのようになる。
|
|
| 新しく作成されたElementクラス(C#) | |
ここでコンパイルしてテストを実行してみよう。正常にコンパイルが完了し、テストも通るはずだ。
これでElementクラスがLeaf(単純要素)として振る舞えることを確認できた。
■リファクタリング2:クラスのインスタンスによる「じか書きされた子要素」の置き換え
次のステップとして、「じか書きされた子要素」を探し出し、新しく作成したElementクラスのインスタンスへと置き換えよう。
前回のリストのStoriesWriterクラスには、以下のようなじか書きされた子要素が存在している。
- WriteStoryContentToメソッド内のcontentエレメント
- WriteTaskActualPointToメソッド内のactualPointエレメント
- WriteTaskEstimatedPointToメソッド内のestimatedPointエレメント
- WriteTaskContentToメソッド内のcontentエレメント
そこで、これらのじか書きされた子要素をそれぞれElementクラスのインスタンスに置き換え、情報を蓄積するためのコレクティング・パラメータ(StringBuilder型の変数xml)にはElementクラスのToStringメソッドの戻り値を格納するように変更する。
子要素のインスタンスへの置き換えごとにコンパイルしてテストを実行する。どの段階でも正常にコンパイルが完了し、テストも通るはずだ。
|
|
| じか書きされた子要素がElementクラスのインスタンスに置き換えられたStoriesWriterクラス(C#) | |
■リファクタリング3:すべての「じか書きされた子要素」の置き換えと共通インターフェイスの抽出
CompositeパターンではLeaf(単純要素)とComposite(複合要素)をポリモーフィズムによって同一視するため、要素間で共通のインターフェイスを実装していることを保証する必要がある。つまり、すべてのLeaf(単純要素)においても共通のインターフェイスを実装していることを保証する必要がある。
そこで通常は、リファクタリング1とリファクタリング2を繰り返して、すべてのじか書きされた子要素を識別してクラスのインスタンスに置き換えた後に「インターフェイスの抽出(F)」もしくは「スーパー・クラスの抽出(F)」を行い、要素間で共通のインターフェイスを抽出する。
しかし、今回のリファクタリングでは、XML文書のツリー構造におけるすべてのLeaf(単純要素)はすでにElementクラスによってモデル化されており、インターフェイスが共通であることも保証されているので、わざわざインターフェイスを抽出する必要がない。
つまり、ここでは実際のリファクタリング作業は必要ない。従って、次のステップへと進むことにする。
| INDEX | ||
| .NETで始めるデザインパターン | ||
| 第6回 リファクタリングにより導き出すCompositeパターン | ||
| 1.Compositeパターンを導き出すリファクタリング | ||
| 2.GoFのCompositeパターンの構造との比較 | ||
| 3.Compositeパターンの導出手順とまとめ | ||
| 「.NETで始めるデザインパターン」 |
TechTargetジャパン
- Kinectが切り開く“夢の近未来” (2012/2/2)
日本を含めた世界中でKinect for Windowsセンサー商用版とSDK正式版がリリース。未来のコンピューティングはどう変化するのか? - 3つの視点でネイティブと.NETの適材適所を考察 (2012/1/31)
アプリ開発は「ネイティブ」と「.NET」、どちらが最良? その問いには「適材適所」と答えるしかない。では、“適所”は一体どこかを考察する - SQL Azure Data Sync入門 (2012/1/30)
SQL Azure/SQL Serverデータベース間のデータ同期を簡単に実現するサービスとは? その仕組みや使用手順を解説 - Windows Phoneアプリ市場の現状を分析する (2012/1/27)
Windows Phone のアプリ・ストアに日々登録されている多種多様なアプリ。カテゴリ別のアプリ数は? 市場の現状を明らかにする
|
|
キャリアアップ
スポンサーからのお知らせ
- - PR -
イベントカレンダー
- - PR -


