スポンサーサイト

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

F#によるデザインパターン入門 ストラテジーパターン(2)

さて前回はストラテジー パターンをJava風にインターフェイスを用いた方法で紹介しましたが、今回はF#風の方法を紹介します。
ストラテジー パターンは問題解決部分を別々のオブジェクトとしてひっぱり出して上で切り替えて処理するというパターンでした。この別々のオブジェクトというのが同じインターフェイスを実装した別々クラスのインスタンスとなっていました。F#では、この別々のオブジェクトというものの代わりに、別々の関数を使えば済むだけの話になってしまいます。
 
では前回のコードと関数を使ったコードを再掲しておきます。
<前回のjava風コード>
 
type ISoloveThatProblemable =
    abstract SolveProblem : int -> int
 
type Superviser (inSolver:ISoloveThatProblemable) =
    let mutable numOfProblem = 0 //解かせる問題のnの値
    let mutable solver:ISoloveThatProblemable = inSolver    //どれを雇って解かせるか
    member this.NumOfProblem //問題設定のプロパティ 
        with get() = numOfProblem
        and set(n) = numOfProblem <- n 
    member this.Solver //どれを雇って解かせるかを設定するプロパティ
        with set(sol) = solver <- sol
    member this.Solve() = //解かせて答えを表示
            printfn "%d" (solver.SolveProblem(n))
 
 
type SmartKind() =
    interface ISoloveThatProblemable with
        member this.SolveProblem (n) =
            printfn "%d * (%d + 1) / 2 を計算して答えを返します。" n n
            n * (n + 1) / 2
 
 
type FoolKind ()=
    interface ISoloveThatProblemable with
        member this.SolveProblem (n) =
            printfn "1 + 2 + ... + %d をまともに計算して答えを返します。" n
            List.fold (+) 0 [for i in 1 .. n  -> i ]
   
 
let sk = new SmartKind()
let fk = new FoolKind()
 
監督者クラスのインスタンスを生成しておきます。(解く方は、まずはskの方を登録しておきます。)
let sv = new Superviser(sk)
 
問題のnの値を設定します。
sv.NumOfProblem <- 100
 
skに問題を解かせます。
> sv.Solve();;
100 * (100 + 1) / 2 を計算して答えを返します。
5050
val it : unit = ()
 
解答者をfkにチェンジします。
> sv.Solver <- fk;;
val it : unit = ()
 
問題を解かせます。
> sv.Solve();;
1 + 2 + ... + 100 をまともに計算して答えを返します。
5050
 
 
次は関数を使った場合をやってみます。
 
type Superviser (inSolverFunc:int->int) =
    let mutable numOfProblem = 0 //解かせる問題のnの値
    let mutable solverFunc:int->int = inSolverFunc    //どの関数を使って解くか
    member this.NumOfProblem //問題設定のプロパティ 
        with get() = numOfProblem
        and set(n) = numOfProblem <- n 
    member this.Solver //どれを雇って解かせるかを設定するプロパティ
        with set(sol) = solverFunc <- sol
    member this.Solve() = //関数を適用して答えを表示
            printfn "%d" (solverFunc numOfProblem)
 
 
let smartSolveFunc =
        (fun n ->printfn "%d * (%d + 1) / 2 を計算して答えを返します。" n n
                 n * (n + 1) / 2)
 
let foolSolveFunc =
        (fun n ->printfn "1 + 2 + ... + %d をまともに計算して答えを返します。" n
                 List.fold (+) 0 [for i in 1 .. n  -> i ])
 
監督者クラスのインスタンスを生成しておきます。(解く方は、まずはsmartSolveFuncの方を登録しておきます。)
 
> let sv = new Superviser(smartSolveFunc);;
val sv : Superviser
 
問題のnの値を設定します。
 
> sv.NumOfProblem <- 100;;
val it : unit = ()
 
skに問題を解かせます。
> sv.Solve();;
100 * (100 + 1) / 2 を計算して答えを返します。
5050
val it : unit = ()
 
解答関数をfoolSolveFuncにチェンジします。
 
> sv.Solver <- foolSolveFunc;;
val it : unit = ()
 
問題を解かせます。
 
> sv.Solve();;
1 + 2 + ... + 100 をまともに計算して答えを返します。
5050
val it : unit = ()
スポンサーサイト

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

コメントの投稿

非公開コメント

プロフィール

T GYOUTEN

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

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

この人とブロともになる

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