diff --git a/README.adoc b/README.adoc index 3a993e9..b88e5ec 100644 --- a/README.adoc +++ b/README.adoc @@ -19,7 +19,75 @@ CNF-01 is a library that provides immutable configuration for Java projects. Imm . command line arguments (`ArgsConfiguration`) - Default configurations in case the provided configurations from a source are not found or are otherwise broken (`DefaultConfiguration`) -== How to use +== A Word About Immutability + +Notable in CNF-01 is that the *configurations can not change after initialization*. + +For example, something might be added to the Java's System Properties even before calling `asMap()` on the `PropertiesConfiguration` object. However, this will not have effect on the `Configuration` object at all. *All the objects are immutable.* + +== How To Implement + +When implementing CNF-01 to a project, the point is to keep the main objects immutable and simple by moving the handling of configuration to their own objects. + +Follow these steps to implement CNF-01 in a Java project: + +* Identify the object that has to use configurations. +* You can define an interface for the factory objects that create the configured objects: ++ + +[,java] +---- +public interface Factory { + public T object(); +} +---- + +* Create a Factory object for the object that has to use configurations. ++ + +[,java] +---- +public final class ExampleFactory implements Factory { + + private final Map config; + + public ExampleFactory(final Map config) { + this.config = config; + } + + @Override + public Example object() { + // Parsing of values should be done here too if something else than String is needed + final String exampleType = config.get("example.type"); + final String exampleText = config.get("example.text"); + final Example example; + + if (exampleType.equals("good")) { + example = new GoodExample(exampleText); + } else { + example = new BadExample(exampleText); + } + + return example; + } +} +---- + +* Utilize the Factory object to get properly initialized objects with the configuration options. ++ + +[,java] +---- +PropertiesConfiguration config = new PropertiesConfiguration(); +Map configurationMap = config.asMap(); + +ExampleFactory exampleFactory = new ExampleFactory(configurationMap); +Example example = exampleFactory.object(); +---- + +* Create additional factories for other objects that require configurations. + +== How To Use // add instructions how people can start to use your project === Configuration @@ -88,7 +156,7 @@ try { Read Default Configuration section to see how default configurations can be used to avert the need for the try-catch. -=== Command line arguments +=== Command Line Arguments Command line arguments (or any `String[] args`) can be utilized as a configuration source with the `ArgsConfiguration` object. @@ -123,7 +191,7 @@ Configuration configuration = new EnvironmentConfiguration(); Map configMap = configuration.asMap(); ---- -=== Default configuration +=== Default Configuration Default configurations can be used in case the `asMap()` function throws `ConfigurationException`. If the function throws an exception, the defaults are used instead. Only `PathConfiguration` and `ArgsConfiguration` can currently throw an exception. @@ -145,20 +213,6 @@ DefaultConfiguration defaultConfiguration = new DefaultConfiguration( Map result = defaultConfiguration.asMap(); ---- -=== Configuration objects in your project - -The configuration Map from CNF-01 shouldn't be used directly in regular objects. It should only be passed to objects that are responsible for providing configured versions of other objects, in other words, Factories. The regular objects must not be configurable! - -Small example with an `Example` object: - -[,java] ----- -ExampleFactory exampleFactory = new ExampleFactory(configurationMap); -Example example = exampleFactory.example(); ----- - -Here, the logic for instantiating an `Example` is in the `ExampleFactory` object, which receives the configuration map from CNF-01 as a parameter. This ensures that the main object `Example` is as clear as it can be. - == Contributing // Change the repository name in the issues link to match with your project's name