[java-design-patterns] Replacement of Enum and Factory patterns

Design pattern collection git note series.

In the introduction of abstract factory pattern

  1. Created the interface of KingdomFactory
  2. Implemented ElfKingdomFactory and OrcKingdomFactory respectively
  3. A corresponding enum is declared for each KingdomFactory
  4. The Factory that declares the KingdomFactory, returns the corresponding KingdomFactory according to the enum

This process was born in the era when Java was still a weak chicken language, and the language features were very weak. The problem is that KingdomFactory not only has a class (1), but also declares an enum (2) and adds it to the switch-case (3). There are three steps that have to be said to be troublesome. Before, my colleagues used Annotation-processing to automate steps 2 and 3 by generating code , which can greatly simplify the work, but isn't there a better way? The following will add a Kingdom class based on the original text to simplify the code.

If the module where the enum is located can depend on all KingdomFactoryImpl modules , directly use the enum to implement the KingdomFactory interface, and use lambda expressions to pass different implementations:

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

The above method is a real single-point modification, that is, adding a Factory only needs to add one item to this enum. However, with the introduction of dependencies, the interface implementations of ElfCastle could have been implemented by the existence of KingdomFactory without being exposed to the outside world.

If you want to hide all the implementations (actually I think this is the goal of the Factory), you can declare the Factory of the KingdomFactory as an enum and get rid of the third step.

public enum FOF implement KingdomFactory{
    ELF(new ElfKingdomFactory()),
    ORC(new OrcKingdomFactory());

    private KingdomFactory mFactory;
    FOF(KingdomFactory factory){
        mFactory = factory;
    }
    ...// proxy KingdomFactory的各种方法
}

This hides as much implementation, but with fewer modification points. It also avoids the trouble of annotation-processing and the embarrassment of blind-tuned code generation. In any case, it's still a lot better than the original model.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325837077&siteId=291194637