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

CLとデザインパターン - Factory Method

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

今回はFactory Methodパターンです。

Template Methodに良く似たパターンというか、インスタンス生成をTemplate Method化したようなパターンです。

Template Method内でインスタンスの生成する場合に、インスタンスの種類を決め打ちにしたくない場合に使えたりするようです。

ということで動作は理解できたのですが、上手い表現が思い付かず、例のための例という感じになってしまいました。

  1. なんらかの種類の容器を作成して、
  2. なんらかの内容で埋めて、
  3. なんらかの方法で要素を表示

というテンプレを作って、テンプレに沿って2種類作ってみています。

上記の「なんらかの種類のシーケンスを作成して、」のところが、Factory Methodに当たる部分です。

(defclass template () ())

;; テンプレ
(defgeneric template (class)
  (:method ((class template))
    (let ((seq (make-container class)))
      (fill-container class seq)
      (print-elements class seq))))

(defgeneric make-container (class))
(defgeneric fill-container (class seq))
(defgeneric print-elements (class seq))

;; その1
(defclass concrete-1 (template) ())

(defmethod make-container ((type concrete-1))
  (make-list 10))

(defmethod fill-container ((class concrete-1) seq)
  (mapl (lambda (x) (setf (car x) (random 10)))
        seq)
  seq)

(defmethod print-elements ((class concrete-1) seq)
  (dolist (e seq)
    (princ e))
  (terpri))

;; その2
(defclass concrete-2 (template) ())

(defmethod make-container ((type concrete-2))
  (make-array 10))

(defmethod fill-container ((class concrete-2) seq)
  (map-into seq (lambda (x) (declare (ignore x)) (gensym))
            seq))

(defmethod print-elements ((class concrete-2) seq)
  (map nil #'princ seq)
  (terpri))

;; その1 実行例
(template (make-instance 'concrete-1))
;-> 1563867922
;=> nil

;; その2 実行例
(template (make-instance 'concrete-2))
;-> G2637G2638G2639G2640G2641G2642G2643G2644G2645G2646
;=> nil