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