スポンサーサイト

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

F#によるデザインパターン入門 Proxy パターン(2)

前回は防御Proxyを紹介しました。今回はまずはリモートProxyの概要のみを紹介します。
これは前回のたとえ話でとらえると、政治家が、どっかに雲隠れしてしまい、連絡手段は秘書の電話のみという感じです。政治家に用事がある時は、秘書に用件を伝えて、秘書はどっかにいる政治家に連絡をとり用件を処理します。
リモートというのは、「離れた」という意味合いで、実際には政治家は別のサーバ上のウェブサービス等であったりします。秘書がウェブサービスとの連絡役をつとめるという仕組みです。
秘書(Proxy)は、用件をネットワークを用いて送信し、政治家(外部サーバのサービス等)からの返答を受信したらそれを、用件の依頼者に伝えます。
サブジェクト(政治家)が用件処理に専心し、秘書(Proxy)がデータを運ぶことに専心するという仕組みです。
 
次に仮想 Proxy(virtual proxy)を紹介します。
これは本当に必要になるまで政治家は登場せず、秘書が代理をつとめ、どうしても必要となったときに、政治家オブジェクト(サブジェクト)が登場して(生成されて)用件を処理するというパターンです。
基本的にサブジェクトの生成に時間がかかる場合に用いられます。(例えばプログラムの最初に政治家が大量に必要になる場合、ここですべてを生成しているとプログラムがなかなか始まらなくなります。そこで秘書群を生成し(もちろんこれらの生成は軽くないと意味がありません。)、政治家が必要になるタイミングで、政治家を生成していくという仕組みです。
 
ではサンプルを。
 
まずはインターフェイスです。
 
> type IWhatToDo  =
    abstract do_something1 : unit -> unit;;
 
type IWhatToDo =
  interface
    abstract member do_something1 : unit -> unit
  end
 
次にRealPlayer(政治家、サブジェクト)です。
 
> type MyRealPlayer () =
    do printfn "実際には時間かけて生成してます。" //コンストラクタで実行される部分
    interface IWhatToDo with
      member this.do_something1 ()=
                printfn "RealPlayer do something1";;
 
type MyRealPlayer =
  class
    interface IWhatToDo
    new : unit -> MyRealPlayer
  end
 
最後にProxy(秘書、代理、プロキシー)です。
 
> type MyProxyPlayer () =
    let mutable rp : MyRealPlayer option = None
    //RealPlayerが生成されてなければ生成し、参照を保持させるunit->unit型の関数
    let init () =
        match rp with
        | None -> rp <- Some(new MyRealPlayer())
        | _    -> ()
    
    interface IWhatToDo with
      member this.do_something1 () =
                init()
                (rp.Value:>IWhatToDo).do_something1 ();;
 
type MyProxyPlayer =
  class
    interface IWhatToDo
    new : unit -> MyProxyPlayer
  end
 
前回のと異なる点はサブジェクトの生成がproxy任せになり、proxyのメソッドが呼ばれた時点で、サブジェクトの生成ができているかどうかをチェックし、できてなければその時点で生成を行う部分です。
 
では使ってみます。
 
> let myProxyP1 = new MyProxyPlayer();;
 
val myProxyP1 : MyProxyPlayer
 
この時点では、サブジェクトの生成はなされていません。
次のdo_something1を呼び出した時点でサブジェクトが生成されます。
 
> (myProxyP1:>IWhatToDo).do_something1();;
実際には時間かけて生成してます。
RealPlayer do something1
val it : unit = ()
 
なおMyProxyPlayerは次のように書き換えてもよいかと思います。
 
type MyProxyPlayer () =
    let mutable rp : MyRealPlayer option = None
    let getSubject () =
        match rp with
        | None -> rp <- Some(new MyRealPlayer())
        | _    -> ()
        rp.Value :> IWhatToDo
    
    
    interface IWhatToDo with
      member this.do_something1 () =
                (getSubject()).do_something1 ()
スポンサーサイト

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

コメントの投稿

非公開コメント

プロフィール

T GYOUTEN

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

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

この人とブロともになる

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