Giter Site home page Giter Site logo

dmytromykhailiuk / s.o.l.i.d Goto Github PK

View Code? Open in Web Editor NEW

This project forked from vdslv/s.o.l.i.d

0.0 0.0 0.0 73 KB

S.O.L.I.D: The First 5 Principles of Object Oriented Design

Home Page: https://github.com/vdslv/S.O.L.I.D

License: MIT License

TypeScript 100.00%

s.o.l.i.d's Introduction

S.O.L.I.D. 🙈

☀️ S.O.L.I.D: The First 5 Principles of Object Oriented Design :shipit:

S.O.L.I.D is an acronym for the first five object-oriented design(OOD)** principles** by Robert C. Martin, popularly known as Uncle Bob.

These principles, when combined together, make it easy for a programmer to develop software that are easy to maintain and extend. They also make it easy for developers to avoid code smells, easily refactor code, and are also a part of the agile or adaptive software development.

S.O.L.I.D stands for:

  • S - Single-responsiblity principle
  • O - Open-closed principle
  • L - Liskov substitution principle
  • I - Interface segregation principle
  • D - Dependency Inversion Principle

Single-responsibility Principle 🌵

A class should have one and only one reason to change, meaning that a class should have only one job.
TypeScript Example

// A class should have one and only one reason to change,
// meaning that a class should have only one job.

class Circle {
    constructor(public radius: number) {
    }
}

class Rectangle {
    constructor(public length: number) {
    }
}

class AreaCalculator {
    constructor(public shapes: any[]) {
    }
    sum() {
        // logic to sum the areas
        return 9;
    }

    // wrong, should be in separate class
    // output() {
    //     return `Sum of the areas of provided shaper: ${this.sum()}`
    // }
}

class SumCalculatorOutputter {
    constructor(public areas: AreaCalculator) {
    }

    outputStr() {
        console.log(`Sum of the areas: ${this.areas.sum()}`)
    }

    outPutJSON() {
        console.log(JSON.stringify(`Sum of the areas JSON: ${this.areas.sum()}`))
    }
}

const areas = new AreaCalculator([new Circle(5), new Rectangle(7)]);
const output = new SumCalculatorOutputter(areas);

Open-closed Principle 🔧

Objects or entities should be open for extension, but closed for modification.
TypeScript Example

interface ShapeInterface {
    area(): number
}

class Square implements ShapeInterface {
    constructor(public length: number) {
    }
    area() {
        return Math.pow(this.length,2)
    }
}

class Circle implements ShapeInterface {
    constructor(public radius: number) {
    }
    area() {
        return Math.PI * Math.pow(this.radius,2)
    }
}

function sum(arr: ShapeInterface[]) {
   let sum = 0;
    for (const arrElement of arr) {
        sum += arrElement.area();

        // wrong, each class should have their own method to calculate area,
        // and be extended from interface
        //
        // if(arrElement instanceof Circle) {
        //     sum += Math.PI * Math.pow(arrElement.radius,2)
        // } else if (arrElement instanceof Square) {
        //     Math.pow(arrElement.length,2)
        // }
    }

    return sum;
}

Liskov substitution principle 💑

 Every subclass/derived class should be substitutable for their base/parent class.
TypeScript Example

// every subclass/derived class should be substitutable for their base/parent class.

class Circle {
    constructor(public radius: number) {
    }
}

class Rectangle {
    constructor(public length: number) {
    }
}

class AreaCalculator {
    constructor(public shapes: any[]) {
    }
    sum() {
        // logic to sum the areas
        return 9;
    }

    // wrong, should be in separate class
    // output() {
    //     return `Sum of the areas of provided shaper: ${this.sum()}`
    // }
}

class SumCalculatorOutputter {
    constructor(public areas: AreaCalculator) {
    }

    outputStr() {
        console.log(`Sum of the areas: ${this.areas.sum()}`)
    }

    outPutJSON() {
        console.log(JSON.stringify(`Sum of the areas JSON: ${this.areas.sum()}`))
    }
}

class VolumeCalculator extends AreaCalculator {
    constructor(public shapes: any[]) {
        super(shapes);
    }

    sum() {
        // logic to calculate volumes and return array
        // wrong, can not return array as the output of parent and child should be same
        // return [1,2,3]

        return 25
    }
}

const areas = new AreaCalculator([new Circle(5), new Rectangle(7)]);
const volumes = new VolumeCalculator([new Circle(5), new Rectangle(7)])

const output = new SumCalculatorOutputter(areas);
const output2 = new SumCalculatorOutputter(volumes);

output.outputStr();
output2.outPutJSON();

Interface segregation principle ✂️

A client should never be forced to implement an interface
that it doesn’t use or clients shouldn’t be forced to depend on methods they do not use.
TypeScript Example

// A client should never be forced to implement an interface that it doesn’t use or
// clients shouldn’t be forced to depend on methods they do not use.

interface ShapeInterface {
    area();

    // wrong, should be in new interface, we do not use method in every class
    // volume();
}

interface SolidShapeInterface {
    volume();
}

class Square implements ShapeInterface {
    area() {
        console.log('SQUARE AREA')
    }
}

class Cuboid implements ShapeInterface, SolidShapeInterface {
    area() {
        console.log('CUBOID AREA')
    }

    volume() {
        console.log('CUBOID VOLUME')
    }
}

Dependency Inversion principle 🔑

Entities must depend on abstractions not on concretions.
It states that the high level module must not depend on the low level module,
but they should depend on abstractions.
TypeScript Example

// Entities must depend on abstractions not on concretions.
// It states that the high level module must not depend on the low level module,
// but they should depend on abstractions.

// Depend on Abstraction not on concretions

interface DBConnectionInterface {
    connect();
}

class MySQLConnection implements DBConnectionInterface {
    connect() {
        return 'Database connection';
    }
}

class MongoDBConnection implements DBConnectionInterface {
    connect() {
        return 'MONGO DB connection';
    }
}

class PasswordReminder {
    constructor(public dbConnection: DBConnectionInterface) {
    }
}

const pass1 = new PasswordReminder(new MySQLConnection());
const pass2 = new PasswordReminder(new MongoDBConnection());

console.log(pass1.dbConnection.connect());
console.log(pass2.dbConnection.connect());


Conclusion

S.O.L.I.D might seem to be a bit too abstract at first, but with each real-world application of S.O.L.I.D. principles, the benefits of adherence to its guidelines will become more apparent. Code that follows S.O.L.I.D. principles can more easily be shared with collaborators, extended, modified, tested, and refactored without any problems.

s.o.l.i.d's People

Contributors

vdslv avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.