スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

F#によるデザインパターン入門 ファクトリー パターン(1)

次のようなシナリオを考えます。
「ある特定のメソッド群をもったクラス(そのようなクラスは複数あるとします。例えば同じインターフェイスを実装したクラスがそうです)のインスタンスを生成して、そのインスタンスとメソッド群を用いて何らかの処理をする。(メソッド群を用いての処理は、どのクラスのインスタンスであろうと同一とします。)」
 
特定のメソッドを持っているという点については、複数のクラスは同じ派生元を持っているという形か、同一のインターフェイスを実装しているという形で表現できます。
 
「インスタンスを生成して、そのインスタンスとメソッド群を用いて何らかの同一の処理をする」という部分はどのように実現すればよいでしょうか?
 
例えばmethodAとmethodBをもつ同じクラスから派生したDerive1クラスとDerive2クラスがあるとします。
「Derive1クラスのインスタンスderive1を生成してmethodAとmethodBを実行させるという処理」と
「Derive2クラスのインスタンスderive2を生成してmethodAとmethodBを実行させるという処理」はそれぞれ
 
derive1 = new Derive1() //#1
derive1.method1()
derive1.method2()
 

 
derive2 = new Derive2() //#2
derive2.method1()
derive2.method2()
 
というようになります。これをまとめることはできないでしょうか?
答えはテンプレートパターンです。この場合、インスタンス生成の部分を派生クラスにまかせて、一連の処理は基底(派生元)クラスで定義します。
 
ではコード化してみます。
 
> [<AbstractClass>]
type BaseBehavior () =
    abstract member method1 : unit -> unit
    abstract member method2 : unit -> unit
 
type Derive1 () =
    inherit BaseBehavior() with //inherit BaseBehavior withとも書ける
        override  this.method1 () =
          printfn "Derive1クラスのインスタンスとしてのmethod1の実行"
        override this.method2 () =  
          printfn "Derive1クラスのインスタンスとしてのmethod2の実行"
 
type Derive2 () =
    inherit BaseBehavior() with //inherit BaseBehavior withとも書ける
        override  this.method1 () =
          printfn "Derive2クラスのインスタンスとしてのmethod1の実行"
        override this.method2 () =  
          printfn "Derive2クラスのインスタンスとしてのmethod2の実行"
 
 
[<AbstractClass>]
type BaseCreateAndManupilator () = 
//Create(作成) manupilate(操る)だが
//実際にどのクラスのインスタンスを作成するかは派生先クラスにおまかせ  
     abstract member create : unit -> BaseBehavior
     abstract member manupilate : unit -> unit
                default this.manupilate ()  =
                            let t = this.create()//この生成は派生クラスが担当
                            t.method1()
                            t.method2()
                            t.method1()
                     
 
 
type Derive1CreateAndManupilator () =
//createはするが、manupilateは派生元クラスにおまかせ
    inherit BaseCreateAndManupilator() with
        override this.create () =
            (new Derive1()) :> BaseBehavior
 
type Derive2CreateAndManupilator () =
//createはするが、manupilateは派生元クラスにおまかせ
    inherit BaseCreateAndManupilator() with
        override this.create () =
            (new Derive2()) :> BaseBehavior
 
//////////////////////////////////////////////////////////////////////
;;
 
type BaseBehavior =
  class
    new : unit -> BaseBehavior
    abstract member method1 : unit -> unit
    abstract member method2 : unit -> unit
  end
type Derive1 =
  class
    inherit BaseBehavior
    new : unit -> Derive1
    override method1 : unit -> unit
    override method2 : unit -> unit
  end
type Derive2 =
  class
    inherit BaseBehavior
    new : unit -> Derive2
    override method1 : unit -> unit
    override method2 : unit -> unit
  end
type BaseCreateAndManupilator =
  class
    new : unit -> BaseCreateAndManupilator
    abstract member create : unit -> BaseBehavior
    abstract member manupilate : unit -> unit
    override manupilate : unit -> unit
  end
type Derive1CreateAndManupilator =
  class
    inherit BaseCreateAndManupilator
    new : unit -> Derive1CreateAndManupilator
    override create : unit -> BaseBehavior
  end
type Derive2CreateAndManupilator =
  class
    inherit BaseCreateAndManupilator
    new : unit -> Derive2CreateAndManupilator
    override create : unit -> BaseBehavior
  end
 
では使ってみます。
 
> let d1cm = new Derive1CreateAndManupilator ();;
val d1cm : Derive1CreateAndManupilator
 
> d1cm.manupilate();;
Derive1クラスのインスタンスとしてのmethod1の実行
Derive1クラスのインスタンスとしてのmethod2の実行
Derive1クラスのインスタンスとしてのmethod1の実行
val it : unit = ()
 
> let d2cm = new Derive2CreateAndManupilator ();;
val d2cm : Derive2CreateAndManupilator
 
> d2cm.manupilate();;
Derive2クラスのインスタンスとしてのmethod1の実行
Derive2クラスのインスタンスとしてのmethod2の実行
Derive2クラスのインスタンスとしてのmethod1の実行
val it : unit = ()
 
一般的には上の
 BaseBehaviorをProduct(生成されて利用されるオブジェクトの基底クラス)
 Derive1,Derive2をConcreteProduct(具体的なProduct(生成物))
 BaseCreateAndManupilatorをCreator(Productを生成して利用するオブジェクトの基底クラス)
 Derive1CreateAndManupilator,Derive2CreateAndManupilatorをConcreteCreator(具体的なCreator(製造者))といいます。
またProductを生成するメソッドをfactory methodと呼ぶ場合もあるようです。(上の例ではcreateがそれにあたります。)
スポンサーサイト

テーマ : プログラミング
ジャンル : コンピュータ

コメントの投稿

非公開コメント

ざっと見ただけですが、

>derive2 = new Derive1() //#2
って
derive2 = new Derive2() //#2
では?

No title

すみません。その通りです。訂正しました。
プロフィール

T GYOUTEN

Author:T GYOUTEN
F#と英単語とフリーソフトと読書に興味があります。
ホームページでフリーソフトも公開しています。どぞ御贔屓に。

最新記事
最新コメント
最新トラックバック
月別アーカイブ
カテゴリ
フリーエリア
フリーエリア
blogram投票ボタン
検索フォーム
RSSリンクの表示
リンク
ブロとも申請フォーム

この人とブロともになる

QRコード
QRコード
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。