2013.02.10
デザインパターンよりも、まずリファクタリングを学んだほうがいい
ウィキペディア - デザインパターン (ソフトウェア)
http://ja.wikipedia.org/wiki/%E3%83%87

<ソフトウェア開発におけるデザインパターン(型紙(かたがみ)または設計パターン、英: design pattern)とは、過去のソフトウェア設計者が発見し編み出した設計ノウハウを蓄積し、名前をつけ、再利用しやすいように特定の規約に従ってカタログ化したものである>。

ウィキペディア - リファクタリング
http://ja.wikipedia.org/wiki/%E3%83%AA..

<リファクタリング (refactoring) とはコンピュータプログラミングにおいて、プログラムの外部から見た動作を変えずにソースコードの内部構造を整理すること。いくつかのリファクタリング手法の総称としても使われる。十分に確立された技術とはいえず、「リファクタリング」の語にも厳密な定義があるわけではない>。

私の個人的な意見だが、これからデザインパターンを学ぼうとしている人は、それよりもリファクタリングを先に学んだほうがいいと思う。

デザインパターンは、うまくいくパターンを集めたもので、いわば道具箱である。しかし、それをいつ使えばいいのか、いま直面している状況にどれを適用できるかの判断は、あるていど慣れるまでは、なかなかむずかしい。

これに対してリファクタリングは、まずダメな状態、「コードの臭い」から出発する。いろいろな「コードの臭い」に対して、それをどうやって改善すればいいか、というノウハウの集合がリファクタリングである。

ウィキペディアの「コードの臭い」には、次のようなものがあげられている。

重複したコード - 同一あるいは同様のコードが複数箇所に存在。
・長すぎるメソッド - メソッド、関数、手続きが長くなりすぎている。
・巨大なクラス - 大きくなりすぎたクラス。神オブジェクト参照。
・機能の横恋慕 - 他クラスのメソッドを過度に用いるクラス。
・不適切な関係 - 他のクラスの実装の詳細に依存しているクラス。
・相続拒否 - 基底クラスの規約が尊重されない形でのメソッドオーバーライド。リスコフの置換原則参照。
・怠け者クラス - 行うことが少なすぎるクラス。
・重複メソッド - 同一あるいは同様のメソッドが複数箇所に存在。
・不自然な複雑さ - 簡潔な設計で十分なところに、過剰に複雑なデザインパターンの使用を強制する。

こういった「コードの臭い」は、「アンチパターン」でもある。コードを書いていて、このような「コードの臭い」やアンチパターンを見つけるのは、わりと容易である。これに比べると、「どのデザインパターンが使えるか」を見つけ出すのは、はるかにむずかしいだろう。

ウィキペディアの「リファクタリング」では、次のようなものがあげられている。

・メソッドを抽出する
・双方向関連を単方向へ変更する
・クラスの抽出
・switch文をポリモーフィズムに置き換える
・メンバの移動
・継承を委譲に置き換える
・ダウンキャストをカプセル化する
・コンストラクタをFactory Methodに置き換える
・引数オブジェクトの導入
・クラス・メソッド・属性の名称を変更する

この中で私が特によく使うのは、「クラスの抽出」「継承を委譲に置き換える」「引数オブジェクトの導入」あたりだ。これらのリファクタリングを私がよく使うということは、それが私のコードの弱みを突いている、ということを意味している。つまり、私のコードはクラスが肥大化しすぎであり、継承を使いすぎであり、引数をバラバラのまま渡しすぎなのだ。

リファクタリングの代名詞とも言える第一人者、マーティン・ファウラーが運営する「Refactoring Home Page」では、リファクタリングが多数集められている。多くのリファクタリングにクラス図やコード例がつけられており、カタログとして使いやすい(それぞれページが短いので、スマホでも見やすい)。より詳しく解説した、ファウラーによる書籍『Refactoring』(日本語訳『リファクタリング』)もある。

リファクタリングをあるていど学んでから、そのあとにデザインパターンを学べば、それがなぜすぐれた設計なのかも理解しやすいし、それをいつ使えばいいかという「使いどころ」も、おそらく見えやすくなると思う。


関連エントリ:
ケント・ベック『実装パターン』(2008年) 実装パターンの6つの原則
http://mojix.org/2012/11/21/beck-impl-pattern