我可以在Scheme中实现这样的Singleton Design Pattern吗?

时间:2014-07-31 10:03:42

标签: design-patterns scheme

我对设计模式知之甚少,今天我学会了Singleton设计模式,所以我尝试了 像这样在

中实现它
(define nil '())
(define Singleton
  (let ((instance nil))
    (lambda ()
      (if (null? instance)
          (let ((a 0))
            (define (dispatch msg)
              (cond ((eq? msg 'get)
                     (lambda () a))
                    ((eq? msg 'set)
                     (lambda (v) 
                       (begin (set! a v)
                              'ok)))))
              (set! instance dispatch)))
      instance)))
(define a (Singleton))
(define b (Singleton))
(eq? a b);;#t
((a 'set) 3)
((b 'get));;3

是我对这种设计模式的理解和实现吗?

1 个答案:

答案 0 :(得分:6)

您的实施是正确的,因为(eq? a b)#t

我会简化它(尽管这不是Code Review),如下所示:

  1. 如果是第一个电话,则无需拥有标志;只需定义一次调度程序并不断返回对它的引用
  2. 无需定义nil'()即可
  3. 我个人更喜欢使用(a 'set 3)而不是((a 'set) 3)
  4. 在这种情况下,使用case代替cond
  5. 更清晰

    所以

    (define Singleton
      (let ((a 0))                     ; instance variables
        (define (get) a)
        (define (set v) (set! a v) 'ok)
        (define (dispatch msg . args)  ; dispatcher procedure
          (case msg
            ((get) (apply get args))
            ((set) (apply set args))
            (else  (error "unknown message"))))
        (lambda () dispatch)))         ; return dispatch procedure
    

    然后

    (define a (Singleton))
    (define b (Singleton))
    (eq? a b)    ;;  #t
    (a 'set 3)   ;; 'ok
    (b 'get)     ;;   3