设计模式合集git笔记系列。
abstract factory模式的介绍中
- 创建了KingdomFactory的接口
- 分别实现了ElfKingdomFactory和OrcKingdomFactory
- 为每个KingdomFactory声明了相应的enum
- 声明了KingdomFactory的Factory,根据enum返回对应的KingdomFactory
这个流程,诞生自Java还是弱鸡语言的时代,语言特性很弱。问题就在于KingdomFactory不仅有一个类(1),还要再声明一个enum(2),并添加到switch-case中(3),共三步不得不说怪麻烦的。之前同事曾经通过Annotation-processing把2、3步通过生成代码自动化掉,可以极大的简化工作,但是不是还有更好的办法?下面会在原文基础上增加一个Kingdom类,用来简化代码。
如果enum所在module能够依赖所有KingdomFactoryImpl的module,直接用enum实现KingdomFactory接口,使用lambda表达式传递不同实现:
public enum Factory implement KingdomFactory{
ELF(()->new ElfCastle(), ()-> new ElfKing(), ()-> new ElfArmy()),
ORC(...);
private Function<Void, Castle> mCastleCreator;
private Function<Void, King> mKingCreator;
private Function<Void, Army> mArmyCreator;
Factory(Function<Void, Castle> castleCreator, Function<Void, King> kingCreator, Function<Void, Army> armyCreator){
mCastleCreator = castleCreator;
...
}
public Kingdom create(){
return new Kingdom(mCastleCreator.create(), mKingCreator.create(), mArmyCreator.create());
}
}
上面的方法是真正的单点修改,即增加一个Factory只需要在这个enum里增加一项即可。但是,引入了依赖,ElfCastle这些接口实现本来可以通过KingdomFactory的存在而不对外暴露。
如果希望隐藏所有实现(其实我看来这个是Factory的目标),可以把KingdomFactory的Factory声明成enum,干掉第三步。
public enum FOF implement KingdomFactory{
ELF(new ElfKingdomFactory()),
ORC(new OrcKingdomFactory());
private KingdomFactory mFactory;
FOF(KingdomFactory factory){
mFactory = factory;
}
...// proxy KingdomFactory的各种方法
}
这样可以隐藏同样多的实现,但减少了修改点。也避免了annotation-processing的麻烦和盲调生成代码的尴尬。不论如何,比原始的模式还是好不少的。