From: weboweb on
Hi everybody,

I'm getting my feet wet in Design Patterns, I have a question before I
go any deeper.
I have the following classes:

----------------------------------------------------
Folder (class that will need logging)

File (class that will need logging)
----------------------------------------------------


Logging structure:
----------------------------------------------------
AuditBase
projectID
name

AuditFolder (inherits from Base)

AuditFile (inherits from Base)
size
serverName
----------------------------------------------------


I want to add logging functionality to both Folder and File objects.
They will both inherit from lets say "TreeItem" class.

I was thinking of using an AuditDecorator class to take a TreeItem as
a parameter in the constructor.
However, as you may see, the AuditBase class does not contain all the
properties that need to be logged. For example, AuditFile has the
size and serverName properties that would need to get logged for a
File object.

Which would mean that the AuditDecorator class would have to be aware
of those 2 extra properties when receiving a TreeItem object.

Could somebody more experienced than me please tell me if I'm going in
the right direction here?

Many thanks!

weboWeb






I want to add Log functionality to

From: H. S. Lahman on
Responding to Weboweb...

> Hi everybody,
>
> I'm getting my feet wet in Design Patterns, I have a question before I
> go any deeper.
> I have the following classes:
>
> ----------------------------------------------------
> Folder (class that will need logging)
>
> File (class that will need logging)
> ----------------------------------------------------
>
>
> Logging structure:
> ----------------------------------------------------
> AuditBase
> projectID
> name
>
> AuditFolder (inherits from Base)
>
> AuditFile (inherits from Base)
> size
> serverName
> ----------------------------------------------------
>
>
> I want to add logging functionality to both Folder and File objects.
> They will both inherit from lets say "TreeItem" class.
>
> I was thinking of using an AuditDecorator class to take a TreeItem as
> a parameter in the constructor.
> However, as you may see, the AuditBase class does not contain all the
> properties that need to be logged. For example, AuditFile has the
> size and serverName properties that would need to get logged for a
> File object.

First, I am confused by the names used. Is File a problem object whose
changes need to be logged, as it seems to be in the description
immediately above)? AuditFile sounds more like an object that exists to
accept change messages and write them out to a persistent data store
(e.g., a log file).

Second, I am not sure things need to be that complicated. In principle
logging is pretty simple. When something changes a message is generated
and sent to a persistent store or somebody who cares about the change.
Either way, there is <usually> one "processor" of the audit information
and many client objects who have to notify that "processor" when they
change.

Usually the complicated part is figuring out a message format that is
easy to encode and interpret while being fairly generic. For example,
with a message format of {message ID, object ID, attribute ID, new
value}, one needs an identity scheme that allows 'new value' to be
interpreted properly for a variety of memory formats or data aggregates.

In a simple situation the "processor" might have a single logInfo
(message ID, object ID, attribute ID, value) interface method that is
invoked directly from the attribute setter of the object:

Folder::setName (name)
this.myName = name
myLogger.logInfo(FOLDER, this, NAME_CHANGE, name)

where one uses operator overloading in the Logger class to deal with
different attribute memory formats.

So my push back is: what sort of problem complexity do you have that
seems to warrant something as complex as Decorator?


*************
There is nothing wrong with me that could
not be cured by a capful of Drano.

H. S. Lahman
hsl(a)pathfindermda.com
Pathfinder Solutions
http://www.pathfindermda.com
blog: http://pathfinderpeople.blogs.com/hslahman
"Model-Based Translation: The Next Step in Agile Development". Email
info(a)pathfindermda.com for your copy.
Pathfinder is hiring:
http://www.pathfindermda.com/about_us/careers_pos3.php.
(888)OOA-PATH



From: weboweb on
On Nov 5, 1:58 pm, "H. S. Lahman" <h.lah...(a)verizon.net> wrote:
> Responding to Weboweb...
>
>
>
>
>
> > Hi everybody,
>
> > I'm getting my feet wet in Design Patterns, I have a question before I
> > go any deeper.
> > I have the following classes:
>
> > ----------------------------------------------------
> > Folder (class that will need logging)
>
> > File (class that will need logging)
> > ----------------------------------------------------
>
> > Logging structure:
> > ----------------------------------------------------
> > AuditBase
> > projectID
> > name
>
> > AuditFolder (inherits from Base)
>
> > AuditFile (inherits from Base)
> > size
> > serverName
> > ----------------------------------------------------
>
> > I want to add logging functionality to both Folder and File objects.
> > They will both inherit from lets say "TreeItem" class.
>
> > I was thinking of using an AuditDecorator class to take a TreeItem as
> > a parameter in the constructor.
> > However, as you may see, the AuditBase class does not contain all the
> > properties that need to be logged. For example, AuditFile has the
> > size and serverName properties that would need to get logged for a
> > File object.
>
> First, I am confused by the names used. Is File a problem object whose
> changes need to be logged, as it seems to be in the description
> immediately above)? AuditFile sounds more like an object that exists to
> accept change messages and write them out to a persistent data store
> (e.g., a log file).

A File object could basically be deleted, modified, downloaded,
uploaded, etc.
A Folder object could be deleted, renamed, its access modified, etc.

>
> Second, I am not sure things need to be that complicated. In principle
> logging is pretty simple. When something changes a message is generated
> and sent to a persistent store or somebody who cares about the change.
> Either way, there is <usually> one "processor" of the audit information
> and many client objects who have to notify that "processor" when they
> change.

In this case it would not be automatic. In some cases the changes
would need to be logged, in other cases not.

>
> Usually the complicated part is figuring out a message format that is
> easy to encode and interpret while being fairly generic. For example,
> with a message format of {message ID, object ID, attribute ID, new
> value}, one needs an identity scheme that allows 'new value' to be
> interpreted properly for a variety of memory formats or data aggregates.
>
> In a simple situation the "processor" might have a single logInfo
> (message ID, object ID, attribute ID, value) interface method that is
> invoked directly from the attribute setter of the object:
>
> Folder::setName (name)
> this.myName = name
> myLogger.logInfo(FOLDER, this, NAME_CHANGE, name)
>
> where one uses operator overloading in the Logger class to deal with
> different attribute memory formats.
>
> So my push back is: what sort of problem complexity do you have that
> seems to warrant something as complex as Decorator?

In your example, the Folder class has to be aware of the Log class
(the myLogger object). I was trying to avoid the File / Folder class
being aware of any Log class.
Or to put it in another way,I am trying to not include the Log
functionality in the File / Folder classes, but just "adorn" some of
their objects at runtime if need be.

Another pattern that comes to mind is a Mediator, which would know the
connection between the File / Folder class and some Log class which
actually logs the changes to some data store.

I guess the main problem I find is that either the Mediator or the
Decorator would have to check the Concrete type of the General type it
would work on in order to provide slightly different functionality.
(File object contains a couple extra properties that Folder does not
have)


Thanks for your comments, very much appreciated!

weboWeb



>
> *************
> There is nothing wrong with me that could
> not be cured by a capful of Drano.
>
> H. S. Lahman
> h...(a)pathfindermda.com
> Pathfinder Solutionshttp://www.pathfindermda.com
> blog:http://pathfinderpeople.blogs.com/hslahman
> "Model-Based Translation: The Next Step in Agile Development". Email
> i...(a)pathfindermda.com for your copy.
> Pathfinder is hiring:http://www.pathfindermda.com/about_us/careers_pos3.php.
> (888)OOA-PATH- Hide quoted text -
>
> - Show quoted text -


From: weboweb on
On Nov 5, 1:58 pm, "H. S. Lahman" <h.lah...(a)verizon.net> wrote:



- Hide quoted text -
- Show quoted text -

> Responding to Weboweb...

> > Hi everybody,


> > I'm getting my feet wet in Design Patterns, I have a question before I
> > go any deeper.
> > I have the following classes:


> > ----------------------------------------------------
> > Folder (class that will need logging)


> > File (class that will need logging)
> > ----------------------------------------------------


> > Logging structure:
> > ----------------------------------------------------
> > AuditBase
> > projectID
> > name


> > AuditFolder (inherits from Base)


> > AuditFile (inherits from Base)
> > size
> > serverName
> > ----------------------------------------------------


> > I want to add logging functionality to both Folder and File objects.
> > They will both inherit from lets say "TreeItem" class.


> > I was thinking of using an AuditDecorator class to take a TreeItem as
> > a parameter in the constructor.
> > However, as you may see, the AuditBase class does not contain all the
> > properties that need to be logged. For example, AuditFile has the
> > size and serverName properties that would need to get logged for a
> > File object.


> First, I am confused by the names used. Is File a problem object whose
> changes need to be logged, as it seems to be in the description
> immediately above)? AuditFile sounds more like an object that exists to
> accept change messages and write them out to a persistent data store
> (e.g., a log file).



A File object could basically be deleted, modified, downloaded,
uploaded, etc.
A Folder object could be deleted, renamed, its access modified, etc.


> Second, I am not sure things need to be that complicated. In principle
> logging is pretty simple. When something changes a message is generated
> and sent to a persistent store or somebody who cares about the change.
> Either way, there is <usually> one "processor" of the audit information
> and many client objects who have to notify that "processor" when they
> change.



In this case it would not be automatic. In some cases the changes
would need to be logged, in other cases not.



- Hide quoted text -
- Show quoted text -

> Usually the complicated part is figuring out a message format that is
> easy to encode and interpret while being fairly generic. For example,
> with a message format of {message ID, object ID, attribute ID, new
> value}, one needs an identity scheme that allows 'new value' to be
> interpreted properly for a variety of memory formats or data aggregates.


> In a simple situation the "processor" might have a single logInfo
> (message ID, object ID, attribute ID, value) interface method that is
> invoked directly from the attribute setter of the object:


> Folder::setName (name)
> this.myName = name
> myLogger.logInfo(FOLDER, this, NAME_CHANGE, name)


> where one uses operator overloading in the Logger class to deal with
> different attribute memory formats.


> So my push back is: what sort of problem complexity do you have that
> seems to warrant something as complex as Decorator?



In your example, the Folder class has to be aware of the Log class
(the myLogger object). I was trying to avoid the File / Folder class
being aware of any Log class.
Or to put it in another way,I am trying to not include the Log
functionality in the File / Folder classes, but just "adorn" some of
their objects at runtime if need be.


Thanks for your comments, very much appreciated!


weboWeb



- Hide quoted text -
- Show quoted text -

> *************
> There is nothing wrong with me that could
> not be cured by a capful of Drano.


> H. S. Lahman
> h...(a)pathfindermda.com
> Pathfinder Solutionshttp://www.pathfindermda.com
> blog:http://pathfinderpeople.blogs.com/hslahman
> "Model-Based Translation: The Next Step in Agile Development". Email
> i...(a)pathfindermda.com for your copy.
> Pathfinder is hiring:http://www.pathfindermda.com/about_us/careers_pos3.php.
> (888)OOA-PATH- Hide quoted text -


> - Show quoted text -






From: H. S. Lahman on
Responding to Weboweb...

>>>I have the following classes:
>>
>>>----------------------------------------------------
>>>Folder (class that will need logging)
>>
>>>File (class that will need logging)
>>>----------------------------------------------------
>>
>>>Logging structure:
>>>----------------------------------------------------
>>>AuditBase
>>> projectID
>>> name
>>
>>>AuditFolder (inherits from Base)
>>
>>>AuditFile (inherits from Base)
>>> size
>>> serverName
>>>----------------------------------------------------
>>
>>>I want to add logging functionality to both Folder and File objects.
>>>They will both inherit from lets say "TreeItem" class.
>>
>>>I was thinking of using an AuditDecorator class to take a TreeItem as
>>>a parameter in the constructor.
>>>However, as you may see, the AuditBase class does not contain all the
>>>properties that need to be logged. For example, AuditFile has the
>>>size and serverName properties that would need to get logged for a
>>>File object.
>>
>>First, I am confused by the names used. Is File a problem object whose
>>changes need to be logged, as it seems to be in the description
>>immediately above)? AuditFile sounds more like an object that exists to
>>accept change messages and write them out to a persistent data store
>>(e.g., a log file).
>
>
> A File object could basically be deleted, modified, downloaded,
> uploaded, etc.
> A Folder object could be deleted, renamed, its access modified, etc.

So are File and Folder different objects than AuditFile and AuditFolder?

>>Second, I am not sure things need to be that complicated. In principle
>>logging is pretty simple. When something changes a message is generated
>>and sent to a persistent store or somebody who cares about the change.
>>Either way, there is <usually> one "processor" of the audit information
>>and many client objects who have to notify that "processor" when they
>>change.
>
>
> In this case it would not be automatic. In some cases the changes
> would need to be logged, in other cases not.

OK, that just means there is some condition on sending the message (or
there is some context information in the message or other objects that
"processor" can access that the "processor" can use to ignore the message).

>>Usually the complicated part is figuring out a message format that is
>>easy to encode and interpret while being fairly generic. For example,
>>with a message format of {message ID, object ID, attribute ID, new
>>value}, one needs an identity scheme that allows 'new value' to be
>>interpreted properly for a variety of memory formats or data aggregates.
>>
>>In a simple situation the "processor" might have a single logInfo
>>(message ID, object ID, attribute ID, value) interface method that is
>>invoked directly from the attribute setter of the object:
>>
>>Folder::setName (name)
>> this.myName = name
>> myLogger.logInfo(FOLDER, this, NAME_CHANGE, name)
>>
>>where one uses operator overloading in the Logger class to deal with
>>different attribute memory formats.
>>
>>So my push back is: what sort of problem complexity do you have that
>>seems to warrant something as complex as Decorator?
>
>
> In your example, the Folder class has to be aware of the Log class
> (the myLogger object). I was trying to avoid the File / Folder class
> being aware of any Log class.
> Or to put it in another way,I am trying to not include the Log
> functionality in the File / Folder classes, but just "adorn" some of
> their objects at runtime if need be.

There's no free lunch. An announcement needs to be sent to somebody when
something changes in Folder. That message needs to be addressed to
whoever cares about the change and the 3GL type systems require
substantial physical coupling to do that. [Alternatively, whoever
changes Folder could also send the logging message. But that would be
more fragile and one would still have the message addressing problem; it
would just be in a different object.]

Also note that this is somewhat backward from what Decorator provides.
Decorator allows one to add properties to an object dynamically that
other objects can then access. But Folder isn't changing dynamically and
nobody is accessing Folder for the logging; it initiates the message
sending.

I really don't see why this shouldn't be a garden variety collaboration
between Folder and whoever handles the logging details. The logical
decoupling is achieved by encapsulating the logging details in the
implementation of the "processor" object. Then Folder only needs to know
what information to send and when to send it, which both seem intimately
related to change within Folder.

>
> Another pattern that comes to mind is a Mediator, which would know the
> connection between the File / Folder class and some Log class which
> actually logs the changes to some data store.

One uses Mediator when an object needs to talk to a lot of different
objects about the same thing. In your case a lot of objects talk /to/
"processor", but "processor" is the only object they need to talk to for
a logging collaboration.

Note that almost all of the GoF patterns, including Decorator and
Mediator, address the same megathinker problem:

1 R1 collaborates with 1
[Client] ------------------------- [Service]

However, the behavior that [Service] actually provides is substituted
dynamically based on the context of the collaboration. That dynamic
complexity is too complex to try to capture in a single static
association in the OOA/D. So the GoF patterns typically apply a
combination of delegation and polymorphic dispatch to be more specific
about how the substitution works. Thus the various GoF patterns
represent different common contexts where such dynamic substitution is
needed in a basic client/service collaboration.

My push back here is that I don't see the sorts of dynamic substitution
issues in this problem that the GoF patterns resolve. File, Folder, et
al simply collaborate with somebody who knows how to do audit trails.
They send exactly the exactly the same message to exactly the same place
for a particular kind of change every time.

[Having said that, I can certainly envision auditing situations that are
more complex where the "processor" needs to be very smart and may have
to gather additional context data. In that case the messages generated
by Folder et al just trigger complex processing that might involve
multiple objects or even an entire subsystem. Then one might encapsulate
all that behind a Facade pattern that Folder et al talk to.]


*************
There is nothing wrong with me that could
not be cured by a capful of Drano.

H. S. Lahman
hsl(a)pathfindermda.com
Pathfinder Solutions
http://www.pathfindermda.com
blog: http://pathfinderpeople.blogs.com/hslahman
"Model-Based Translation: The Next Step in Agile Development". Email
info(a)pathfindermda.com for your copy.
Pathfinder is hiring:
http://www.pathfindermda.com/about_us/careers_pos3.php.
(888)OOA-PATH