Skip to content

Instantly share code, notes, and snippets.

@helmutkian
Created August 1, 2012 00:31
Show Gist options
  • Save helmutkian/3222000 to your computer and use it in GitHub Desktop.
Save helmutkian/3222000 to your computer and use it in GitHub Desktop.
CLOS Mixin pattern

Mixin classes in CLOS are very similar to abstract base classes or interfaces in other object-oriented languages. Like interfaces in Java, they circumvent many of the issues associated with multiple-inheritence.

Imagine a senario in which one is tasked with building a platform-independent GUI framework. At the top of the widgit hierarchy sits a mixin WIDGIT-MIXIN:

(defclass widgit-mixin () ())

WIDGIT-MIXIN allows all of its subclasses access to the base method of the DISPLAY-WIDGIT generic function:

(defgeneric display-widgit (widgit)
  (:method ((widgit widgit-mixin))
    (print 'widgit)))

All the essential widgit base classes would then inherit from WIDGIT-MIXIN, for example BUTTON:

(defclass button (widgit-mixin)
  ((clicked
    :reader clicked-p
    :initform nil)))
    
(defmethod display-widgit ((widgit button))
  (print 'button)
  (call-next-method))

We can also define the platform type of the widgits as mixin classes:

(defclass windows-mixin () ())

(defclass cocoa-mixin () ())

Now these base classes can extend the DISPLAY-WIDGIT generic function with platform-specific behavior

(defmethod display-widgit ((widgit windows-mixin))
  (print 'windows)
  (call-next-method))

(defmethod display-widgit ((widgit cocoa-mixin))
  (print 'cocoa)
  (call-next-method))

And then "mixed into" the widgit base classes:

(defclass windows-button (button windows-mixin) ())

(defclass cocoa-button (button cocoa-mixin) ())

Now we can call DISPLAY-WIDGIT on different buttons and get platform-specific behavior

(display-widgit (make-instance 'windows-button))

> BUTTON
> WINDOWS
> WIDGIT

(display-widgit (make-instance 'cocoa-button))

> BUTTON
> COCOA
> WIDGIT
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment