Skip to content

Commit 7e12f16

Browse files
authored
Add "How to implement" to README (#31)
* Add "How to implement" to README * Fix headings, add list continuation to code blocks * Add empty line before code blocks * Move "How To Implement" to be before "How To Use"
1 parent 35d44df commit 7e12f16

1 file changed

Lines changed: 71 additions & 17 deletions

File tree

README.adoc

Lines changed: 71 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,75 @@ CNF-01 is a library that provides immutable configuration for Java projects. Imm
1919
. command line arguments (`ArgsConfiguration`)
2020
- Default configurations in case the provided configurations from a source are not found or are otherwise broken (`DefaultConfiguration`)
2121

22-
== How to use
22+
== A Word About Immutability
23+
24+
Notable in CNF-01 is that the *configurations can not change after initialization*.
25+
26+
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.*
27+
28+
== How To Implement
29+
30+
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.
31+
32+
Follow these steps to implement CNF-01 in a Java project:
33+
34+
* Identify the object that has to use configurations.
35+
* You can define an interface for the factory objects that create the configured objects:
36+
+
37+
38+
[,java]
39+
----
40+
public interface Factory<T> {
41+
public T object();
42+
}
43+
----
44+
45+
* Create a Factory object for the object that has to use configurations.
46+
+
47+
48+
[,java]
49+
----
50+
public final class ExampleFactory implements Factory<Example> {
51+
52+
private final Map<String, String> config;
53+
54+
public ExampleFactory(final Map<String, String> config) {
55+
this.config = config;
56+
}
57+
58+
@Override
59+
public Example object() {
60+
// Parsing of values should be done here too if something else than String is needed
61+
final String exampleType = config.get("example.type");
62+
final String exampleText = config.get("example.text");
63+
final Example example;
64+
65+
if (exampleType.equals("good")) {
66+
example = new GoodExample(exampleText);
67+
} else {
68+
example = new BadExample(exampleText);
69+
}
70+
71+
return example;
72+
}
73+
}
74+
----
75+
76+
* Utilize the Factory object to get properly initialized objects with the configuration options.
77+
+
78+
79+
[,java]
80+
----
81+
PropertiesConfiguration config = new PropertiesConfiguration();
82+
Map<String, String> configurationMap = config.asMap();
83+
84+
ExampleFactory exampleFactory = new ExampleFactory(configurationMap);
85+
Example example = exampleFactory.object();
86+
----
87+
88+
* Create additional factories for other objects that require configurations.
89+
90+
== How To Use
2391

2492
// add instructions how people can start to use your project
2593
=== Configuration
@@ -88,7 +156,7 @@ try {
88156

89157
Read Default Configuration section to see how default configurations can be used to avert the need for the try-catch.
90158

91-
=== Command line arguments
159+
=== Command Line Arguments
92160

93161
Command line arguments (or any `String[] args`) can be utilized as a configuration source with the `ArgsConfiguration` object.
94162

@@ -123,7 +191,7 @@ Configuration configuration = new EnvironmentConfiguration();
123191
Map<String, String> configMap = configuration.asMap();
124192
----
125193

126-
=== Default configuration
194+
=== Default Configuration
127195

128196
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.
129197

@@ -145,20 +213,6 @@ DefaultConfiguration defaultConfiguration = new DefaultConfiguration(
145213
Map<String, String> result = defaultConfiguration.asMap();
146214
----
147215

148-
=== Configuration objects in your project
149-
150-
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!
151-
152-
Small example with an `Example` object:
153-
154-
[,java]
155-
----
156-
ExampleFactory exampleFactory = new ExampleFactory(configurationMap);
157-
Example example = exampleFactory.example();
158-
----
159-
160-
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.
161-
162216
== Contributing
163217

164218
// Change the repository name in the issues link to match with your project's name

0 commit comments

Comments
 (0)