views:

302

answers:

6

The situation is this: You have two classes that both implement the same interface and both classes work together to complete some business process.

For example networkUserManager and localUserManager implement IUserManager which has a method getUser(). networkUserManager.getUser() puts a request to get a User on the queue and returns the reply. localUserManager.getUser() gets a request off the queue, finds the user information in some database, and then replies with the user data.

When I saw something similar to this being done, I couldn't help but wonder if this was bad design. Is this bad design and if not what is an example where doing something like this would be a good idea?

+1  A: 

Suppose networkUserManager needs to get the data from across a network. So it puts a request on the request queue to the network server which has that information, and localUserManager sitting on the server actually services that request. When you write a single-machine version of the software, it's probably better to keep it pretty much the same than to spend developer time rewriting that area for no reason.

Anon.
+11  A: 

That smells pretty bad to me. Different classes may have methods with the same name, of course, but if they are both implementing the same interface, then there is an assumption that they will be doing the same thing. Here they are doing opposite things!

Perhaps it's a lack of imagination on my part, but I cannot fathom why that would ever be a good idea.

Jeffrey L Whitledge
+1 - This is what I was thinking when I first saw the question, but couldn't put into words. Thanks =)
Erik Forbes
im not sure about "opposite" things.. they both return the same object.. I should have said localusermanager returns the User and in addition replies over the queue with a User so that way networkusermanager can also return the User... but i agree it smells
insipid
+1  A: 

You seem to be describing the Decorator pattern. In this case, the NetworkUserManager provides additional functionality over that provided by the LocalUserManager. You don't say what language you're using, but this pattern appears throughout the java.io package.

On the other hand, your description of LocalUserManager.getUser() pulling a message off the queue seems wrong -- it's backward from the way NetWorkUserManager works. I would see this as being a proper decorator if LocalUserManager accessed the database, in response to something else (perhaps a NetworkUserManagerService) invoking getUser().

kdgregory
OK, downvoter, got a reason?
kdgregory
I didn't downvote but I believe decorator adds something more to a method while keeping the core functionality the same. So if one were to decorate a GetUser() which returns just a User it might be to add a log entry saying that User was gotten.
wheaties
Yes, that's exactly what it does. Which was pretty much the point of my first paragraph.
kdgregory
+1 very good point.
insipid
I have to agree that this could be interpreted as an improperly done decorator. networkusermanager looks like it wants to provide network functionality for localusermanager.. but localusermanager is already confusingly consuming from the queue.
insipid
Bad code isn't an anti-pattern, it's just bad code :-)
kdgregory
It does sound like the people implementing these objects need to have a conversation with the person who defined the interface: it sounds like `LocalUserManager` is going beyond the interface's conception of the method. Hopefully they're not the same person.
kdgregory
+1  A: 

At the first level, I think it looks like a basic produce-consume queue.

If I understand you correctly, you have a queue. Process A, regardless of name, puts things on the queue. Process B, regardless of name, takes things off the queue and processes them.

Then you add an additional minor complicating factor in that process A wants to be notified of the results of processing the queue. No big deal.

If there is a bad practice here, I would say it is the naming of the classes and the use of the a common interface. They don't seem like they perform similar tasks. It seems like maybe they both operate on the same class/object (this queue).

Keith Hoffman
+1  A: 

Bad smell. Your interface defines a contract that implementing classes agree to follow. In the case of a decorator pattern, you have multiple classes implementing the same contract so that you can snap multiple classes together. It's not clear that there's anything like that going on here.

The question here is whether "getUser" is a meaningful abstraction, and whether it encapsulates your logic, which looks to me like tiered access. I'd argue that it hides more than it illuminates. For example, java.io decorators can (mostly) be snapped together in any order; Given the tiered access you're describing, LocalManager.getUser(NetworkManager.getUser()) makes sense, while NetworkManager.getUser(LocalManager.getUser()) doesn't.

Steve B.
A: 
JimSizzle