Home Navigation

Showing posts with label Design Principle. Show all posts
Showing posts with label Design Principle. Show all posts

Thursday, 16 December 2021

12 Factor App Principles

 

The Twelve-Factor App methodology is a methodology for building software-as-a-service applications. These best practices are designed to enable applications to be built with portability and resilience when deployed to the web.

1.      Code base

use version control, one repo per application, git submodule, maven submodule

2.      Dependencies:

don't check jar in git, use maven, artifactory, gcp artifact

3.      Config:

configuration should be strictly separated from code. As per "config", what varies for the environment to the environment must be moved to configurations and managed via environment variables.         

-        Database connections and credentials, system integration endpoints

-        Credentials to external services such as Amazon S3 or Twitter or any other external apps

-        Application-specific information like IP Addresses, ports, and hostnames, etc.

Principle: can you make your app opensource at anytime without compromising credentials

4.      Backing service:

Database, Message Brokers, any other external systems that the app communicates is treated as Backing service. Treat backing services as attached resources. like messaging service, postgre sql with signle url that can be replaced without making your code change

5.      Build, release, run:

Build stage: transform the code into an executable bundle/ build package.

Release stage: get the build package from the build stage and combines with the configurations of the deployment environment and make your application ready to run.

Run stage: It is like running your app in the execution environment.

Strictly separate the process with single command. You can use CI/CD tools to automate the builds and deployment process. Docker images make it easy to separate the build, release, and run stages more efficiently.

6.      Processes:

Execute the app as one or more stateless processes

As per 12-factor principles, the application should not store the data in in-memory and it must be saved to a store and use from there. As far as the state concern, your application should store the state in the database instead of in memory of the process.

Avoid using sticky sessions, using sticky sessions are a violation of 12-factor app principles. If you would store the session information, you can choose redis or memcached or any other cache provider based on your requirements.

7.      Port binding :

Export services via port binding. The web app exports HTTP as a service by binding to a port and listening to requests coming in on that port. Spring boot is one example of this one. Spring boot by default comes with embedded tomcat, jetty, or undertow.

8.      Concurrency:

By adopting the containerization, applications can be scaled horizontally as per the demands.

9.      Disposability

Maximize robustness with fast Startup and graceful shutdown. Docker containers can be started or stopped instantly. Storing request, state, or session data in queues or other backing services ensures that a request is handled seamlessly in the event of a container crash.

10.  Dev/prod parity

Keep development, staging, and production as similar as possible. This reduces the risks of showing up bugs in a specific environment.

11.  Logs

Treat logs as event streams

observability is the first-class citizen. Observability can be achieved through using APM tools (ELK, Newrelic, and other tools) or log aggregations tools like Splunk, logs, etc.

12.  Admin processes

Run admin/management tasks as one-off processes. Any needed admin tasks should be kept in source control and packaged with the application.

Twelve-factor principles advocates for keeping such administrative tasks as part of the application codebase in the repository. By doing so, one-off scripts follow the same process defined for your codebase.

Ensure one-off scripts are automated so that you don't need to worry about executing them manually before releasing the build. Twelve-factor principles also suggest using the built-in tool of the execution environment to run those scripts on production servers. 

Ref: https://12factor.net/

Thursday, 30 April 2020

SOLID Principle

SOLID Principle

  • The principles are from Robert "Uncle Bob" Martin
  • Michael Feathers is credited with coming up with the SOLID acronym
    • S = Single Responsibility Principle
    • O = Open/Closed Principle
    • L = Liskov Substitution principle
    • I = Interface Segregation Principle
    • D = Dependency Inversion Principle

Why?


  • OOP does not always lead to quality software
  • Poor dependency management leads to code that is brittle, fragile, and hard to change
  • Proper dependency management leads to quality code that is easy to maintain.
  • The 5 principles focus on dependency management
The one thing you can always count on in software engineering is CHANGE, no matter how well you design an application over time an application must grow and change or it will die.

Single Responsibility Principle

  • Every Class should have a single responsibility.
  • There should never be more than one reason for a class to change.
  • Your classes should be small. No more than a screen full of code.
  • Avoid ‘god’ classes.
  • Split big classes into smaller classes.
You can avoid these problems by asking a simple question before you make any changes: What is the responsibility of your class/component?

If your answer includes the word “and”, you’re most likely breaking the single responsibility principle. Then it’s better to take a step back and rethink your current approach.

Example: please follow the github link with bad and good example. explanation is class comment.


Real world example:
  • Java Persistence API (JPA) specification. defines a standardized way to manage data persisted in a relational database by using the object-relational mapping concept.
  • Spring Data Repository
  • Logging

Open/Closed Principle

  • Your classes should be open for extension but closed for modification
  • You should be able to extend a classes behavior, without modifying it.
  • Use private variables with getters and setters - ONLY when you need them.
  • Use abstract/interface base classes
  • Design should be ploymorphic to allow different implementations which you can easily substitute without changing the code that uses them
Example: please follow the github link with bad and good example. explanation is class comment.


Liskov Substitution Principle

  • By Barbara Liskov, in 1998
  • Objects in a program would be replaceable with instances of their subtypes WITHOUT altering the correctness of the program.
  • Violations will often fail the “Is a” test.
  • A Square “Is a” Rectangle
  • However, a Rectangle “Is Not” a Square
  • Can most usually be recognized by a method that does nothing, or even can’t be implemented.
  • The solution to these problems is a correct inheritance hierarchy/ correct interface
  • If it looks like a Duck, Quacks like a Duck but needs batteries. You probably Have the wrong abstraction.
Example: please follow the github link with bad and good example. explanation is class comment.


Interface Segregation Principle

  • No matter what should never be forced to implement an interface that it does not use or the client should never be obliged to depend on any method, which is not used by them.
  • Make fine grained interfaces that are client specific
  • Many client specific interfaces are better than one “general purpose” interface
  • Keep your components focused and minimize dependencies between them
  • Changing one method in a class should not affect classes that don't depend on
  • Notice relationship to the Single Responsibility Principle?
  • ie avoid ‘god’ interfaces
Example: please follow the github link with bad and good example. explanation is class comment.

Dependency Inversion Principle

  • Abstractions should not depend upon details
  • Details should depend upon abstractions
  • Important that higher level and lower level objects depend on the same abstract interaction
  • Able to change an implementation easily without altering the high level code.
  • This is not the same as Dependency Injection - which is how objects obtain dependent objects
Example: please follow the github link with bad and good example. explanation is class comment.

Some of other design principles
  • Encapsulate what varies ( identify the aspect of your application that vary and separate them from what stays the same)
  • Program to an interface not an implementation
  • Favor composition over inheritance ( HAS- A can better than IS - A)
  • Composition gives you a lot more flexibility. Not only does it let you encapsulate a family of algorithms into their own set of classes, but it also lets you change behavior at runtime as long as the object you are composing with implements correct behavior interface.