Search code examples
javaoopsingle-responsibility-principle

Violating Single Responsibility Principle and static methods


I have the following strange question. Lets say we have a class BlackJackGame and this class contains the BlackJackGame algorithm for electing a winner. Same class though contains the main method for starting the game. This main method in some sense is violating the principle of Single Responsibility for a class. In addition lets say we place one more method for printing the winner in some format. Lets say this method is also static, is this method breaking the responsibility principle any more than the main method. And then what, lets say we say that it is breaking. Does this mean we should create. Now lets presume we also have a utility method that parses the arguments coming from the command line and place it as static method as well.

1 Main class to hold the Main method, 1 Print class to hold the Print method and 1 ArgumentParser class holding a single static method to parse the arguments.

I will visualize it like this:

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);

}

}

If we follow the Single Responsibility Principle. Does it reay matter and is it more correct if we had:

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);

}

}

Isn't this a little bit extreme ???? Like Single Responsibility taken into extremities ?

I am asking this question because it popped up during a code review I requested here. codereview.stackexchange.com/questions/172469/… I kind of have feeling that it is a bit Single Responsibility Principle taken into extremeties to be honest.


Solution

  • A few random thoughts.

    (a) Can you even pin down precisely what it means for a class to have some "responsibility" ??? And subsequently, if (as I suspect) all you have is vague notions without any formally observable / measurable properties / characteristics to pin down the meaning of "responsibility", then how can you say as unequivocally as you do that what you have is violating it ?
    (b) If your application grows large enough or you want certain advanced means (JMX) to interact with your running application, you will split "MyEngine" and "StartMyEngine" just naturally as you go. Methinks. If your application is not large/advanced/complex/critical/... enough, then not having that split will not matter much.
    (c) Every instance method M(args) is the semantic equivalent of a static method SM that has all of args plus an argument of the type of the instance. So an instance method M() on class Foo is equivalent to a static method SM(Foo foo). This starts to reveal why your static print method "does not belong" in class BlackJackGame : it does not have any argument of type BlackJackGame and therefore cannot ever be said to relate in any way to the BlackJackGame type. Fundamentally speaking the same holds of course for main(String[]) but in that case its usage has become a common pattern, and moreover, there has to be an entry point somewhere somehow otherwise no java process could ever get started at all.