这是反模式吗?

时间:2010-01-20 22:09:14

标签: design-patterns oop anti-patterns

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

例如networkUserManagerlocalUserManager实施IUserManager,其方法为getUser()networkUserManager.getUser()发出请求以获取队列中的User并返回回复。 localUserManager.getUser()从队列中获取请求,在某个数据库中查找用户信息,然后使用用户数据进行回复。

当我看到与此类似的东西时,我不禁想知道这是不是很糟糕的设计。这是一个糟糕的设计,如果不是这样的例子,做这样的事情会是一个好主意吗?

6 个答案:

答案 0 :(得分:10)

对我来说闻起来很糟糕。当然,不同的类可能具有相同名称的方法,但如果它们都实现相同的接口,则假设它们将执行相同的操作。在这里,他们正在做相反的事情!

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

答案 1 :(得分:2)

您似乎在描述Decorator模式。在这种情况下,NetworkUserManager提供的功能超过LocalUserManager提供的功能。您没有说出您正在使用的语言,但此模式会出现在整个java.io包中。

另一方面,你对LocalUserManager.getUser()从队列中拉出消息的描述似乎是错误的 - 它是从NetWorkUserManager的工作方式向后的。如果LocalUserManager访问数据库,响应其他(可能是NetworkUserManagerService)调用getUser(),我会认为这是一个合适的装饰者。

答案 2 :(得分:1)

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

答案 3 :(得分:1)

在第一级,我认为它看起来像是一个基本的生产消耗队列。

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

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

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

答案 4 :(得分:1)

难闻的气味。您的界面定义了一个实现类同意遵循的合同。对于装饰器模式,您有多个类实现相同的合同,以便您可以将多个类一起捕捉。目前还不清楚这里发生了什么。

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

答案 5 :(得分:0)

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

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

  • localUserManager.getUser()期望队列中已存在某些内容
  • networkUserManager.getUser()没有。