Decorator Pattern

From REALbasicWiki

Jump to: navigation, search

Contents

[edit] Intention

The Decorator Pattern allows you to attach additional responsibilities to an object dynamically. Thus it provides a flexible alternative to subclassing for extending the functionality.

[edit] Class-Diagram

Image:Decorator.png


[edit] Example

Imagine you have a class that has a list of names stored in an array. By using the decorator you are able to dynamically add filters or a sorting to this list. Although this could be done easier with the normal array-functions in REALbasic it demonstrates the capabilities of the Decorator Pattern

We are starting with the component-class AbstractList - this is an abstract class (note the protected constructor). Every concrete list as well as the decorator are inheriting the properties and methods of this class.


Class AbstractList

Protected Sub Constructor()
End Sub

Function getNames() As string()
return names
End Function

Protected names() As string

End Class

The second class used is the Decorator - here called ListDecorator



Class ListDecorator
Inherits AbstractList

Private Sub Constructor()
// Calling the overridden superclass constructor.
Super.Constructor
End Sub

Function getNames() As string()
End Function

End Class


Now we are adding a concrete component: the namelist. It generates a list of names in its constructor and returns them in its getNams()-method.


Class NameList
Inherits AbstractList

Function Untitled() As Boolean
Return True
End Function

Sub Constructor()
names.Append "Judy"
names.Append "Max"
names.Append "Audrey"
names.Append "Thelma"
names.Append "Louise"
names.Append "Herbert"
names.Append "Frank"
names.Append "Adam"
names.Append "John"
names.Append "Monica"
names.Append "Tom"
names.Append "Luke"
names.Append "Hillary"
names.Append "Fred"
names.Append "Ann"
End Sub

Function getNames() As string()
return names
End Function

Private names() As String
End Class

Lets add some decorator-functionality - the first decorator sorts our list. As you can see the concrete decorator has an AbstractList as property.


Class OrderedListDecorator
Inherits ListDecorator

Sub Constructor(l as abstractList)
list = l
End Sub

Function getNames() As string()
dim l() as string
l = list.getNames
l.Sort
return l
End Function

Private list As AbstractList

End Class


The second decorator filters some of the names.


Class ListFilterDecorator
Inherits ListDecorator

Sub Constructor(l as abstractList)
list = l
End Sub

Function getNames() As string()
dim l() as string
dim f() as string
l = list.getNames
//get only names that start with an A, H or T
for each n as string in l
if left(n, 1) = "A" or left(n,1) = "H" or left(n,1) = "T" then
f.Append n
end if
next
return f
End Function

Private list As AbstractList
End Class

Lets try it out and see what happens.


dim names as AbstractList
dim s as string
names = new NameList
s = "The names in the original list are" + EndOfLine + EndOfLine
for each name as string in names.getNames
s = s + " " + name + EndOfLine
next
Msgbox s

s = "The namelist with the OrderedListDecorator: " + EndOfLine + EndOfLine
names = new OrderedListDecorator(names)
for each name as string in names.getNames
s = s + " " + name + EndOfLine
next
Msgbox s
s = "The namelist with OrderedListDecorator and ListFilterDecorator: " + EndOfLine
+ EndOfLine
names = new ListFilterDecorator(names)
for each name as string in names.getNames
s = s + " " + name + EndOfLine
next
MsgBox s

The interesting thing is that we can use just one variable for all the decorators and concrete classes as all of them inherit from AbstractList.

[edit] External resources

http://en.wikipedia.org/wiki/Decorator_pattern

For more information about the Unified Modeling Language that was used to describe the classes please visit these links:

http://www.holub.com/goodies/uml/index.html

http://www.developer.com/design/article.php/2206791

http://en.wikipedia.org/wiki/Unified_Modeling_Language

Personal tools
related