在这种情况下如何使用 java 尊重单一责任原则?
Posted
技术标签:
【中文标题】在这种情况下如何使用 java 尊重单一责任原则?【英文标题】:How to respect single responsability principle in this situation using java? 【发布时间】:2018-03-26 08:16:33 【问题描述】:假设我有三个频道(它们只是一个概念而不是一个类):A
、B
、C
。
每个频道都有一些我想要处理的对象,它们之间是不同的。假设:
频道A
有A1
、A2
和A3
。
频道B
有B1
、B2
和B3
。
频道C
有C1
、C2
和C3
。
所有通道都有一个通用的save
方法来存储这些对象。
我的方法是使用所有通道方法的接口ATaskProcessor
:
a1Process(arguments)
a2Process(arguments)
a3Process(arguments)
b1Process(arguments)
b2Process(arguments)
b3Process(arguments)
c1Process(arguments)
c2Process(arguments)
c3Process(arguments)
然后是该接口的实现,其中实现了所有这些方法和一个公共save
,以便存储处理的对象。我需要为每个对象使用不同的过程,但我使用相同的 save
。
该方法的目标是对所有对象重用相同的save
方法,但这不尊重单一职责原则并且不可扩展。
我曾想过将不同包中的通道分开,这会减少我的课程代码,但我会重复代码,我也不会尊重这个原则。
如何才能尊重单一责任原则并尽可能少地重复代码?
例子:
public interface ATaskProcessor
void a1Process(arguments);
void a2Process(arguments);
void a3Process(arguments);
void b1Process(arguments);
void b2Process(arguments);
void b3Process(arguments);
void c1Process(arguments);
void c2Process(arguments);
void c3Process(arguments);
public class taskProcessor implements ATaskProcessor
void a1Process(arguments) ...
void a2Process(arguments) ...
void a3Process(arguments) ...
void b1Process(arguments) ...
void b2Process(arguments) ...
void b3Process(arguments) ...
void c1Process(arguments) ...
void c2Process(arguments) ...
void c3Process(arguments) ...
void save() ...
谢谢。
【问题讨论】:
您能否详细解释一下这些渠道是什么以及这些任务是什么?目前我们唯一可以肯定的是,你提出的设计看起来很笨拙,而且只要我们了解你想要什么,肯定有更好的方法来做你想做的事。 我想把它泛化,但是好的,我会解释确切的情况。例如,渠道是谷歌、必应和亚马逊。我有以下对象:帐户、活动和指标。所以我实际上从这些渠道下载信息并处理它们,以便将其保存在数据库中。话虽如此,我对每个渠道都有一个 accountProcessor、campaignProcessor 和 metricsProcessor(我无法统一它们,因为它们需要不同的流程)。对@Kayaman 有帮助吗? 是的,它描绘的画面更加清晰。是否可以将一些行为卸载到 Task 对象本身,而不是让 TaskProcessor 尝试做很多事情?我还尝试使 TaskProcessor 通道具体化,因为虽然所有通道可能非常相似,但它们仍然有自己独特的来源。 所以你的意思是我应该创建一个 GoogleTaskProcessor、BingTaskProcessor 和 AmazonTaskProcessor(每个都有 3 种方法:帐户、活动和指标处理器)?这些对象只有我必须处理的属性,没有别的。所有的逻辑都在 taskProcessor 中,我认为应该是这样的。 是的,我就是这个意思。如果存在可以共享的行为,您可以让它们共享一个超类,但没有理由试图强迫 Bing 和 Google 采用相同的模式。该接口可能像 Tobb 的示例中那样是通用的,如果您想懒惰地找到一个处理器,您可以实现类似boolean isApplicable(Task)
的方法,如果该处理器可以处理该任务,它将返回 true(这也允许您创建一个处理器可以处理所有用于记录或其他类似目的的任务)。
【参考方案1】:
这确实有点取决于 A、B 和 C 以及 1、2 和 3 之间的关系(A1 和 B1 是否有点相同?)
但如果我做一些假设,解决这个问题的一种方法是通过继承和泛型:
public abstract class Task
public class A extends Task
public class B extends Task
public class C extends Task
public <T extends Task> interface TaskProcessor<T>
process1(T task);
process2(T task);
process3(T task);
public class AProcessor implements TaskProcessor<A>
//...
public class BProcessor implements TaskProcessor<B>
//...
public class CProcessor implements TaskProcessor<C>
//...
那么如果你想引入另一种任务类型D,你只需要:
public class D extends Task
public class DProcessor implements TaskProcessor<D>
//...
【讨论】:
我想我没有正确解释我的情况。所有的对象都是不同的,通道作为实体没有意义,它只是一个概念。我添加了一个示例以使其更直观,希望对您有所帮助。以上是关于在这种情况下如何使用 java 尊重单一责任原则?的主要内容,如果未能解决你的问题,请参考以下文章