RE: Myth of loose coupling

> > What about DESIGN OPTION C:
> >
> > Operation #1: processVisaRegistration( xmlVisaOnlyForm )
> > WebQueue #1: https://www.verisign.com/payflow/visaOnly
> > Operation #2: processVisaAndMasterCard( xmlVisaAndMasterCard
> > ) WebQueue #2: https://www.verisign.com/payflow/visaAndMasterCard
> >
> > Or DESIGN OPTION D:
> >
> > Operation #1: processCreditCard( xmlCreditCard )
> >
> I am not sure I understand what Option C and D are. Could you please
> elaborate?

In option C I understand that not all clients require the same set of
operations, so I decouple them. That way, a change to one operation (and its
definition) would only affect clients using that operation. And I can
support multiple versions as I keep evolving the interface, e.g.:

Operation #3: processVisaAndMasterCard( xmlVisaAndMasterCardV2
WebQueue #3: https://www.verisign.com/payflow/visaAndMasterCardV2

In option D I understand that I can hide the specifics by creating a generic
operation. My operation supposedly deals with any credit card in the same
way. Right now it only supports Visa and Matercard, but when I add support
for Discover or Visa V2.0, I simply extend the implementation (and schema)
while retaining backward compatibility.

Option D is not always valid, but a good design choice. You will see a lot
of interfaces that don't change that often. Come to thing about it, credit
card processing is one such example. Though it does not invalidate the point
you are making, which is conceptual, so it's fair to assume it would change
for the purpose of the argument.

Option C simply created a separation along the same lines we would use WSDL
today. If two operations are tightly related to each other (e.g.
processVisaRegistration, queryVisaRegistration) they could be made part of
the same service. If the operations are not tightly related (e.g. Visa vs
MaterCard), they are exposed as separate interface, even if there is a
single implementation behind.


> > On the other hand if an architecture forces you to always do
> > the right thing, then I would elect not to use it. What I
> > learned by experience is: if you can't abuse it, it's pretty
> > much useless.
>
> Architectures provides constraints. As a developer you can decide to
> work around that constraint and loose its benefits: In this case you
> could have a dispatcher behind the queue and encode the method in the
> XML document or the header (emulation of case A).

My point exactly. But we have to understand that there are two architectures
here. The one that is right for me, and the one that gives me an option.

In some applications the best architecture is to use asynchronous messaging.
In some applications the best architecture is to use synchronous messaging.
In some applications you combine both, for example, commerce applications
use synchronous for the catalog part and asynchronous for the order
processing. The ratio depends on the catalog/order ratio.

But to be able to select the right architecture for my particular
application I need to first start with a more generic architecture that
gives me more options. An architecture that lets me do both synchronous and
asynchronous things, and I select the constraints that are best for my
particular application.

We see the same thing with IP. You have UDP and you have TCP. Some
applications use only UDP, others use only TCP, some do so in combination.
Some uses of UDP are purely synchronous (e.g. reliable IP multicast). Some
uses of TCP are purely asynchronous (e.g. SMTP). IP doesn't tell you what to
use, it gives you options, but the particular application you use requires
an architecture that may elect to use one protocol over the other.


> The counter argument to C would be to find class of use cases where
> being able to expose/group a set of non-generic methods as part of a
> service reduced the cost of integrating that service into client
> applications or maintaining, managing and updating that service.

Here are two good examples from different sides of the specturm.

The first is credit card processing. The means by which you process a credit
card transaction has not changed for decades. And even with the addition of
smart credit cards and odd-shaped credits cards (like the new Discover), it
still works exactly the same way. If a WSDL was defined two decades ago it
would still be valid.

The second is generating an invoice. The purchase order management
application is a client of this service, and in turn a provider of a service
to a larger audience (buyers). The interface has one client and one
provider. Any change is going to affect the implementation (service
provider) more than the client and only one client. So there's little to be
gained form working too hard to abstract it.

Abstraction and decoupling, or people would be doing them all the time and
we would not be having this discussion. They need an ROI. If you can prove
that the cost of developing an abstracted/decoupled interface is lower than
the cost incurred by change management, you have a compelling argument
(positive ROI). On the other hand, if you can prove that there is no change
management you are wasting resources with abstraction/decoupling (negative
ROI).

For a lot of applications out there changes to the interface are unlikely.
Usually because enough thought has been put into the API to make sure it
meets all future requirements that you would not consider changing it. If
the API is fixed, you gain little from adding abstraction.

arkin

>
> Edwin
>
>

Received on Tuesday, 7 January 2003 03:10:44 UTC