8

情况是这样的:您有两个类都实现了相同的接口,并且两个类一起工作以完成一些业务流程。

例如networkUserManager,并localUserManager实现IUserManager了一个方法getUser()networkUserManager.getUser()将获取 a 的请求放入User队列并返回回复。 localUserManager.getUser()从队列中获取请求,在某个数据库中查找用户信息,然后用用户数据进行回复。

当我看到类似的事情正在做时,我不禁怀疑这是否是糟糕的设计。这是一个糟糕的设计吗?如果不是,那么做这样的事情是个好主意的例子是什么?

4

6 回答 6

10

这对我来说很难闻。当然,不同的类可能有同名的方法,但是如果它们都实现相同的接口,那么就假设它们会做同样的事情。他们在这里做相反的事情!

也许这是我缺乏想象力,但我无法理解为什么这会是一个好主意。

于 2010-01-20T22:15:01.983 回答
2

您似乎在描述装饰器模式。在这种情况下,NetworkUserManager提供了比LocalUserManager. 你没有说你正在使用什么语言,但是这个模式出现在整个java.io包中。

另一方面,您对LocalUserManager.getUser()从队列中拉出消息的描述似乎是错误的——它与NetWorkUserManager工作方式背道而驰。LocalUserManager如果访问数据库,我会认为这是一个适当的装饰器,以响应NetworkUserManagerService调用getUser().

于 2010-01-20T22:15:40.357 回答
1

假设networkUserManager需要通过网络获取数据。因此,它将请求队列中的请求发送到具有该信息的网络服务器,并且localUserManager位于服务器上实际上为该请求提供服务。当您编写软件的单机版本时,最好保持它几乎相同,而不是无缘无故地花费开发人员的时间重写该区域。

于 2010-01-20T22:13:57.883 回答
1

在第一层,我认为它看起来像一个基本的生产-消费队列。

如果我理解正确,你有一个队列。进程 A,无论名称如何,都将事物放入队列中。进程 B,无论名称如何,都会从队列中取出并处理它们。

然后,您在该进程中添加了一个额外的次要复杂因素,A 希望被通知处理队列的结果。没什么大不了的。

如果这里有不好的做法,我会说是类的命名和公共接口的使用。他们似乎不执行类似的任务。似乎他们都在同一个类/对象(这个队列)上运行。

于 2010-01-20T22:20:22.080 回答
1

臭气。你的接口定义了一个实现类同意遵循的契约。在装饰器模式的情况下,您有多个实现同一个契约的类,以便您可以将多个类捕捉在一起。目前尚不清楚这里是否发生了类似的事情。

这里的问题是“getUser”是否是一个有意义的抽象,以及它是否封装了你的逻辑,这在我看来就像分层访问。我认为它隐藏的比它照亮的更多。例如,java.io 装饰器(大多数情况下)可以以任何顺序拼接在一起;鉴于您描述的分层访问, LocalManager.getUser(NetworkManager.getUser()) 有意义,而 NetworkManager.getUser(LocalManager.getUser()) 没有。

于 2010-01-20T22:26:28.417 回答
0

我不会将其称为反模式,但绝对是一个非常糟糕的接口实现。(这个帖子中提到的“难闻的气味”?)

我什至认为这两个 getUser() 方法应该有不同的名称,因为尽管它们具有相同的返回值且没有参数,但它们的“语义”接口明显不同:

  • localUserManager.getUser() 期望某些东西已经在队列中
  • networkUserManager.getUser() 没有。
于 2010-01-20T22:38:25.563 回答