Re: Is it a facade
- From: "Sanjay" <sanjay.chittar@xxxxxxxxx>
- Date: 29 Jan 2006 10:23:47 -0800
H. S. Lahman wrote:
> >>>Was curious to know if I can *only* call a pattern which gives client
> >>>an abstraction of the subsystems in a single call, a facade or could
> >>>it be possible that a ModuleManager class that provides many API's to
> >>>clients to finally build a Module entity also as Facade.
> >>>
> >>>Please note that all those API's are independent of each other but in a
> >>>way help to build an entity. I mean they are loosely coupled.
> >>
> >>I think you need to put some more words around the problem that you are
> >>actually trying to solve. What are the modules? How do they relate to
> >>subsystems? Who are the clients? What semantics are the APIs accessing?
> >
> >
> > Actually dont have any particular problem at hand, but will try to put
> > this as best as I can.
> >
> > Assume I am looking at a module that does auditing of any existing
> > application, may be a web application. Auditing, tries to figure out
> > how long this application is trying to respond to a request, which
> > server page was requested ...etc. Besides this let us assume that these
> > applications can also pass few auditing parameters.
> >
> > The auditing module finally builds an entity that is dumped as an audit
> > record.
>
> By 'dumped' I assume you mean it is written to a file(?)
Yes, may be into the database also.
>
> > Now this audit record is what every application is interested in and
> > can build using the classes that are well defined ( _subsystems_ ).
> > Now we think of giving API's to these exisitng applications ( _clients_
> > ), so that the clients deal with API's that are interfaces taking
> > simple context information.
>
> This is where I am getting lost. Who is building (instantiating?)
> classes from the audit record? Why do you see these as subsystems? (In
The classes inside the Audit Module under consideration is building
this Audit record.
I guess I understand now that the well defined classes cannot be a
subsystems since they only have to collaborate for building this audit
record.
> my world a subsystem captures a particular <large scale> subject matter
> that is implemented with multiple objects from multiple classes.)
>
> These "other applications" seem to just need the audit record. So why
> don't they read it from the file and process it (i.e., the original
> audit module is now out of the picture)?
I guess I didnot complete my problem, the audit record is not for the
clients. They are used by the Audit Module under consideration to
generate reports.
The clients systems help the Audit module under consideration to build
an Audit record.
>
> Why do the other applications need APIs rather than the audit record
> whose information they access?
These API's are interfaces for the client system to build the Audit
records.
>
> > These API's are exposed to the clients through an interface called
> > AuditManager class.
>
> Since you don't have a particular application in mind we can't abstract
> identity from a particular problem space entity, so I guess I'll have
> ignore my concerns here. But XxxxManager still makes me queasy. B-)
>
Do you still see any concerns here, I am unable to understand your
concerns.
> >
> > Now would this pattern be a facade pattern? would AuditManager class a
> > facade.
> >
> > Now may be I can rewrite my question as above
> >
> > "Was curious to know if I can *only* call a pattern which gives client
> > an abstraction of the subsystems in a single call, a facade or could
> > it be possible that a ModuleManager class that provides many API's to
> > clients to finally build a Module entity also as Facade."
>
> OK. This is a somewhat different question and I think the answer is:
> all of the above, depending on problem context.
>
> It is not uncommon to hide detailed processing at a lower level of
> abstraction in another subsystem. A common technique is then for a
> method in the higher level subsystem to just re-dispatch to an interface
> method of the lower level service subsystem. In that case, the bridge
> between subsystems is hidden in individual method implementations. So
> from the perspective of the higher level system the lower level of
> detail and, consequently, the existence of the service subsystem hidden
> (at the level of object collaborations); it is just mapped in the
> implementation of individual methods that, from the higher level
> subsystem's perspective, are atomic responsibilities.
>
> However, the service subsystem does exist and it provides multiple
> individual services for the higher level subsystem. When one defines
> that lower level subsystem, one needs to define and interface to
> encapsulate it that can be used by all those method implementations in
> the higher level subsystem for re-dispatching. That segues to...
>
> A Facade pattern is ideally suited to capturing broad, invariant
> responsibilities that can be implemented in many ways (i.e., with
> different objects, relationships, and detailed responsibilities). This
> happens to be exactly what one needs to decouple service subsystem
> implementations from the subsystems' clients, so the Facade pattern is
> commonly used to encapsulated subsystems.
>
> Because of the generic nature of the Facade interface, that allows plug
> & play substitutability of subsystem implementation. Thus an
> application may not care if the user is using a GUI or a web browser.
> The details of the UI are encapsulated in a subsystem behind a Facade
> that just describes the general communication needs. Then one can swap
> the UI implementation between GUI and browser without touching the rest
> of the application. One only needs to modify how the Facade interface's
> object dispatches to the GUI or browser abstractions that abstract the
> UI mechanism in hand.
>
> To examine the last issue of multiple APIs, imagine the case of swapping
> UI implementations. At the subsystem level this is very much like the
> GoF State pattern:
>
> * communicates via 1
> [ClientSubsystem] ------------------------ [UI]
> R1 + displayX()
> + displayY()
> ...
> A
> | R2
> +------------+-------------+
> | | |
> [GUI] [Browser] [SmokeSignal]
>
> As I described the use of Facade for subsystem interfaces above, [UI]
> would define the common interface and each subclass would provide its
> own implementation of displayX(), displayY(), etc. to talk to the
> objects of the particular UI mechanism. IOW, the Facade pattern enables
> polymorphic substitution of the subsystems in a manner that is
> transparent to the client.
>
> Your third issue address the problem where each subsystem has unique
> specialized services that the client may need to access in particular
> contexts. So there are unique interface methods in the Facade
> subclasses that the client must access when that UI is relevant. There
> is really no direct way to do that. The client must have relationships
> to the individual relationships:
>
>
> [UI]
> A
> | R2
> +----------------+----------------+
> | | |
> [GUI] [Browser] [SmokeSignal]
> + displayX + displayY + displayZ
> ... ... ...
> | 0..1 | 0..1 | 0..1
> | communicates | communicates | communicates
> | via | via | via
> | | |
> | R3 | R4 | R5
> | | |
> | * | * * |
> +-------- [ClientSubsystem] ------+
>
> Note the conditionality of R3, R4, and R5. This assumes that in a given
> context the ClientSubsystem will have only one relevant subsystem to
> talk to so only one relationship will be instantiated. However, somehow
> the ClientSubsystem has to know which interface to invoke once a
> particular relationship is instantiated (i.e., when R4 is instantiated,
> then ClientSubsystem must invoke displayY rather that displayX or displayZ).
>
> There is a way to work around this through a variation on the Visitor
> pattern. Once can use the same sort of accept/visitor infrastructure
> here. One just uses the VisitConcreteElementX (here VisitBrowser or
> VisitGUI) to provide dispatching to the relevant UI subclass methods.
>
> Note that since [ClientSubsystem] isn't subclassed here (i.e., there
> aren't different /client/ contexts for visitation), one only needs a
> single Visitor class to provide the dispatch. That "Visitor" object is
> essentially your ModuleManager. But it really doesn't manage anything;
> it just hard-wires the appropriate dispatching map so that
> [ClientSubsystem] does not need to be aware of it.
>
> However, I am skeptical that such a situation would be very common. If
> [ClientSubsystem] needs to invokes specialization properties and there
> are multiple context-driven choices, that means [ClientSubsystem] needs
> to understand the differences in context and do something different for
> each context. That is, the nature of the participation of the client in
> the collaboration changes because of the context. That is inherently
> suspicious because it starts to suggest [ClientSubsystem] is not
> cohesive and knows too much about its context of use.
>
> So if I was tempted to do something like this I would look for a way to
> capture common invariants or delegate responsibilities so that one could
> end up with a generic Facade that re-dispatches to unique
> /implementations/ of the same generic activities for each context (i.e.,
> the first model).
>
> If the processing of the service is complex but involves a fixed
> sequence of operations where the sequence is different for each service,
> then the Visitor variant may be useful. That's because one can
> essentially delegate the sequences to the Visitor object for hard-wiring
> in its VisitXxx methods. Then the client doesn't need to invoke
> individual operations in the right sequence for each context; it just
> focuses on when the processing needs to be done and what parametric data
> might be needed.
>
> For the UI example that is rather unlikely because one usually wants to
> display specific information and one can do that via a generic displayX
> sort of interface. The semantics is the same regardless of UI
> mechanism, so each UI subsystem can provide its own implementation of a
> common request. An exception might be where one wants to display
> graphics vs. text, but one would normally do that parametrically (i.e.,
> tell the UI subsystem whether the information is text or graphics in the
> message and let the subsystem figure out what to do). [Even if one uses
> different subsystems for text and graphics so there are separate
> <coexistent> relationships, the message is still the same and the client
> just has a rudimentary choice based on gross message context in
> selecting which relationship to navigate.]
>
> However, there are other examples, such as network protocols, where
> things like handshaking, message packet size, etc. are unique to the
> protocol. So one would like to encapsulate the protocol-specific
> aspects in a single method process rather than making the client
> providing the message context from doing that. But then one is back to
> a generic sendMessage(<content>) message where the implementation of a
> Protocol subclass implementation does the right thing.
>
> I mention this because the processing of your "audit record" sounds like
> could have fixed but different sequences of operations for each record
> type. So you might be able to use a Visitor-like infrastructure.
> However, I would still look for a way to raise the level of abstraction
> of the client request so that it is the same for any record type (e.g.,
> processIt). Then you can use a GoF Strategy or State pattern to
> substitute AuditRecord subclass implementations.
>
>
> *************
> There is nothing wrong with me that could
> not be cured by a capful of Drano.
>
Thanks
Sanjay
> H. S. Lahman
> hsl@xxxxxxxxxxxxxxxxx
> Pathfinder Solutions -- Put MDA to Work
> http://www.pathfindermda.com
> blog: http://pathfinderpeople.blogs.com/hslahman
> (888)OOA-PATH
.
- Follow-Ups:
- Re: Is it a facade
- From: H. S. Lahman
- Re: Is it a facade
- References:
- Is it a facade
- From: Sanjay
- Re: Is it a facade
- From: H. S. Lahman
- Re: Is it a facade
- From: Sanjay
- Re: Is it a facade
- From: H. S. Lahman
- Is it a facade
- Prev by Date: Re: Teaching OO
- Next by Date: Re: SQL
- Previous by thread: Re: Is it a facade
- Next by thread: Re: Is it a facade
- Index(es):