Hatena::Groupcadr

わだばLisperになる このページをアンテナに追加 RSSフィード

2004 | 12 |
2005 | 01 | 02 | 07 | 10 | 11 |
2006 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2007 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2008 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2009 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2010 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2011 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 11 |

2008-12-11

CLとデザインパターン - Bridge

| 23:44 | CLとデザインパターン - Bridge - わだばLisperになる を含むブックマーク はてなブックマーク - CLとデザインパターン - Bridge - わだばLisperになる

今回は、Bridgeパターンです。

機能と実装を分けるためのパターンとのことですが、CLOSのような総称関数ベースのOOPだとBridgeが解決しようとしている問題にどうアプローチするものなのかが良く分かりませんでした。

問題は何点か考えられて

  1. クラスにメソッドが属してないので、そもそも橋渡ししなくても外から使える。
  2. マルチメソッドなので引数に条件を指定すれば、色々な条件でディスパッチできる。つまり「機能」と「実装」それぞれでディスパッチできる。
  3. 総称関数ベースのOOPと委譲の関係がいまいち自分が理解できていない(総称関数ベースのOOPでは「委譲」という言葉自体あまり聞かない気がします)

等々なので今回はいつにも増してまるで間違ったことを書いてる可能性が高いのですが、とりあえず書いてみました。

実装側は、fib-implを作成して、それを継承したfib-tailと、fib-recurを作成し、それぞれにメソッドを付けています。

機能付加の側では、fib/timerクラスを作成し、メソッドは付加機能で囲った後にスーパークラスのメソッドを呼んでいます。

しかし、これだと、枝葉のクラスをそれぞれ継承しないといけないので面倒なです。

やはり引数を2つに増して多重ディスパッチが良いのでしょうか。良い解決策をご存知の方は是非教えて下さい!

(defclass fib-impl () ())
(defclass fib-tail (fib-impl) ())
(defclass fib-recur (fib-impl) ())

(defgeneric fib (class n))

(defmethod fib ((class fib-tail) n)
  (labels ((*fib (n a1 a2)
             (if (< n 2)
                 a1
                 (*fib (1- n) 
                       (+ a1 a2)
                       a1))))
    (*fib n 1 0)))

(defmethod fib ((class fib-recur) n)
  (labels ((*fib (n)
             (if (< n 2)
                 n
                 (+ (*fib (1- n))
                    (*fib (- n 2))))))
    (*fib n)))

(defclass fib/timer () ())
(defclass fib-recur/timer (fib/timer fib-recur) ())
(defclass fib-tail/timer (fib/timer fib-tail) ())

(defmethod fib ((class fib/timer) n)
  (time (call-next-method)))

;;; 実行

;; 普通
(fib (make-instance 'fib-tail)
     40)
;=> 102334155

;; 時間計測つき
(fib (make-instance 'fib-recur/timer)
     40)
;-> 
;Evaluation took:
;  11.768363 seconds of real time
;  11.755267 seconds of thread run time
;  11.815329 seconds of process run time
;  11.772736 seconds of user run time
;  0.004 seconds of system run time
;  0 page faults
;  0 bytes consed by this thread and
;  73,728 total bytes consed.
;=> 102334155

ゲスト



トラックバック - http://cadr.g.hatena.ne.jp/g000001/20081211