Upgrade to Pro — share decks privately, control downloads, hide ads and more …

SOLID Principles

Sahil Kumar
September 06, 2019
17

SOLID Principles

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 is 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.

Sahil Kumar

September 06, 2019
Tweet

Transcript

  1. 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 is 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.
  2. S.O.L.I.D. STANDS FOR: S - Single responsibility principle O -

    Open closed principle L - Liskov substitution principle I - Interface segregation principle D - Dependency Inversion principle
  3. # Single-responsibility Principle A class should have one and only

    one reason to change, meaning that a class should have only one job.
  4. class User { final int id; final String name; final

    int age; User(this.id, this.name, this.age); }
  5. class User { final int id; final String name; final

    int age; User(this.id, this.name, this.age); User getUser() => DB.getUser(this.id); void saveUser() => DB.saveUser(this); }
  6. class User { final int id; final String name; final

    int age; User(this.id, this.name, this.age); User getUser() => DB.getUser(this.id); void saveUser() => DB.saveUser(this); } Oops due to change in requirements, we have to change our DB.
  7. class User { final int id; final String name; final

    int age; User(this.id, this.name, this.age); User getUser() => DB.getUser(this.id); void saveUser() => DB.saveUser(this); }
  8. class User { final int id; final String name; final

    int age; User(this.id, this.name, this.age); }
  9. class User { final int id; final String name; final

    int age; User(this.id, this.name, this.age); } class UserRepository { User getUser(int id) => DB.getUser(id); void saveUser(User user) => DB.saveUser(user); }
  10. # Open-closed Principle Objects or entities should be open for

    extension, but closed for modification.
  11. class Burger { final String customerName; Burger(this.customerName); void prepareBurger() =>

    print(‘Preparing Burger); void addCheese() { If (customerName == ‘Amit’) print('Adding Chesse'); else print(‘Cheese not needed’); } }
  12. class Burger { final String customerName; Burger(this.customerName); void prepareBurger() =>

    print(‘Preparing Burger); void addCheese() { If (customerName == ‘Amit’) print('Adding Chesse'); If (customerName == ‘Sahil’’) print('Adding extra Chesse'); else print(‘Cheese not needed’); }
  13. class Burger { final String customerName; Burger(this.customerName); void prepareBurger() =>

    print(‘Preparing Burger); void addCheese() { If (customerName == ‘Amit’) print('Adding Chesse'); If (customerName == ‘Sahil’’) print('Adding extra Chesse'); else print(‘Cheese not needed’); } We have to add another condition everytime a new customer requests a burger
  14. class AmitBurger extends Burger{ @override void addCheese() { print("Adding extra

    cheese for amit"); } } class SahilBurger extends Burger{ @override void addCheese() { print("Adding cheese for sahil"); } }
  15. # Liskov substitution principle Let q(x) be a property provable

    about objects of x of type T. Then q(y) should be provable for objects y of type S where S is a subtype of T.
  16. # Liskov substitution principle Let q(x) be a property provable

    about objects of x of type T. Then q(y) should be provable for objects y of type S where S is a subtype of T. More generally it states that the object of a derived class should be able to replace an object of the base class without bringing any errors in the system or modifying the behavior of the base class"
  17. class TransportationDevice { final String name; final double speed; TransportationDevice(this.name,

    this.speed); void startEngine() => print('Starting engine of $name'); }
  18. class Car extends TransportationDevice { Car(String name, double speed, this.engine)

    : super(name, speed); @override void startEngine() { } }
  19. class Car extends TransportationDevice { final Engine engine; Car(String name,

    double speed, this.engine) : super(name, speed); @override void startEngine() { } }
  20. class Car extends TransportationDevice { final Engine engine; Car(String name,

    double speed, this.engine) : super(name, speed); @override void startEngine() { engine.start(); } }
  21. class Bicycle extends TransportationDevice { Bicycle(String name, double speed) :

    super(name, speed); @override void startEngine() { } }
  22. class Bicycle extends TransportationDevice { // Engine…. What’s that ?

    Bicycle(String name, double speed) : super(name, speed); @override void startEngine() { // Cannot start an engine in Bicycle } }
  23. class TransportationDevice { final String name; final double speed; TransportationDevice(this.name,

    this.speed); void startEngine() => print('Starting engine of $name'); }
  24. class DevicesWithEngines extends TransportationDevice { final Engine engine; DevicesWithEngines(String name,

    double speed,this.engine) : super(name,speed); void startEngine() { ... } }
  25. class DevicesWithEngines extends TransportationDevice { final Engine engine; DevicesWithEngines(String name,

    double speed,this.engine) : super(name,speed); void startEngine() { ... } } class DevicesWithoutEngines extends TransportationDevice { DevicesWithoutEngines(String name, double speed,this.engine) : super(name,speed); void startMoving() { ... } }
  26. # 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.
  27. class RestaurantEmployee { final String name; final String designation; final

    double salary; RestaurantEmployee(this.name, this.designation, this.salary); }
  28. class Chef extends RestaurantEmployee { Chef(String name, String designation, double

    salary) : super(name, designation, salary); } class Waiter extends RestaurantEmployee { Waiter(String name, String designation, double salary) : super(name, designation, salary); }
  29. class Chef extends RestaurantEmployee implements IEmployeeTasks { Chef(String name, String

    designation, double salary) : super(name, designation, salary); @override void cookFood() {} @override void takeOrder() {} }
  30. class Chef extends RestaurantEmployee implements IEmployeeTasks { Chef(String name, String

    designation, double salary) : super(name, designation, salary); @override void cookFood() {} @override void takeOrder() {} } Hey, I can’t take orders
  31. class Waiter extends RestaurantEmployee implements IEmployeeTasks { Waiter(String name, String

    designation, double salary) : super(name, designation, salary); @override void cookFood() {} @override void takeOrder() {} }
  32. class Waiter extends RestaurantEmployee implements IEmployeeTasks { Waiter(String name, String

    designation, double salary) : super(name, designation, salary); @override void cookFood() {} @override void takeOrder() {} } Hey, If i can cook i won’t be working here as a waiter
  33. abstract class IEmployeeTasks { void takeOrder(); void cookFood(); } abstract

    class IChefTasks{ void cookFood(); } abstract class IWaiterTasks{ void takeOrder(); }
  34. class Chef extends RestaurantEmployee implements IEmployeeTasks { Chef(String name, String

    designation, double salary) : super(name, designation, salary); @override void cookFood() {} @override void takeOrder() {} }
  35. class Chef extends RestaurantEmployee implements IChefTasks{ Chef(String name, String designation,

    double salary) : super(name, designation, salary); @override void cookFood() {} }
  36. class Waiter extends RestaurantEmployee implements IEmployeeTasks { Waiter(String name, String

    designation, double salary) : super(name, designation, salary); @override void cookFood() {} @override void takeOrder() {} }
  37. class Waiter extends RestaurantEmployee implements IWaiterTasks{ Waiter(String name, String designation,

    double salary) : super(name, designation, salary); @override void takeOrder() {} }
  38. # Dependency inversion principle • 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.
  39. class Waiter { VegChef _chef = VegChef(); final Order order;

    Waiter(this.order); void serveOrder() { final orderName = _chef.getFood(order).name; print("Serving $orderName to the customer"); } }
  40. class Waiter { VegChef _chef = VegChef(); final Order order;

    Waiter(this.order); void serveOrder() { final orderName = _chef.getFood(order).name; print("Serving $orderName to the customer"); } }
  41. class Waiter { NonVegChef _chef = NonVegChef(); final Order order;

    Waiter(this.order); void serveOrder() { final orderName = _chef.getFood(order).name; print("Serving $orderName to the customer"); } }
  42. class NonVegChef implements Chef { @override Food getFood(Order order) {

    print('Preparing NonVeg Food'); return Food(order.orderName); } }
  43. class VegChef implements Chef { @override Food getFood(Order order) {

    print('Preparing Veg Food'); return Food(order.orderName); } }
  44. class Waiter { VegChef _chef = VegChef(); final Order _order;

    Waiter(this._order); void serveOrder() { final orderName = _chef.getFood(_order).name; print("Serving $orderName to the customer"); } }
  45. class Waiter { final Chef _chef; final Order _order; Waiter(this._order,

    this._chef); void serveOrder() { final orderName = _chef.getFood(_order).name; print("Serving $orderName to the customer"); } }