デザインパターンはソフトウェアの拡張性・再利用性を高める構成法のカタログである。しかし、拡張性・再利用性を指向しているのはデザインパターンだけではなく、言語自身も拡張性・再利用性を意図して設計されることがあり、そのような言語で既存のデザインパターンを使うと、拡張性・再利用性にさまざまな(往々にして良い)影響が現れる。ここでは、Java をベースとして拡張性・再利用性を指向した差分ベースモジュールという機構を持つ言語である MixJuice について、そのデザインパターン(GoF パターン 23種)への影響を述べる。
従来のオブジェクト指向言語で各パターンを使用する際に起きる問題点のうち、 MixJuice を用いることで改善できるものを表にまとめた。なお、 MixJuice による改善策の中にはトレードオフがあるものもある。 (表内のページ数は MixJuice が改善する問題点が、「デザインパターン」日本語版のどのページで述べられているかを示すものである。詳細については各パターンの説明のページを参照。)
| デザインパターン | 種別 | 導入 | 拡張 | 情報隠蔽 | 型安全性 | 単純化 | 使用するプログラミング技法 |
|---|---|---|---|---|---|---|---|
| AbstractFactory | 改善 | p.98 | アブストラクトメソッド追加 | ||||
| 別解 | p.98 | p.100 | ○ | 実装モジュール選択 | |||
| Builder | 改善 | p109 | ○ | メソッド追加・メソッド拡張 | |||
| 別解 | ○ | メソッド拡張・実装モジュール選択 | |||||
| FactoryMethod | 改善 | p.118 | 名前空間分離 | ||||
| 別解 | ○ | ○ | 実装モジュール選択 | ||||
| Prototype | 改善 | p.131 | アブストラクトメソッド追加 | ||||
| Singleton | 別解 | p.138 | クラスメソッド拡張 | ||||
| Adapter | 別解 | p.153 | p.152 | スーパーインターフェース追加 | |||
| Bridge | 改善 | ○ | アブストラクトメソッド追加・メソッド追加 | ||||
| 別解 | ○ | ○ | 実装モジュール選択 | ||||
| Composite | 改善 | ○ | スーパーインターフェース追加 | ||||
| Decorator | 改善 | p.191 | メソッド追加・アブストラクトメソッド追加 | ||||
| 別解 | p.190 | クラス拡張 | |||||
| Facade | 改善 | p.201 | 名前空間分離 | ||||
| 別解 | ○ | クラスメソッド追加 | |||||
| Flyweight | なし | ||||||
| Proxy | なし | ||||||
| ChainOfResponsibility | 改善 | ○ | p.241 | スーパーインターフェース追加・アブストラクトメソッド追加 | |||
| Command | なし | ||||||
| Interpreter | 改善 | ○ | p.265 | アブストラクトメソッド追加 | |||
| Iterator | 改善 | p.280 | 名前空間分離 | ||||
| Mediator | なし | ||||||
| Memento | 改善 | p.307 | 名前空間分離 | ||||
| Observer | 改善 | ○ | p.318 | クラス拡張 | |||
| State | 改善 | ○ | アブストラクトメソッド追加 | ||||
| Strategy | 改善 | p.339 | アブストラクトメソッド追加 | ||||
| 別解 | p.340 | 実装モジュール選択 | |||||
| TemplateMethod | 改善 | p.351 | ○ | メソッド実装 | |||
| Visitor | 改善1 | p.359 | 仕様モジュールと実装モジュールの分離 | ||||
| 改善2 | ○ | p.358 | アブストラクトメソッド追加 | ||||
| 別解 | ○ | アブストラクトメソッド追加 |
また、個々のパターンに関する利点とは別に、ひとつのクラスが複数のパターンに参加する場合 MixJuice では各パターンを分離して情報隠蔽を行なうことが容易という利点がある。なお、パターンはコラボレーションをなすことが多く、その場合、コラボレーションを分離できることを意味する。
本カタログは Design Patterns (Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides, Addison-Wesley, ISBN0-201-63361-2) およびその日本語版の「デザインパターン」(本位田真一、吉田和樹監訳、ソフトバンク株式会社、ISBN4-89052-797-4)からの引用をかなり含んでいる。各パターンの目的と、デザインパターンの問題点を述べている部分についてはパラグラフ単位でそのまま引用した。また、各パターンの構造を表すクラス図は、最新の UML の記法に描き直して用いた。
このカタログに載せたパターンの改善策のうちのいくつかは、 GoF パターンのクラス構造とは異なるクラス構造を使用しており、ここではそのようなものを別解と呼んでいる。
MixJuice により、デザインパターンにはさまざまな影響が現れるが、ここでは影響を次の 5種に分類する。
既存のクラスをあるデザインパターンの新たな構成要素にするために、従来はソースコードの編集の必要があったものが、 MixJuice を用いることによって、編集の必要がなくなる。逆に言えば、1つのクラスが複数のデザインパターンに参加している場合でも、個々のデザインパターンごとに別のモジュールに分離して記述可能である。つまり、1つのデザインパターンに関するアスペクトを分離することが可能である。このことはプログラムのモジュラリティ向上に貢献する。
パターンを用いたプログラムに新たな機能を追加するとき、従来はソースコードの編集の必要があったものが、 MixJuice を用いることによって、編集の必要がなくなる。このことは、パターンを用いたプログラムを機能単位で異なるモジュールに分離できることを意味する。
クラス単位の情報隠蔽機構しかない場合に比べて、 MixJuice を用いることによって情報隠蔽の精度が向上する。「情報隠蔽の精度が向上」とは2つのことを意味する。1つはある名前を参照することができるスコープのサイズが減少するということ、もう1つは、ソースコード中のある地点から参照可能な名前の数が減少する、ということである。前者は、ある名前の定義を変更した時に、その変更が影響を及ぼし得る範囲を小さくすることを意味する。後者は、名前の衝突の可能性を減らすことを意味し、それにより簡潔で分かりやすい名前を用いやすくなる。 Java のように package や nested class の機構があれば、 MixJuice でなくても改善できる項目も、このカタログに載せている。
ダウンキャストの必要があったものが、不要になる。これは、 GoF パターンではない「別解」によって可能になる。
クラスの数が減少し、クラスモデルが単純化する。これは、 GoF パターンではない「別解」によって可能になる。これにより、プログラムの実行時のイメージを理解やすくなる。1つのクラスの定義が複数のモジュールに分割される場合があるので、必ずしもソースコードが単純化するとは限らない。
デザインパターンの改善策において使用される、 MixJuice のプログラミング技法には次のようなものがある。
ここで、MixJuice 以外にも同様な技法を使える言語がある。たとえば、CLOS ではメソッド追加が可能である。そのような言語では MixJuice と同様なデザインパターンの改善が行なえることがある。
| 技法 | AspectJ | CLOS | Ruby |
| メソッド拡張 | around advice | alias/def | |
| スーパーインターフェース追加 | declare parents | defmethod | include |
| フィールド追加 | introduction | 代入 | |
| メソッド追加 | defmethod | class が実行文 | |
| アブストラクトメソッド追加 | 不要/メソッド追加と同様 | ||
| 名前空間分離 | aspect | package | |
| 仕様モジュールと実装モジュールの分離 | |||
| 実装モジュール選択 | aspect選択 | require 切替え | |
Aspect-Oriented Design Pattern Implementations - Language-dependence of Design Patterns
AspectJ による GoF デザインパターンの実装
不適切な点などがありましたら、mj-language ML または田中哲 <akr@m17n.org> まで連絡して下さい。