Re: interfaces in APIs
From: H. S. Lahman (h.lahman_at_verizon.net)
Date: 03/25/05
- Next message: Laurent Bossavit: "Re: Design is intent."
- Previous message: H. S. Lahman: "Re: Attaching a behavior only to multiple classes."
- In reply to: Paul MG: "interfaces in APIs"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Date: Fri, 25 Mar 2005 21:17:08 GMT
Responding to MG...
My comments below assume that your application is more that simply a
pipeline between the RDB and UI doing basic USER/CRUD processing. If
your application is such, then I would advise using one of the many
"canned" RAD layered model infrastructures that hide these sorts of
problems in the layer interfaces. If your application has more complex
business processing than that, then you can continue to read...
> I have the following architectural problem. I have designed a service
> layer for my application which consists of a number of domain objects,
> and a service object to create, manage and store them. The service and
> domain objects are all specified as interfaces. The purpose of those
> interfaces is to specify exactly what the client code (the GUI layer)
> can expect of, and do to, those domain objects.
The GUI layer deals with a very different problem space than the
business problem the application is solving. The subject matter of the
GUI is data display and the dominant paradigm is Window/Control. It is
dealing with the user's or GUI Designer's view of the application.
As such the GUI layer is really not interested in the business semantics
of the data displayed. Business semantics like Account and Balance are
relegated to text strings used for labels in various GUI display artifacts.
The corollary is that objects in the GUI layer have no need to know
about objects in business domain layer. Your problems with downcasts
are directly related to the object-to-object coupling across the layer
boundary. If you do a better job of hiding the implementations of each
layer, those problems will go away.
The short answer solution to properly decoupling the layer
implementations is the GoF Facade pattern. Encapsulate both layers'
contents with a single interface that does not reflect any particular
objects that it contains. Then let the interface class' implementation
dispatch incoming messages to the relevant classes that implement the layer.
To make that work you need two things. First, is a mapping of identity
across the layer boundary so that each side can interpret the message
content properly in a manner appropriate to their subject matter. That
is, you need some way for the Balance attribute of an Account object on
the business side to map to the right Control instance associated with
the right Window instance on the GUI side.
The second thing you need is a pure message-based data transfer
interface. That is, a generic {message ID, <data packet>}. This will
work better if the data in <data packet> is by value rather than by
reference. (The reference exposes the sender implementation.) The
interfaces of the Facade classes should be designed around this
paradigm. Also, the interface should reflect the sender context. (The
transformation to the receiver context is handled by implementation of
the receiving Facade class.)
Obviously there is a price one pays for this decoupling. Any
communication involves encoding a message on the sender side and
decoding the message on the receiver side. However it is a very small
price to pay for the benefits...
-- The only shared semantics across the layer boundary is the definition
of the message itself and that is interpreted uniquely on each side.
This provides "firewall" decoupling of the implementations. So...
-- ...you can change the implementation of either layer without touching
the other layer so long as the semantics of communication does not change.
-- If the interface must be changed, it is relatively easy to do because
the "glue" code is isolated to the Facade implementation and the
communication paradigm is fixed (i.e., the dispatch paradigm is always
the same so one tends to modify the layer implementation in the same
manner).
-- Because each layer deals with a unique subject matter, those
solutions are more focused and the decoupling tends to result in simpler
layer implementations. That's just because there are no distractions
with peripheral "boilerplate" processing.
-- The isolation of subject matters makes it easier to recognize
invariants of the subject matter for more elegant solutions. An example
is that the dominant paradigm to abstract for the GUI display is
Window/Control.
-- Subject matter focus and encapsulation behind pure message interfaces
often results in large scale reuse. If the GUI is done in terms of
Window/Control, then it can easily be reused across applications by
defining different configuration data (e.g., text labels). Note that
this is exactly what commercial GUI builders do.
I have more details on application partitioning techniques on my blog,
if you are interested in more detail.
*************
There is nothing wrong with me that could
not be cured by a capful of Drano.
H. S. Lahman
hsl@pathfindermda.com
Pathfinder Solutions -- Put MDA to Work
http://www.pathfindermda.com
blog: http://pathfinderpeople.blogs.com/hslahman
(888)OOA-PATH
- Next message: Laurent Bossavit: "Re: Design is intent."
- Previous message: H. S. Lahman: "Re: Attaching a behavior only to multiple classes."
- In reply to: Paul MG: "interfaces in APIs"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Relevant Pages
|