# Abbreviations and principles
## SOLID
**S** - single responsibility
**O** - open-closed principle
**L** - Liskov substitution
**I** - Interface segregation
**D** - Dependency-inversion
### Single Responsibility
A class should only have one responsibility. ha
### Open-closed principle
Classes should be open for extension, but closed for modification.
Extend behaviour of the class without modifying existing code:
* **Inheritance** - alter/extend behaviour or properties by extending the class
* **Composition** - design class so that the specific behaviour could be defined by an interface. Class extention then can be achived by providing different implementation
### Liskov substitution
If class A is a subtype of class B, then we should be able to replace B with A without disrupting the behavior of our program.
### Interface Segregation
Larger interfaces should be split into smaller ones. By doing so, we can ensure that implementing classes only need to be concerned about the methods that are of interest to them.
### Dependency-inversion
High-level modules, which provide complex logic, should be easily reusable and unaffected by changes in low-level modules, which provide utility features.
Dependency Inversion Principle consists of two parts:
* High-level modules should not depend on low-level modules. Both should depend on abstractions.
* Abstractions should not depend on details. Details should depend on abstractions.
## 12 Factor app
### Codebase
Use VCS
### Dependencies
Use dependency management tools
### Config
Store config in the environment. Code should remain the same irrespective of where the application is being deployed, but
### Backing Services
Backing services refer to the infrastructure and other services by which the application communicates over the network. Database, Message Brokers, other API-accessible consumer services such as Authorization Service, Twitter, GitHub etc.
They should be loosely coupled with the application and be treated them as resource.
configurations can vary.
### Build, Release, Run
* The build stage - converts a code repo into an executable bundle known as a build.
* The release stage - takes the build produced by the build stage and combines it with the current config. The resulting release contains both the build and the config and is ready for immediate execution in the execution environment.
* The run stage (also known as “runtime”) runs the app in the execution environment, by launching some set of the app’s processes against a selected release.
Stages should be isolated. For example it should be impossible to update config of running app.
### Processes
Execute the app as one or more stateless processes. App shouldn't rely on in-memory or file sustem state.
### Port binding
Export services via port binding
### Concurrency
Applications should be designed to distribute workload across multiple processes. Individual processes are, however, free to leverage a concurrency model like Thread internally.
### Disposability
Apps can be started or stopped (gracefully) at a moment’s notice. This facilitates fast elastic scaling, rapid deployment of code or config changes, and robustness of production deploys.
### Dev/prod parity
Keep development, staging, and production as similar as possible
### Logs
Treat logs as event streams
### Admin processes
Run admin/management tasks as one-off processes