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

Docs/architecture #78

Merged
merged 2 commits into from
Feb 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
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
Binary file added docs/reference/imgs/component_diagram.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
68 changes: 68 additions & 0 deletions docs/reference/koswat_architecture.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# Koswat design

In general, the architecture of this package is based on the following principles:

- Single responsibility principle, [component hierarchy](#component-hierarchy).
- Open-closed principle, [inheritance](#inheritance).
- Interface segregation principle, [protocols](#protocols).

## Component-module hierarchy

We cluster entities into modules (components) that represent their domain and have minimal dependencies with others components, this way the modules can be accessed when operating Koswat as a sandbox. Within each component we apply the same principle and create sub-modules to reduce dependencies.

At the current version (v.0.12.1) the component hierarchy looks like follows:

koswat/
calculations/ # Dike calculations to generate possible reinforcements.
io/
outside_slope_reinforcement/
protocols/
standard_reinforcement/

configuration/ # Data structures required for a koswat run.
io/
settings/

core/ # Generic definitions and functionatilities.
geometries/
io/
protocols/

cost_report/ # Summary of costs per dike reinforcement.
io/
multi_location_profile/
profile/
summary/

dike/ # Definition of a koswat dike.
characteristic_points/
layers/
material/
profile/
surroundings/

plots/ # Generic functionality for plotting.
dike/
geometries/

And the components interdependencies could be slightly represented as in the following diagram:

|![Base profile sand layer](./imgs/component_diagram.png)|
|:--:|
|Image 1. Component diagram|

## Inheritance

To facilitate the `Open-Closed principle` most of our classes have parameterless constructors (`__init__` method). Then, to instantiate objects we often relay on the implementation of [builder patterns](#builder-pattern)

## Protocols

In Koswat we make use of [Protocols](https://docs.python.org/3/library/typing.html?highlight=protocol#typing.Protocol) to define the __required__ and __essential__ properties and methods that represent an entity. Although Python does not always enforce these types as other OO languages would do (for instance C#), we try to follow and respect this principle throughought the whole repository.

### Builder pattern

Check for instance this [wikipedia article](https://en.wikipedia.org/wiki/Builder_pattern) for a more detailed reference.

Because most of our classes have dependencies on other classes their initialization would require multiple steps that would become tedious and hard to maintain if they were defined in the default __init__ method. Moreover, this approach would violate the open-closed principle.

Therefore, we apply the builder pattern to reduce complexity at the classes, improving maintainability and enabling future developments to create a separate builder shall the design require a different way of instantiating a given class.