【问题标题】:Violating Single Responsibility Principle and static methods [closed]违反单一职责原则和静态方法[关闭]
【发布时间】:2017-08-09 18:35:20
【问题描述】:

我有以下奇怪的问题。假设我们有一个 BlackJackGame 类,该类包含用于选举获胜者的 BlackJackGame 算法。同一个类虽然包含启动游戏的主要方法。这种主要方法在某种意义上违反了类的单一职责原则。此外,假设我们放置了另一种方法来以某种格式打印获胜者。可以说这个方法也是静态的,这个方法是否比main方法更违反责任原则。然后是什么,假设我们说它正在破坏。这是否意味着我们应该创造。现在假设我们还有一个实用方法,它解析来自命令行的参数并将其也放置为静态方法。

1 个 Main 类保存 Main 方法,1 个 Print 类保存 Print 方法,1 个 ArgumentParser 类保存一个静态方法来解析参数。

我会把它想象成这样:

public class BlackJackGame{

//returns the wining player
public Player play(Deck deck) {
  // some logic here
}
// deck is a class holding the Deck.
public static Deck parseArguments(String args[]) {
// logic here
}

public static void printPlayer(Player winner) {
// some logic here
}

public static void main(String args[]) {
    Deck deck = createDeck(args);
    BlackJackGame game = new BlackJackGame();
    Player winner = game.play(deck);
    printWinner(winner);

}

}

如果我们遵循单一职责原则。如果我们有,这是否重要,是否更正确:

public class BlackJackGame{

//returns the wining player
public Player play(Deck deck) {
  // some logic here
}
}

public class Main{

public static void main(String args[]) {
    Deck deck = DeckCreator.createDeck(args);
    BlackJackGame game = new BlackJackGame();
    Player winner = game.play(deck);
    Printer.printWinner(winner);

}

}

这不是有点极端吗????就像把单一职责带到四肢?

我问这个问题是因为它在我在这里请求的代码审查期间弹出。 codereview.stackexchange.com/questions/172469/… 老实说,我有点觉得单一责任原则有点极端。

【问题讨论】:

  • 我的意见 - 不要仅仅为了符合一些关于如何处理代码的命名一般准则而修改你的代码。
  • 我不会费心创建一个单独的课程,特别是对于像二十一点游戏这样的小规模游戏,但这个问题是基于意见的。请记住,编程中几乎没有绝对规则。
  • SRP 规则始终取决于上下文。有人会说一件事,另一件事会说不同
  • 讨论现代美国政治也是一个有趣的讨论,我们都可以从中学到很多东西。它也不属于这里。
  • ImO:SRP 是编码中非常重要的原则。但是每个单一职责都包含多个“子职责”。问题是,你能用一种简单的方式来制定一个模块的职责吗?还有其他模块的职责重叠吗?那么你应该重新考虑你的程序结构。

标签: java oop single-responsibility-principle


【解决方案1】:

一些随意的想法。

(a) 你能准确地确定一个班级有一些“责任”意味着什么吗???随后,如果(我怀疑)你所拥有的只是模糊的概念,没有任何形式上可观察/可测量的属性/特征来确定“责任”的含义,那么你怎么能像你所做的那样明确地说你所拥有的是违反吗?
(b) 如果您的应用程序变得足够大,或者您希望某些高级方式 (JMX) 与正在运行的应用程序进行交互,您将自然地拆分“MyEngine”和“StartMyEngine”。我想。如果您的应用程序不够大/高级/复杂/关键/...不够大,那么不进行拆分将无关紧要。
(c) 每个实例方法 M(args) 是静态方法 SM 的语义等价物,它具有所有 args 加上实例类型的参数。所以类 Foo 上的实例方法 M() 等价于静态方法 SM(Foo foo)。这开始揭示为什么您的静态打印方法“不属于”BlackJackGame 类:它没有任何 BlackJackGame 类型的参数,因此不能说与 BlackJackGame 相关BlackJackGame 类型的任何方式。从根本上讲,main(String[]) 当然也是如此,但在这种情况下,它的使用已经成为一种常见的模式,而且,必须在某个地方有一个入口点,否则没有 java 进程可以永远不要开始。

【讨论】:

  • 是的,我同意你的说法“这开始揭示为什么你的静态打印方法“不属于”BlackJackGame 类:它没有任何 BlackJackGame 类型的参数,因此不能说是相关的以任何方式到 BlackJackGame 类型。” 但是现在让我们想象这个方法被放置在 Player 而不是 BlackJackGame 中。那时会是什么样子
  • @AlexanderPetrov 显然 printPlayer 确实与 BlackJackGame 有一些关系,它需要一个由 BlackJackGame.play() 生成的 Player 实例 - 这显然是一种关系。当你认为这是正确的事情时,你会拆分代码,这可能很难决定,所以一些程序员喜欢拆分所有东西,但我认为你需要为该活动找到一个黄金比例。
  • “当时的情况如何”:看起来专业的挑剔者会开始用“这应该是一个实例方法”来唠叨你,甚至直接拒绝 当他们担任审查角色时您的代码。
  • @ErwinSmout 废话 :D :D :D :D
  • @Krzysztof Cichocki “黄金比例”:1.618 ??? (对不起,无法抗拒)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-14
  • 2010-10-22
相关资源
最近更新 更多