Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add "How to implement" to README #31

Merged
merged 4 commits into from
Feb 12, 2025
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 56 additions & 5 deletions README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ 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`)

== 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 use

// add instructions how people can start to use your project
Expand Down Expand Up @@ -145,19 +151,64 @@ DefaultConfiguration defaultConfiguration = new DefaultConfiguration(
Map<String, String> result = defaultConfiguration.asMap();
----

=== Configuration objects in your project
== 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.

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!
[,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;

Small example with an `Example` object:
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.example();
Example example = exampleFactory.object();
----

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.
* Create additional factories for other objects that require configurations.

== Contributing

Expand Down