GoFのデザインパターン(Design Pattern)の一つ、アブストラクトファクトリ(Abstract Factory)をRubyのサンプルコードで紹介します。
アブストラクトファクトリは、矛盾のないオブジェクトの生成を行うためのパターンです。
ソースコードを使ったAbstract Factoryの説明
Abstract Factoryをソースコードを使って説明します。
ここでは次のような池をサンプルとして取り上げます。
* 動物を表すクラス: * アヒルを表すDuckクラスは、食事(eat)メソッドを持っている * カエルを表すFrogクラスは、食事(eat)メソッドを持っている * 植物を表すクラス: * 藻を表すAlgaeクラスは、成長(grow)メソッドを持っている * スイレンを表すWaterLilyクラスは、成長(grow)メソッドを持っている 池の生態系を生成するクラス: * コンストラクタで動物と植物を定義する * 動物、植物のオブジェクトを返すメソッドを持っている * 池の環境(動物と植物の組み合わせ)は次の2種類のみが許されている * DuckとWaterLily * FrogとAlgae
上を満たすコードを書いていきます。
まず、アヒル(Duckクラス)とカエル(Frogクラス)は次のようになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
|
一方、藻(Algaeクラス)とスイレン(WaterLilyクラス)のは次のようになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
|
次に池を作成する前に、「池の環境の制約」について考えます。
* 池の環境(動物と植物の組み合わせ)は2種類のみが許されている * アヒル(Duckクラス)とスイレン(WaterLilyクラス) * カエル(Frogクラス)と藻(Algaeクラス)
この池の環境の制約を守ること、言い換えると矛盾のないオブジェクトの組み合わせを作るのが「Abstract Factoryパターン」です。 今回はこの矛盾のない環境の作成を次の2つのクラスに担当してもらいます。
* カエル(Frog)と藻(Algae)の生成を行う => FrogAndAlgaeFactory * アヒル(Duck)とスイレン(WaterLily)の生成を行う => DuckAndWaterLilyFactory
さらに上の2つのクラスのベースとなる池の生態系を表すクラスOrganismFactory
を作り、上記のクラスが継承するようにします。
ということで、ソースコードはこちら。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
|
上のプログラムを実行した結果を載せておきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
|
矛盾のない組み合わせて、オブジェクトを生成できた事がわかります。
このサンプルソースはGitHubにも置いています。
Abstract Factoryの構成
Abstract Factoryは次の3つの要素で構成されています。
AbstractFactory: ConcreteFactoryの共通部分の処理を行う(この例ではPond) ConcreteFactory: 実際にオブジェクトの生成を行う (この例ではFrogAndAlgaeFactoryとDuckAndWaterLilyFactoryクラス) Product: ConcreteFactoryによって生成される側のオブジェクト (この例では、Duck,Frog, WaterLily, algaeクラス)
アブストラクトファクトリのメリットは?
* 関連し合うオブジェクトの集まりを生成することができる * 整合性が必要となるオブジェクト群を誤りなしに生成できる
Special Thanks
@chinmoさんにアブストラクトファクトリについてコード付きのコメントを頂きました。深謝です!
ma2さんにブログ上に記述したコードがOrganismFactoryを継承していない部分のミスをご指摘頂きました。ミスすんませんでした&ma2さん、本当に有難うございます!
Amazon.co.jp: Rubyによるデザインパターン: Russ Olsen, ラス・オルセン, 小林 健一, 菅野 裕, 吉野 雅人, 山岸 夢人, 小島 努: 本
変更来歴
12/12/10 23:10 11回FactoryをFactoryMethodとAbstractFactoryに分割
12/12/11 00:00 書籍へのリンクをAmazon アフィリエイトに変更
13/06/21 19:10 Ruby2.0.0対応、読みづらい部分を修正
13/08/15 13:15 モデリング・説明が不適切だったため、修正
14/01/18 09:35 継承の記述が抜けていたため、修正