情况是这样的:你有两个实现相同接口的类,两个类一起工作以完成一些业务流程。
例如networkUserManager
和localUserManager
实施IUserManager
,其方法为getUser()
。 networkUserManager.getUser()
发出请求以获取队列中的User
并返回回复。 localUserManager.getUser()
从队列中获取请求,在某个数据库中查找用户信息,然后使用用户数据进行回复。
当我看到与此类似的东西时,我不禁想知道这是不是很糟糕的设计。这是一个糟糕的设计,如果不是这样的例子,做这样的事情会是一个好主意吗?
答案 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()方法应该有不同的名称,因为虽然它们具有相同的返回值而没有参数,但它们的“语义”接口明显不同: