Skip to content

Commit

Permalink
Add "How to implement" to README (#31)
Browse files Browse the repository at this point in the history
* 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"
  • Loading branch information
51-code authored Feb 12, 2025
1 parent 35d44df commit 7e12f16
Showing 1 changed file with 71 additions and 17 deletions.
88 changes: 71 additions & 17 deletions README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -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<T> {
public T object();
}
----

* Create a Factory object for the object that has to use configurations.
+

[,java]
----
public final class ExampleFactory implements Factory<Example> {
private final Map<String, String> config;
public ExampleFactory(final Map<String, String> 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<String, String> 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
Expand Down Expand Up @@ -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.

Expand Down Expand Up @@ -123,7 +191,7 @@ Configuration configuration = new EnvironmentConfiguration();
Map<String, String> 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.

Expand All @@ -145,20 +213,6 @@ DefaultConfiguration defaultConfiguration = new DefaultConfiguration(
Map<String, String> 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
Expand Down

0 comments on commit 7e12f16

Please sign in to comment.