Creator - examples

Printer-friendly versionPrinter-friendly version
How to use the Creator framework

 

We want the (behavior) implementation of a Foobar, either ConcreteFoobar1 or ConcreteFoobar2, to be choosen by a context, which is the main reason to use a creational framework or creational pattern after all.

The context can be technical e.g. represents if the current process is running in a test environment or in a production environment, so either a test implementation or a production implementation will be choosen, but the context can also be domain specific, to dispatch the behavior by domain specific criteria. For purposes of this example we choose the following context properties:

  • environment: "DEV", "TEST", "PROD".
  • product type: "BAR1", "BAR2".
  • customer category: "GOLD", "SILVER", "BRONZE".

 

and for the extra thrill a dynamic property:

  • current month: 0-11 .  (foobar comes in seasonal flavors   wink   )

 

This Creator framework promises that you can use any arbitrary object or set of values as context. That is true, but under one condition: the context object must implement the marker interface CreationContext:

public interface CreationContext<F extends Factory> {}

(Sure, the framework could work fine without that marker interface, but on the long run this interface will rescue the maintainability of the project in terms of finding each and every context used...)

Note: the CreationContext is bound to a factory type. Remember we use abstract extra levels of factories and creators to represent segregated areas. For congruence with these areas we set that upper bound accordingly.

Now, we could create or modify a class to implement the marker interface with the context properties. Fortunately, the Creator framework provides already very convenient ways to define a creation context with the following classes:

  • GenericCreationContext (takes any set of given parameters, which will be evaluated equally)
  • RankingCreationContext (takes any set of given parameters, which will be evaluated by their rank - first parameter wins over the second, the second over the third etc.)

 

More CreationContext types can be derived from that, but for our example we just implement the following context:

CreationContext<Domain1Factory> context = new GenericCreationContext<>(
    getEnvironment(),
    getProductType(),
    getCustomerCategory(),
    getCurrentMonth()
);

But wait... where shall we implement that? Well, we really do not want to implement that in every client class and we also try to avoid to pass it to every client class. We rather implement it once in an appropriate place of our system where the context will be updated on the respective events, e.g. when the user changes the product type, and from there we set the context on each update as default context for a creator type (here Domain1Creator) into the FactoryContext. This way the Creator framework will always pick the right context even if the client itself has no knowledge about it! We might use instead a context that updates automatically by the use of references and set that context just once as the default context. This implementation depends completely on the architecture of our system.

 

 

Seiten