How to use composition in an UML diagram

10 views
Skip to first unread message

J.T.K.M.

unread,
Jan 19, 2010, 4:33:00 AM1/19/10
to UML Forum
Hello,

I am learning how to draw UML diagrams however there are still some
uncertainties about a composition relationship. Let's say I want to
design a system for managing items a shop. So I make a class shop and
shop contains zero or infinity items.

So should I use composition or aggregation? As a shop contains items,
so I would use composition. But when do I use aggregation? Can someone
give me a clear definition what aggregation actually does? And maybe
an example (maybe a software unrelated example or some code)?

(I used http://www.objectmentor.com/resources/articles/umlClassDiagrams.pdf
to learn how do draw class diagrams; I can't really see here the
difference in the examples between aggregation and composition.)

(I also googled and found the following: http://www.jguru.com/faq/view.jsp?EID=51520,
however they do not really talk about aggregation.)

Thank you for answering my question,

J.T.K.M.

H. S. Lahman

unread,
Jan 19, 2010, 6:26:25 PM1/19/10
to umlf...@googlegroups.com
Responding to J.T.K.M....

>
> I am learning how to draw UML diagrams however there are still some
> uncertainties about a composition relationship. Let's say I want to
> design a system for managing items a shop. So I make a class shop and
> shop contains zero or infinity items.
>

It's not infinity; the * multiplicity just indicates more that 1
participant is possible. In relational theory a relationship with
exactly 1 participant is special (known as a 'functional relationship').
But a relationship with more than one is different and it doesn't matter
how many more than 1 there are.

> So should I use composition or aggregation? As a shop contains items,
> so I would use composition. But when do I use aggregation? Can someone
> give me a clear definition what aggregation actually does? And maybe
> an example (maybe a software unrelated example or some code)?
>

None of above. B-)

Composition. A logical Whole/Part semantics exists between the
participants in the problem space and the disposition of the Part is
determined by the Whole. That is, in the most common situation the Part
object dies when the Whole object dies. [There are arcane situations
where Parts may be swapped from one Whole to another, in which case the
Whole transfers the disposition responsibility to the other Whole.]

Aggregation. Same as Composition but the Whole does not determine the
disposition of the Part.

In your case the Item is not a logically part of a Shop by any usual
criteria. So the relationship is a simple association rather than
Composition or Aggregation.

As it happens aggregation has no effect whatsoever on the
implementation. It exists in UML to provide symmetry with Composition
when disposition is not an issue. The Whole/Part semantics simply
documents what the developer was thinking when identifying the relationship.

Composition is in UML because Grady Booch was one of the designers of
UML and his original notation for OOA/D was sometimes called "Graphical
C++" because it reflected the C++ language very, very closely. One of
the features of C++ is that relationships can be implemented either
through a referential attribute or by directly embedding one object in
another's implementation. The Composition Association captured the
notion of an embedded object.

Since OOA/D notations are supposed to capture OO designs and OOPLs are
supposed to implement those designs, defining the OOA/D notation around
OOPL syntax is kind of like letting the tail wag the dog. One way this
is manifested is that the OOP programmer might embed one object in
another for reasons unrelated to Whole/Part semantics. Conversely, the
OOP programmer could use a referential attribute instead of embedding an
object when the Whole does determine Part disposition if referential
integrity is managed in some other way. So Composition does not directly
affect the implementation either except to announce a referential
integrity requirement.

But now that UML has an execution semantic meta model, the abstract
action languages (AALs) that describe what methods actually do will
typically have a LINK/UNLINK syntax to explicitly manage relationships
and a DELETE syntax for de-instantiating objects (which can be ignored
in garbage collection languages -- at one's peril). So the referential
intergrity requirement that Composition is supposed to capture is
redundant anyway.

Bottom line: composition and aggregation associations are anachronisms
and can safely be ignored.

--
Life is the only flaw in an otherwise perfect nonexistence
-- Schopenhauer

H. S. Lahman
H.la...@verizon.net
software blog: http://pathfinderpeople.blogs.com/hslahman/index.html


Tsun Kiet Man

unread,
Jan 20, 2010, 10:47:38 AM1/20/10
to umlf...@googlegroups.com
Ah I see, it is just a simple association. Let me get this straight, by using a classic example a student grade managing system. Let's say a student takes courses, so I would get a relation of student and courses with 1 ... * (association).
 
Is this correct?
 
Thank you for your clear answer, all the fog is gone I think ;).
 
Yours, J.T.K.M.

 
2010/1/20 H. S. Lahman <h.la...@verizon.net>
--
You received this message because you are subscribed to the Google Groups "UML Forum" group.
To post to this group, send email to umlf...@googlegroups.com.
To unsubscribe from this group, send email to umlforum+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/umlforum?hl=en.




H. S. Lahman

unread,
Jan 21, 2010, 12:31:02 PM1/21/10
to umlf...@googlegroups.com
Responding to Man...

> Ah I see, it is just a simple association. Let me get this straight,
> by using a classic example a student grade managing system. Let's say
> a student takes courses, so I would get a relation of student and
> courses with 1 ... * (association).
>
> Is this correct?

This is a somewhat different issue: multiplicity.

[Registration]
|
|
1..* | 1..*
[Student] ------------------------ [Course]
R1

The association is a simple one (as opposed to composition or
aggregation) but typically the student can take multiple courses and
there are multiple students taking a course. (Presumably a Student is
always registered for at least one course and each Course has at least
one Student.) So the association is *:* and you need an association
class, [Registration], as a placeholder to capture the more complicated
implementation that will be required for the association.

Livia Pérez

unread,
Jan 21, 2010, 7:07:02 AM1/21/10
to UML Forum
I think J.T.K.M. is thinking about objects instead classes.

Visit some online store. You can have many products, but it doesn’t
matter the kind, the size… You can have a toilet paper and a webcam.
Both are products and the class is the same, with the same attributes.

But when you draw a shopping cart, for example, you need another class
where you can list all the products code, quantity and total cost.

That’s a simple relationship where you can have 1 or more than 1 (*)
products in a shopping cart. At the same time, you can have one
product (class, not object) in many shopping carts.

I hope it helps…

Sorry for my bad English. I’m still learning.


On Jan 20, 1:47 pm, Tsun Kiet Man <temp.t...@gmail.com> wrote:
> Ah I see, it is just a simple association. Let me get this straight, by
> using a classic example a student grade managing system. Let's say a student
> takes courses, so I would get a relation of student and courses with 1 ... *
> (association).
>
> Is this correct?
>
> Thank you for your clear answer, all the fog is gone I think ;).
>
> Yours, J.T.K.M.
>

> 2010/1/20 H. S. Lahman <h.lah...@verizon.net>

> > H.lah...@verizon.net


> > software blog:http://pathfinderpeople.blogs.com/hslahman/index.html
>
> > --
> > You received this message because you are subscribed to the Google Groups
> > "UML Forum" group.
> > To post to this group, send email to umlf...@googlegroups.com.
> > To unsubscribe from this group, send email to

> > umlforum+u...@googlegroups.com<umlforum%2Bunsu...@googlegroups.com>

Bob Palank

unread,
Jan 21, 2010, 7:05:59 PM1/21/10
to umlf...@googlegroups.com
FWIW
In reality, students register for a section of a course!
An active course has one or more sections.
Bob

Responding to Man...

No virus found in this incoming message.
Checked by AVG - www.avg.com
Version: 8.5.432 / Virus Database: 271.1.1/2636 - Release Date: 01/21/10
07:34:00

Livia Pérez

unread,
Jan 22, 2010, 4:32:09 AM1/22/10
to umlf...@googlegroups.com
There's another example...
 
[Product]*-------------------*[Shopping Cart]*--------------------1[Customer]
 
Obs.: Shopping Cart is just a customer's product list.
 
You can have many Customer's shopping carts with many products into.
The Shopping Cart class can have this attributes: (code, date, customer_code, product_code, product_quantity, product_cost, total_cost).
 
It's a Relationship Class.

 
Liv.

 
2010/1/21 Bob Palank <b...@stlcc.org>
--
You received this message because you are subscribed to the Google Groups "UML Forum" group.
To post to this group, send email to umlf...@googlegroups.com.
To unsubscribe from this group, send email to umlforum+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/umlforum?hl=en.




--
Att,

Lívia Pérez Bettero
55 21 8708-8408

Tsun Kiet Man

unread,
Jan 23, 2010, 5:26:52 PM1/23/10
to umlf...@googlegroups.com
Ah, thanks for your responses guys, but is there an actual difference between an UML about classes and objects? (correct me if I'm wrong please)
 
Thanks!

2010/1/22 Livia Pérez <livia...@gmail.com>

H. S. Lahman

unread,
Jan 24, 2010, 11:05:13 AM1/24/10
to umlf...@googlegroups.com
Responding to Man...

> Ah, thanks for your responses guys, but is there an actual difference
> between an UML about classes and objects? (correct me if I'm wrong please)

UML classes are simply sets of objects. The set is defined by the
responsibilities that all objects in the set must have.

Objects abstract identifiable problem space entities.

The questions you are asking are very basic. I would strongly suggest
getting a book on UML and reading it. UML and the methodologies for
using it are too complex to learn on an online forum. The alternative is
that these are homework questions from school, in which case forums are
not an appropriate place to learn.

Livia Pérez

unread,
Jan 25, 2010, 5:52:39 AM1/25/10
to umlf...@googlegroups.com
I Agree with you, Lahman.
 
I was writhing almost the same answer when I saw you e-mail.
 
UML is not so easy as it seems.
Here in Brazil theres a post-graduation course about UML. I think there's another courses like this around the world.
 
A Forum is not the best way to learn... The best way to learn is starting to read any book about UML.
 
UML 2 For Dummies
http://books.google.com.br/books?id=gKHfVZn1CkgC&printsec=frontcover&dq=UML&cd=5#v=onepage&q=&f=false
 
Learning UML 2.0
 
 
Liv.
 
;-)

 
2010/1/24 H. S. Lahman <h.la...@verizon.net>
--
You received this message because you are subscribed to the Google Groups "UML Forum" group.
To post to this group, send email to umlf...@googlegroups.com.
To unsubscribe from this group, send email to umlforum+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/umlforum?hl=en.

Thomas Mercer-Hursh, Ph.D.

unread,
Feb 10, 2010, 5:33:36 PM2/10/10
to umlf...@googlegroups.com
I'm having a bit of a debate with a colleague about the GoF Decorator
pattern and I'm wondering what this group thinks.

His position is that the Intent of Decorator specifically states that
Decorator provides a "flexible alternative to subclassing for extending
functionality" and that the balance of the pattern description
reinforces this statement. He is therefore inclined to use Decorator
routinely as a means of creating subtypes of a base entity, citing the
flexibility this provides and the way that it avoids the "crosstab"
problem which can occur when there are multiple classifications that can
all apply at the same time to the same base entity.

My read of GoF is that Decorator was specifically intended for dynamic
additions of functionality particularly in cases which functionality is
context dependent and/or where the functionality in question is not
systematically applied to all instances. E.g., any particular Order
must be one or the other of an InternalOrder or an ExternalOrder, so I
would not use Decorator to make that distinction because all Orders are
one or the other. But, some Windows have scroll bars and some don't and
the category No Scroll Bars has no specific functionality associated
with it, so that is a good example of a context in which to use Decorator.

To me, the preferred approach for dealing with a potential "crosstab"
generalization problem is to use a combination of Generalization and
Delegation, i.e., by identifying cohesive spheres of responsibility
which can be segregated into their own delegate generalization
hierarchy, one removes one of the possible "dimensions" of the
crosstab. Do that enough and one reduces all generalization hierarchies
to simple ones.

I.e., I would do what decomposition I could do with Generalization and
Delegation and only resort to Decorator for what was "left over" because
it didn't fall into the category of the kinds of breakdowns for which
systematic decomposition was appropriate.

What does this group think?

>
--

======================================================================
Consulting in Architecture-Driven Modernization and Transformation
----------------------------------------------------------------------
Thomas Mercer-Hursh, Ph.D. email: tho...@cintegrity.com
Computing Integrity, Inc. voice: 510-233-5400
60 Belvedere Avenue fax: 510-233-5446
Point Richmond, CA 94801-4023 url: http://www.cintegrity.com
======================================================================

Ken Lloyd

unread,
Feb 10, 2010, 11:09:14 PM2/10/10
to umlf...@googlegroups.com
@Mercer-Hursh:

Actually, I think both positions are conceptually representative of the same
phenomena. So I don't see a conflict. A distinction without a difference.

The basic idea of "decoration" involves "hanging on" new features or objects
onto relatively primitive types. This need not be linear, but can branch as
necessary (as in the scroll bar reference, which seems a good example). I
was confused by the "No Scroll Bars" reference. Does this somehow mean to
undecorate a Decorated type?

Let's say that ScrollBar and TaskBar were both derived from a Decorator
superclass. I could have a decorations::Decorator[*] that could hold none,
one or more of each ScrollBar and TaskBar. But to be a Decorator pattern,
it wouldn't have to be actually named the Decorator class, it could be
called Control, for example.

There are many techniques for dealing with cross-cutting concerns
(cross-tabs, as I take the use of your term). Aspects, for instance. I'm not
sure I see how Generalization and Delegation might apply. I can see using
delegates or delegation for task or event handlers across classes, but not
actual adornment objects themselves - but again I would need to see an
example of your meaning. Or perhaps you are you referring to virtualization,
or interface implementation? Maybe the much maligned multiple inheritance?

A UML picture is worth a thousand words - if you put a lot of comments in
your code. Did I hit any of your meanings?

Ken

ashley....@metamaxim.com

unread,
Feb 11, 2010, 5:08:21 AM2/11/10
to umlf...@googlegroups.com
Hi

Here is a perspective on this.

Many years ago (around 1990) there was debate in academic circles about
the relative merits of composition (mixins) and subclassing. A key paper
produced around this time is:

G. Bracha and W. Cook. Mixin-based inheritance. Proc. of the ASM
conference on Object-Oriented Programming, Systems, Languages,
Applications, OOPSLA/ ECOOP�90, ACM SIGPLAN Notices, volume 25, number 10,
pages 179�183, 1990.

The term "mixin" is used in this paper to mean a language construct that
is an *alternative to inheritance*, and it is possible to design
programming languages that handle class variation in a purely composition
way. The above paper points out that such a pure compositional approach to
variation has the semantic power of multiple inheritance.

It is arguable that the software industry made a fundamental mistake by
adopting the hierarchical (inheritance) approach rather than composition
as the native method of creating variants in OO languages. Hierarchical
multiple inheritance has always been troublesome -- the developers of
Smalltalk experimented with it, and there was a version of Smalltalk that
supported it, but it was removed because it caused semantic confusion. So,
in general, we are left with single inheritance and a variety of "sticking
plasters" to address the problems that it causes -- the "crosstab problem"
being one. These sticking plasters include using compositional patterns
such as Decorator.

The GoF famously said "Prefer Composition Over Inheritance" but, for the
mainstream of OO language design, said it too late!

Rgds
Ashley

Thomas Mercer-Hursh, Ph.D.

unread,
Feb 11, 2010, 12:30:46 PM2/11/10
to umlf...@googlegroups.com
Ken Lloyd wrote:

> So I don't see a conflict. A distinction without
> a difference.

I don't see a conflict either ... if one uses each for the appropriate
purpose. Decorator is clearly the tool of choice ... or at least an
appropriate tool ... when one needs to attach and detach functionality
dynamically or when one has a big bucket of options of which 0 to N may
be applied to any one object. Whereas, I would prefer Generalization
and Delegation for the systematic decomposition of static
functionality. The issue is using Decorator for the latter.

> I was confused by the "No Scroll Bars" reference.
> Does this somehow mean to undecorate a Decorated type?

My intended point ... which I guess wasn't clear ... is that in some
cases with and without are meaningful, complementary states, i.e., there
is functionality associated with the "without" state. With the kind of
functionality one associates with Decorator (at least *this* one), the
"without" state is merely the base condition of the object and has no
particular unique functionality associated with it.

> There are many techniques for dealing with cross-cutting concerns
> (cross-tabs, as I take the use of your term). Aspects, for instance.
> I'm not sure I see how Generalization and Delegation might apply. I
> can see using delegates or delegation for task or event handlers
> across classes, but not actual adornment objects themselves - but
> again I would need to see an example of your meaning. Or perhaps you
> are you referring to virtualization, or interface implementation?
> Maybe the much maligned multiple inheritance?

Let's take Order. There is one possible subtype classification based on
OrderSource - EDI, Catalog, Mail, Phone, Web, etc. - and another
possible subtype classification based on whether the customer is
Internal or External. Represention that with Generalization alone
presents an crosstab problem (although perhaps not a full crosstab since
not all sources may apply to internal customers, but let's pretend they
do). If I turn OrderSource into its own class as a Delegate and do the
same with OrderCustomerType, then there is no crosstab problem because
each delegate has its own simple Generalization hierarchy.

Thomas Mercer-Hursh, Ph.D.

unread,
Feb 11, 2010, 12:38:42 PM2/11/10
to umlf...@googlegroups.com
ashley....@metamaxim.com wrote:
> Many years ago (around 1990)

For some of us EOFs, that wasn't so long ago ... :)

> It is arguable that the software industry made a fundamental mistake
> by adopting the hierarchical (inheritance) approach rather than
> composition as the native method of creating variants in OO
> languages. Hierarchical multiple inheritance has always been
> troublesome -- the developers of Smalltalk experimented with it, and
> there was a version of Smalltalk that supported it, but it was
> removed because it caused semantic confusion. So, in general, we are
> left with single inheritance and a variety of "sticking plasters" to
> address the problems that it causes -- the "crosstab problem" being
> one. These sticking plasters include using compositional patterns
> such as Decorator.
>
> The GoF famously said "Prefer Composition Over Inheritance" but, for
> the mainstream of OO language design, said it too late!

Myself, I don't see it as a competition, but rather a question of
appropriateness. It is all about identifying cohesive areas of
responsibility. If, within the superset responsibility of a collection
of objects there is a cohesive bundle of responsibility which can be
cleanly separated, then the right thing to do is to separate it ...
separation of concerns. This will make all the classes simpler. But,
when the nature of the variation in responsibility is a subdivision into
types, i.e., something where there are N clear types and each object
must be one of those types, then Generalization is the right tool. The
two work hand in hand in a complementary fashion.

ashley....@metamaxim.com

unread,
Feb 11, 2010, 12:54:47 PM2/11/10
to umlf...@googlegroups.com

Hi

Thomas Mercer-Hursh wrote (re: Mixins and Inheritance)

> Myself, I don't see it as a competition, but rather a question of
> appropriateness. It is all about identifying cohesive areas of
> responsibility. If, within the superset responsibility of a collection
> of objects there is a cohesive bundle of responsibility which can be
> cleanly separated, then the right thing to do is to separate it ...
> separation of concerns. This will make all the classes simpler. But,
> when the nature of the variation in responsibility is a subdivision into
> types, i.e., something where there are N clear types and each object
> must be one of those types, then Generalization is the right tool. The
> two work hand in hand in a complementary fashion.

Yes, the two situations you describe exist. But if your language supports
both using the same mechanism, you have a simpler cleaner langauge.

Also, a single mechanism makes it *much* easier to refactor code if you
change your mind about which situation you have.

View it as an application of Occam's Razor, if you like.

Rgds
Ashley

H. S. Lahman

unread,
Feb 12, 2010, 11:07:03 AM2/12/10
to umlf...@googlegroups.com
In the interest of putting words into Thomas' mouth, I would like to try
some clarification on the issue. (I was the one to suggest he poll a forum.)

When the GoF describe Decorator they use the word 'dynamic' several
times. To me that implies run-time decision making based on changing
run-time context. Their example of a menu seems to exemplify that sort
of thing. Let's say some users don't get to use certain menu items.
Whether that functionality is greyed out (i.e., not a responsibility of
the underlying object) can only be determined at run time once one
understands the context (i.e., what flavor of user is logged in).
Similarly, there might be certain activities that users can perform that
require options to be added to menus already existing in scope. Again,
that modification of the menu cannot be done unless one know the dynamic
run-time context of the particular activity. IOW, one is defining
subsets dynamically.

Generalization is the primary OO tool for defining subsets and it is
derived directly from set theory, particularly relational theory.
However, in most OOPLs generalization is a static structure; it can only
be modified by changing the OOPL code because its definition is
inherently declarative. (Even dynamically bound OOPLs that
"transparently" allow such changes at run time are really pausing the
execution and switching seamlessly into a "design" mode to do the
change.) Therefore it is not possible in the popular OOPLs to use just
generalization for the dynamic decisions like the menu example. The
Decorator pattern provides a mechanism for resolving that dynamic situation.

Thomas' colleague, however, is using Decorator to define subsets that
are already defined in an RDB. That is, he is using Decorator as a
mechanism for a factory to instantiate objects by extracting the data
attributes from the RDB and those objects are mapped 1:1 to the RDB
Schema. To me the issue here is that the RDB schema is already a static
definition and no run-time decision making is required for resolving the
responsibilities of the objects. Therefore Decorator seems to be
overkill compared to the much more direct relational mapping between RDB
subtyping* and OO generalization.

* In Thomas' context things are somewhat more confused because some
legacy RDB schema are poorly formed in that subsets are not separated
into their own parent/child subtype tables (i.e., they are all contained
in a single table). But there are still schema mechanisms to distinguish
tuples as true Data Modeling subtypes for interpretation when accessing
the RDB by the factory.

John "Z-Bo" Zabroski

unread,
Feb 12, 2010, 6:11:35 PM2/12/10
to UML Forum

In my experience, I often see developers combining Decorator with
Chain of Responsibility. In other words, an OOPL allows the
programmer to prepend metadata as an "Attribute" or "Annotation" to
the static declare-site (e.g., a field, property, event, method, class
or module) to the dynamic use-site (e.g., constructing an object).
The annotated static signature then maps to an implementation that
knows how to read its annotations at run-time. This is a form of
reflection in 3rd generation OOPLs known as introspection. The
trouble with this approach is that it ultimately relies upon several
layers of static and dynamic configuration contexts, and debugging how
the internal state-process of an object chose a specific configuration
requires knowing the exact implementation of the Chain of
Responsibility pattern.

For example, here is some C# code:

[EmailValidation]
public class Person
{
// private details elided
[EmailValidation]
public String emailAddress { get; set; }
}

I believe this combination of patterns to almost always be a model
smell, and also a design contradiction: you cannot innovate
configuration by using two patterns that both attempt to do dynamic
configuration, without substantially increasing configuration
complexity. To look at a way we can innovate here, let us consider
refactoring the above code:

public class EmailAddress
{
#region Properties
public bool IsValid;
#endregion
#region Methods
public EmailAddress createEmailAddress(string emailAddress)
{
string emailAddressValidationPattern = ...;
// ...the regular expression to properly validate an e-mail
address
// requires a full page length, so we will elide constructing the
// regex pattern here
if (Regex.IsMatch(emailAddress, emailAddressValidationPattern)
{
IsValid = true;
}
}
#endregion
}

public class Person
{
public EmailAddress emailAddress { get; set; }
}

Notice that not only have I removed the necessity for dynamic
configuration logic, but I've also improved the cohesiveness of the
class design. An EmailAddress itself determines whether or not it is
a valid address. Now, instead of scattering validation logic all over
the source code, it is kept in one place. Should we need to customize
the definition of a valid e-mail address, such as adding policies to
restrict the domain of a valid e-mail address, we can do so by adding
additional validation logic. However, we would only do that for a
specific problem domain that requires additional validation logic
rather than encode it directly into the EmailAddress class.

In Example 1 (highly unmaintainable, difficult to debug), we encode
validation logic by using "sticking plaster" (to borrow Ashley's
terminology) which is not guaranteed to stay there and can be easily
scraped off by someone else. Example 1 is also a slippery slope in
general. Where do you stop looking for dependencies? An XML
configuration file? A database on the network? A datastream over TCP/
IP? In a 3rd generation OOPL, this means you are adding additional
dependencies just to resolve dependencies! Keep in mind, you've not
improved maintainability or debuggability. You have made things
slightly easier to change configuration values for, but simply
changing configuration files is not the same thing as making things
easy to configure! Making things easy to configure generally involves
putting data and methods together, to form an object, and then putting
objects together, to form a component that contains all of your
factory logic for creation as well as behavior functionality
dynamically determined at run-time). Also, in addition to not really
making things easier to configure, if you include a Chain of
Responsibility that has the potential for failing (running off the end
of the chain), then now you must account for partial failure in your
system. Given the encoding of the problem domain in Example 1, this
means invasively adding concerns to at least the Person class that
cannot be managed by the Person factory (because the Decorator is
applied at run-time, potentially after the factory has been invoked
and returns a Person object).

Here are some additional thoughts on Decorator:

Sometimes Decorator can be used inappropriately or at least
questionably. For example, I would argue Thomas' example of
decorating a Window with a Border is a problem domain abstraction
issue, because it assumes that in order to instantiate a Window you
must use a Builder pattern that nests Composite objects where each
object in the composite has a Visual role. In other words, assume
that a Window is a facade to the operating system windowing manager.
Then we cannot simply decorate a Window with a Border object and have
the Border object transparently affect the Window base entity, because
the page layout synthesis algorithm belonging to the Window must know
about Visual decorators that can be dynamically inserted into the
Visual Composite (we might want to dynamically adorn a Border to a
Window when some environment variable is true, and the Builder has
already constructed the Composite scene graph so it cannot serve to
update the scene graph as well, especially since Builder is a
creational pattern and is not meant to address issues that require
dynamic object graph management). Furthermore, if the Window's
surface is mostly transparent and irregularly shaped, then the Border
does not have enough information to correct wrap the Window's surface
contents. The abstraction is very leaky. To be honest, I used to
make this mistake all the time in GUI applications, until I decided
that hardcoding containment pointwise reasoning of objects with nested
coordinates was a bad idea. In fact, with today's physics-based GPU
acceleration technology, encoding layout constraints with physics is
potentially more optimal and more responsive. In this sense,
Decorator is not a code smell, but instead a hint that you should be
refactoring your code to something more general, eventualy, once you
understand what that generalization is. It may be suitable not to
abstract away that generalization initially, as clients may not care,
but from the standpoint of a graphics UI library writer, you might
want to seek the most general, reusable, context-independent problem
domain abstractions.

I also think, from my description above, that a Border can switch from
being a visual object (playing a role in the View) to being a
behavioral object (playing a role in interaction), and that not
separating these two roles may result in entangling two separate user
interface concerns.

> * In Thomas' context things are somewhat more confused because some
> legacy RDB schema are poorly formed in that subsets are not separated
> into their own parent/child subtype tables (i.e., they are all contained
> in a single table). But there are still schema mechanisms to distinguish
> tuples as true Data Modeling subtypes for interpretation when accessing
> the RDB by the factory.

Even in this situation, it would behoove the database designer to
refactor the schema first, such that there is a clean separation
between abstract data object and RDBMS storage type. This principle
is covered in Date & Darwen's Third Manifesto book, and they
characterize it as an original sin, referring to it as the The First
Great Blunder. See: http://c2.com/cgi/wiki?FirstGreatBlunder Such a
refactoring will make later code refactorings much more simple.
However, for databases with billions of rows already, it might be
somewhat impractical, as changing the data type would require a side-
by-side copy that streams over rows in small increments to avoid
getting tangled by the database's locking protocols.


> --
> Life is the only flaw in an otherwise perfect nonexistence
>    -- Schopenhauer
>
> H. S. Lahman

Reply all
Reply to author
Forward
0 new messages