【问题标题】:How to respect single responsability principle in this situation using java?在这种情况下如何使用 java 尊重单一责任原则?
【发布时间】:2018-03-26 08:16:33
【问题描述】:

假设我有三个频道(它们只是一个概念而不是一个类):ABC

每个频道都有一些我想要处理的对象,它们之间是不同的。假设:

  • 频道AA1A2A3
  • 频道BB1B2B3
  • 频道CC1C2C3

所有通道都有一个通用的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(这也允许您创建一个处理器可以处理所有用于记录或其他类似目的的任务)。

标签: java solid-principles single-responsibility-principle


【解决方案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> {
    //...
}

【讨论】:

  • 我想我没有正确解释我的情况。所有的对象都是不同的,通道作为实体没有意义,它只是一个概念。我添加了一个示例以使其更直观,希望对您有所帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-08-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-11
相关资源
最近更新 更多