# 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