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-23

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

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

今回はProxyパターンです。

内部的に処理が違うものをプロキシを立てることによってユーザは意識せずに使えるようにするパターンの様です。

毎度例がfibばかりなのですが、Nが30より大きくなると高速版に切り換えるようなものを作成してみました。

例のための例という感じですが…。

とりあえず、今回で色々悩みつつ実習してきた「CLとデザインパターン」今回でGoFの23パターンを制覇できました。

感想としては、Norvig氏のDesign Patterns in Dynamic Programmingでも述べられていますが、生成に関しては、ファースト・クラスの型(クラス)、振舞いに関しては、ファースト・クラスの関数がある場合、実行したいことが分かっているならクラスの構成を色々工夫しなくてもストレートに表現できるかなと思いました。

また、ウェブで参照できる入門的なテキストは殆どJavaやC++なのでこれらの例を翻訳して考えるのに割と苦戦しました。

上記のNorvig氏のプレゼンでは、動的言語ならではのパターンというものが提案されているので、今後はこれをさらって行こうかと思います。

(defclass subject () ())

(defclass proxy (subject) ())
(defclass real-subject (subject) ())

(defgeneric fib (class n))
;; Proxy(基本的に低速 N > 30 で高速版に処理を投げる)
(defmethod fib ((class proxy) n)
  (let ((class 
         (if (< 30 n)
             (change-class class 'real-subject)
             class)))
    (if (< n 2)
        n
        (+ (fib class (1- n))
           (fib class (- n 2))))))
;; 高速版
(defmethod fib ((class real-subject) n)
  (labels ((*fib (n a1 a2)
             (if (< n 2)
                 a1
                 (*fib (1- n) 
                       (+ a1 a2)
                       a1))))
    (*fib n 1 0)))

;; 試してみる
(time (fib (make-instance 'proxy)
     100))
;   Evaluation took:
;     0.002 seconds of real time
;     0.000000 seconds of total run time (0.000000 user, 0.000000 system)
;     0.00% CPU
;     6 forms interpreted
;     3,022,236 processor cycles
;     31,856 bytes consed
;=> 354224848179261915075