开发者

Is this an anti-pattern?

开发者 https://www.devze.com 2022-12-17 09:25 出处:网络
The situation is this:You have two classes that both implement the same interface and both classes work together to complete some business process.

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 i开发者_JAVA技巧mplement 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?


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.


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().


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.


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).


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.


I wouldn't go so far as calling this an antipattern, but definitely a very poor implementation of an interface. ("Bad smell" as mentioned in this thread?)

I would even argue that these two getUser() methods should have different names, since although they have the same return values and no arguments, their "semantic" interfaces are clearly different:

  • localUserManager.getUser() expects something to be already on the queue
  • networkUserManager.getUser() does not.
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号