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-11-04

ContextLとデザインパターン - Template Method

| 01:19 | ContextLとデザインパターン - Template Method - わだばLisperになる を含むブックマーク はてなブックマーク - ContextLとデザインパターン - Template Method - わだばLisperになる

ContextLの概要の説明を読んで、最初にぱっと思いついたのは、デザインパターンでのTemplate Method的な動きがContextLを使えば簡単に記述できるのではないかということでした。

デザインパターンでは、クラスを利用して色々な状況の切り換えパターンが紹介されています。

ContextLでは、クラスの代りにレイヤ機能によって色々と切り換えることができるのですが、その名前の通りコンテクストを切り換えるようなパターンには応用できそうだと思いました。

ということで記念カキコ。

(defpackage :design-patterns 
  (:use :cl))

(in-package :design-patterns)

(use-package :contextl)

;; テンプレート
(define-layered-function template (string)
  (:documentation "テンプレ"))
(define-layered-method template ((string string))
  (op2 (op1 string)))

(define-layered-function op1 (string)
  (:documentation "処理その1"))
(define-layered-method op1 ((string string))
  string)

(define-layered-function op2 (string)
  (:documentation "処理その2"))
(define-layered-method op2 ((string string))
  string)

;; テンプレに従った詳細な実装 その1
(deflayer concrete)

(define-layered-method op1 :in concrete ((string string))
  (string-upcase string))

(define-layered-method op2 :in concrete ((string string))
  (format t "~A~%" string)))

;; テンプレに従った詳細な実装 その2
(deflayer concrete2)

(define-layered-method op1 :in concrete2 ((string string))
  (string-capitalize string))

(define-layered-method op2 :in concrete2 ((string string))
  (princ string)
  (terpri)))

;; テンプレに従った詳細な実装 その2を継承したその3
(deflayer concrete3 (concrete2))

(define-layered-method op2 :in concrete3 ((string string))
  (princ "**")
  (princ string)
  (princ "**")                 
  (terpri))


;;; 動作

;; Tは一番下のルートレイヤ
(with-active-layers (t)
  (template "foo bar baz"))
;=> "foo bar baz"

(with-active-layers (concrete)
  (template "foo bar baz"))
;>>> FOO BAR BAZ
(with-active-layers (concrete2)
  (template "foo bar baz"))
;>>> Foo Bar Baz

(with-active-layers (concrete3)
  (template "foo bar baz"))
;>>> **Foo Bar Baz**