views:

76

answers:

1

Hi,

I see the following situation quite often in system design and I feel it is an anti-

pattern, what is your take?

I call it the doAnything() method, where on an interface for a component much of the

detail of the contract of the component is hidden by having overly generalised

methods.

The extreme degenerate case of this is when the interface has one method called

something like "doStuff" that takes the most general parameter type available and

returns the most general parameter type possible, for e.g. in JAVA:

public Object doStuff(Object params)

If you see this on the interface it is also a good indicator that there may be poor

separation of concerns in the implementation with lots of conditional code.

Of course there are many degrees of this, and sometimes it is very slight e.g. the

method name might be very explanatory, the return parameter may well be very

explicit and there is only slight variability implicit in the definition:

public Transaction makePayment(boolean isCreditCard)

which could be:

public Transaction makePaymentWithCreditCard();
public Transaction makePaymentWithCash();

What I see underneath all of this is a general principle of needing to justify why

the explicitness of the contract is being traded off. I believe that any

generalisation of a contract adds a risk of Separation of Concerns being threatened.

So it needs to be done explicitly as it is a trade-off and what you get for it needs

to be worth what you have lost.

IT is interesting now to consider the following design concerns in this light:

The Command Pattern:

This can look a lot like a do anything method, but usually the individual command

instances are fairly explicit in how they work and it also doesn't usually imply

conditional code with poor separation of concerns.

Most importantly though is that usually there is a major functional gain such as Undo

being implemented. If this is not the case, then one should question why it is being

used.

Late Binding:

If the parameters are very generalised this implies much later binding, in JAVA it

will be done with RTTI for instance. This too is a cost.

Aspect like behaviour:

I have seen this technique used recetly to implement "Aspect Like Behaviour" in an

environment that did not have native support for that (calling Stored Procs in

Oracle). The doAnything() method in this case did logging and authentication and then

delegated the call on to the actual method (Stored Proc). So on the plus side somewhere in the design there is still a place to define the contract, although it is now bound much later.

Soap:

This is used for inter-component calls and in some sense it can be seen as a generic

method that takes XML, processes it and returns XML. However much mitigation has been

done to make the contract explicit with other mechanisms (WSDL), and here

late-binding is in fact desired as these are inter-component calls which should be

late bound to achieve independent replace-ability.



Shoo-wee, A bit of an essay hey.

Cheers A

A: 

I guess he's new to stackoverflow

Xinxua
This should really be a comment, not an answer...
lc