0

as DIP says, "depend upon abstractions, not concretions." so I code like part1. When I want to use ElfBlackSmith, I code "BlackSmith elf = new ElfBlackSmith()".The problem is anytime I want a new ElfBlackSmith, I need to create a new same object. And it seems like ElfBlackSmith can be a singleton. And in some framework like Playframework, it can be done like part2.
part1 satisfies the DIP but it seems like there has some waste;
part2 is direct and it follows the change of java version that makes methods static but doesn't satisfy the DIP and makes it difficult to change;
Or, in my opinion, put a factory in part1's ElfBlackSmith to make it a singleton and thus part1 satisfies both. But I haven't seen anyone code like this. in short, there are three ways, and which one is better?

part1:

Interface BlackSmith{ int make(); }         
class ElfBlackSmith implements BlackSmith{ int make( return 1;)}  
class OrcBlackSmith implements BlackSmith{ int make( return 2;)}

part2:

class ElfBlackSmith { static int make( return 1;)}  
class OrcBlackSmith { static int make( return 2;)}

part3:

Interface BlackSmith{ int make();}
class ElfBlackSmith{ 
    private static final ElfBlackSmith INSTANCE = new ElfBlackSmith();
    public static ElfBlackSmith getInstance(){return INSTANCE;} 
    int make( return 1;)
}

part1 usage:

BlackSmith elf = new ElfBlackSmith();
elf.make();

part2 usage:

ElfBlackSmith.make();

part3 usage:

BlackSmith elf = ElfBlackSmith.getInstance();
elf.make();
japhy
  • 138
  • 1
  • 6
  • It is not clear what are you talking about. This code examples does not contain neither dependency injection, nor singletons. – Alexei Kaigorodov Feb 18 '19 at 08:10
  • @AlexeiKaigorodov I guess he is talking about *dependency inversion* here. But yes, the OP should clarify that part. – GhostCat Feb 18 '19 at 08:11

1 Answers1

1

I don't see that there is a conflict.

Those are simply two independent concepts. Dependency Inversion guides how you design your code to avoid dependencies going in the wrong direction, which you need to enable proper code reuse for example.

Singleton on the other hand is completely independent of that: it simply says: there is only one instance of some "thing".

Thus there is no "better" here. From that point of view, your question is similar to: "what is better, green or apples?"

GhostCat
  • 137,827
  • 25
  • 176
  • 248
  • I'm sorry about my poor words, but I just want to figure it out. Talk about this example, I invoke the ElfBlackSmith by its abstraction, so I don't have to change the type when I change ElfBlackSmith to OrcBlackSmith, which makes my code stronger. It follows the DIP moving the dependency from implement to abstraction. – japhy Feb 18 '19 at 08:38
  • @japhy I think you are overcomplicating things. And please note: your example is merely about "programming against an interface" ( see https://stackoverflow.com/questions/1992384/program-to-an-interface-what-does-it-mean for example ). DIP is "more" than just using interfaces. Interfaces are a lower level construct, DIP is rather a pattern that guides the architecture of your overall design! – GhostCat Feb 18 '19 at 08:41
  • But why should I create a new object anyTime I use it. ElfBlackSmith will never change and is just like a singleton. Look at part2, I don't need to create new objects anymore by making methods static. But that changes the dependency relationship. – japhy Feb 18 '19 at 08:48
  • @japhy You overlook that you *avoid* using static as far as possible. When you have an interface, you are completely decoupled from the implementation. When you invoke a static method, you **kill** polymorphism, and worse, you directly couple the caller to the class it calls a method on. The rule of thumb is: you **only** use static methods when there are good reasons to do so, otherwise you avoid it, as it comes with a long lost of problems. And the question whether you have to create a new object or not, that again has *nothing* to do with DIP or interfaces or whatnot. – GhostCat Feb 18 '19 at 08:52
  • Thanks for your patience! I didn't know how to explain my question clearly and it made you confusing about what I was thinking. It's the Paly 1.0 that confused me so much, but now I find my answer in Play 2 after you pointed my mistake. Anyway, thanks a lot! – japhy Feb 19 '19 at 02:52