Decorator Pattern
From REALbasicWiki
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
[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

