The Artima Developer Community
Sponsored Link

Articles Forum
Scala's Stackable Trait Pattern

6 replies on 1 page. Most recent reply: Sep 26, 2011 9:35 AM by Christian Schlichtherle

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 6 replies on 1 page
Bill Venners

Posts: 2284
Nickname: bv
Registered: Jan, 2002

Scala's Stackable Trait Pattern Posted: Sep 29, 2009 10:00 PM
Reply to this message Reply
Advertisement
This article describes a Scala design pattern in which traits provide stackable modifications to underlying core classes or traits:

http://www.artima.com/scalazine/articles/stackable_trait_pattern.html

What do you think of the Stackable Trait pattern?


John Zabroski

Posts: 272
Nickname: zbo
Registered: Jan, 2007

Re: Scala's Stackable Trait Pattern Posted: Sep 30, 2009 11:18 AM
Reply to this message Reply
> This pattern is similar in structure to the decorator
> pattern, except it involves decoration for the purpose of
> class composition instead of object composition. Stackable
> traits decorate the core traits at compile time, similar to
> the way decorator objects modify core objects at run time
> in the decorator pattern.

This is somewhat incorrect. Role analysis is actually meant to unify object-based and class-based methods for decribing patterns of interactions between objects.

This idea just hasn't been mathematically formalized (that I know of). The closest formalization was done by one of Trygve's Ph.D. students in the '90s.

Bill Venners

Posts: 2284
Nickname: bv
Registered: Jan, 2002

Re: Scala's Stackable Trait Pattern Posted: Sep 30, 2009 11:53 AM
Reply to this message Reply
Hi John,

> > class composition instead of object composition.
> Stackable
> > traits decorate the core traits at compile time, similar
> to
> > the way decorator objects modify core objects at run
> time
> > in the decorator pattern.
>
> This is somewhat incorrect. Role analysis is actually
> meant to unify object-based and class-based methods for
> decribing patterns of interactions between objects.
>
Can you elaborate? I'm not sure what your saying is somewhat incorrect.

My goal was to preempt folks from concluding that this is just decorator, because the GoF book makes it clear that the intent of decorator is (quoting the book) to:

Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.

Whereas this is an example of "subclassing to extend functionality" really, and it isn't dynamic. What's new is Scala's notion of delayed binding of the meaning of super, abstract override, and linearization, which didn't exist when the GoF book was written. The decorator pattern looks in Scala pretty much the same as it does in Java. So even though this has a similar structure to decorator, is a similar concept, it really is different from decorator, because it is a static, compile-time thing.

Howard Lovatt

Posts: 321
Nickname: hlovatt
Registered: Mar, 2003

Re: Scala's Stackable Trait Pattern Posted: Sep 30, 2009 11:45 PM
Reply to this message Reply
Bill,

Nicely written article. The Trait form is a nice alternative to decorators, I guess it has the disadvantage that if people do a lot of:

val queue = new BaseIntQueue with Filter


Then you will create a lot of classes unnecessarily. The decorator equivalent doesn't create the extra classes.

One thing that I don't like about either the decorator or trait version is the order dependence, it is far to easy to write (or edit in when maintaining a program):

val queue = new BaseIntQueue with Filter with Double


When you intended:

val queue = new BaseIntQueue with Double with Filter

John Zabroski

Posts: 272
Nickname: zbo
Registered: Jan, 2007

Re: Scala's Stackable Trait Pattern Posted: Oct 7, 2009 8:07 AM
Reply to this message Reply
> Hi John,
>
> > > class composition instead of object composition.
> > Stackable
> > > traits decorate the core traits at compile time,
> similar
> > to
> > > the way decorator objects modify core objects at run
> > time
> > > in the decorator pattern.
> >
> > This is somewhat incorrect. Role analysis is actually
> > meant to unify object-based and class-based methods for
> > decribing patterns of interactions between objects.
> >
> Can you elaborate? I'm not sure what your saying is
> somewhat incorrect.
>
> My goal was to preempt folks from concluding that this is
> just decorator, because the GoF book makes it clear that
> the intent of decorator is (quoting the book) to:
>
> Attach additional responsibilities to an object
> dynamically. Decorators provide a flexible alternative to
> subclassing for extending functionality.
>
> Whereas this is an example of "subclassing to extend
> functionality" really, and it isn't dynamic. What's new is
> Scala's notion of delayed binding of the meaning of super,
> abstract override, and linearization, which didn't exist
> when the GoF book was written. The decorator pattern looks
> in Scala pretty much the same as it does in Java. So even
> though this has a similar structure to decorator, is a
> similar concept, it really is different from decorator,
> because it is a static, compile-time thing.

Hi Bill,

I am referring to the symmetry between the GoF Decorator pattern GoF State pattern (which Trygve essentially wrote an entire book about, as well as an object-oriented software method for). The GoF State pattern in the book is described as a behavioral pattern, but its more structural in nature: the focus, as in Trygve's OOram (his software method), is about defining the context in which a behavior is applicable. Within that context, you are modeling the structure of object interactions. GoF sees it as a behavioral pattern mainly because their implementation is synchronous with its environment; each role knows where to migrate the token to next. In an asynchronous environment, the pattern is purely structural in nature because the objects communicate by message-passing and state transitions are triggered by signals.

Traits allow you to more easily specify contracts for what sort of compositions an object allows.

As I said, role analysis is actually meant to unify object-based and class-based methods for describing patterns of interactions between objects (this is almost a word for word quote from Trygve). Most of the examples in Trygve's book Working with Objects is dedicated to this idea. The only unfortunate thing is Trygve doesn't really discuss "dependency injection" in conjunction with that big picture idea, so the reader likely does not see the "big idea".

> Whereas this is an example of "subclassing to extend
> functionality" really,

As you subclass to extend functionality, you are changing the problem domain. This is mainly due to the fact that in your example you are not using scala's features to encapsulate some problem domain but rather demonstrate some wiring pattern. The wiring pattern is a code reuse facility with excellent type safety, but it is a clumsy way to package a problem domain.

> and it isn't dynamic.

To wit, I would argue asynchronous message-passing is dynamic, whereas hardwiring sequences of collaborations is static.

The hard problem to solve in OO is not structural. OO applications are filled with structural features. The hard part is to specify at the language level your object interactions (use cases).

John Zabroski

Posts: 272
Nickname: zbo
Registered: Jan, 2007

Re: Scala's Stackable Trait Pattern Posted: Oct 12, 2009 8:34 AM
Reply to this message Reply
Bill,

did that make any sense?

Basically, a GoF decorator pattern allows you to dynamically assign responsibilities to an object or class, whereas a GoF State pattern simply associates roles within a context to a behavior responsibility. Looking at it this way, the only difference between the two patterns is a concrete notion of "when".

In Python, a "decorator" actually is determined at "compile-time" ("when" the AST is converted into a byte code stream) and so the blurriness of these two patterns is perhaps best seen in this language. One huge difference is syntax and how things are composed at "code-write-time". However, ultimately, at run-time, the code is representing some problem domain.

Just as a role does not necessarily need to know what the next role transition will be, so too a decorator does not need to know what other decorators are applied. To each decorator, it is the same object. And from the point-of-view of the decorated object, these decorations do not even exist. Likewise, in an State pattern, the object's chief knowledge responsibility is the context (current role) with regards to its collaboration with other objects -- the object shouldn't care about details such as "how" a message is processed in a role.

Christian Schlichtherle

Posts: 1
Nickname: 78559
Registered: Sep, 2011

Re: Scala's Stackable Trait Pattern Posted: Sep 26, 2011 9:35 AM
Reply to this message Reply
I wonder why it is required to say


trait Doubling extends IntQueue {
abstract override def put(x: Int) { super.put(2 * x) }
}


instead of just


trait Doubling extends IntQueue {
override def put(x: Int) { super.put(2 * x) }
}


The first syntax looks really odd, because you are actually defining a method, not just declaring it. Also, Scala is advertised to be concise, and this looks just superfluous.

Flat View: This topic has 6 replies on 1 page
Topic: "Pure Virtual Function Called": An Explanation Previous Topic   Next Topic Topic: The Next Big JVM Language

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use