SOLID and Base principles
of software design
What is «Simple system»?
▪ There are all tests passed.
▪ The system code is clear and reveals ideas.
▪ There are no code doubling. There are no hierarchy doubling.
▪ There are used minimum possible amount of classes and methods.
Base principles of software design
● DRY : Don’t Repeat Yourself
● SCP : Speaking Code
● OCP : Open Closed
● LSP : Liskov Substitution
● DIP : Dependency Inversion
● ISP : Interface Segregation
● CRP : Common Reuse
● CCP : Common Closure
● ADP : Acyclic Dependencies
● SDP : Stable Dependencies
● SAP : Stable Abstractions
● TDA : Tell, Don’t Ask
● SRP : Single Responsibility Principle
SRP : Single Responsibility Principle (SOLID)
A class should have one, and only one, reason to change.
SRP : Single Responsibility Principle (SOLID)
SRP : Single Responsibility Principle (SOLID)
OCP : Open Closed (SOLID)
The code should be open to extension.
The code should be closed to changes.
OCP : Open Closed (SOLID)
LSP : Liskov Substitution (SOLID)
If S is a subtype of T, then objects of type T may be replaced with objects of
type S without altering any of the desirable properties of the program
LSP : Liskov Substitution (SOLID)
class Rectangle {
double height;
double width;;
int CalculateRectangleArea()
{...}
};;
class Square : Rectangle {
void set_height(int) {}
void set_width(int) {}
};
LSP : Liskov Substitution (SOLID)
class Rectangle {
double height;
double width;;
int CalculateRectangleArea()
{...}
};;
class Square : Rectangle {
void set_height(int) {}
void set_width(int) {}
};
Rectangle CreateRecatgle() {
return new Square();
}
void Main()
{
Rectangle r = CreateRecatgle();
r.Width = 3;
r.Height = 2;
assert(6, r.CalculateRectangleArea());
}
ISP : Interface Segregation (SOLID)
The big interfaces should be divided to particular small interfaces.
ISP : Interface Segregation (SOLID)
class Car
{
virtual void StartEngine() = 0;
virtual void StopEngine() = 0;
virtual int GetSpeed() = 0;
virtual void Turbo() = 0;
};
ISP : Interface Segregation (SOLID)
class SportsCar
{
virtual void Turbo() = 0;
};
class Car
{
virtual void StartEngine() = 0;
virtual void StopEngine() = 0;
virtual int GetSpeed() = 0;
};
DIP : Dependency Inversion (SOLID)
1. High level modules should not depend on low level modules. Both
should depend on abstractions
1. Abstraction shouldn't depend on details. Details should depend upon
abstractions.
DIP : Dependency Inversion (SOLID)
class Ractangle {
void draw();
};
class Circle {
void draw();
};
class UI {
void display() {
rect.draw();
circ.draw();
}
};
DIP : Dependency Inversion (SOLID)
class Ractangle {
void draw();
};
class Circle {
void draw();
};
class UI {
Rectangle rect;
Circle circ;
void display() {
rect.draw();
circ.draw();
}
};
DIP : Dependency Inversion (SOLID)
class Ractangle {
void draw();
};
class Circle {
void draw();
};
class UI {
Rectangle rect;
Circle circ;
void display() {
rect.draw();
circ.draw();
}
};
class Geometry {
virtual void draw() = 0;
};
class Circle: public Geometry{
void draw() override;
};
class Rectangle: public Geometry{
void draw() override;
};
class UI {
vector<Geometry*> geometries;
void display() {
for(auto g : geometries)
g->draw();
}
};
DRY : Don’t Repeat Yourself
You shouldn’t repeat code you written.
SCP : Speaking Code
The code should be well-documented.
CRP : Common Reuse
All classes inside the component should be used together. If you can reuse one class you
will use the rest.
CCP : Common Closure
▪ The classes in a package should be closed together against the same
kind of changes. A change that affects a package affects all classes in
that package.
▪ So “common closure” actually means SRP for packages. The SRP says
that one class shouldn’t have more than one reason to be changed.
The CCP says the same is applicable to packages.
ADP : Acyclic Dependencies
▪ There are shouldn’t be cyclic dependencies between the components
at the dependencies graph.
You worked hard. You fixed a lot of issues at the specific part of a program, but
you observed it didn't work anymore. Why did it happen, because somebody
left a work after you. On the next day it turned out that something broke but it
shouldn't have.
SDP : Stable Dependencies
Dependencies should be directed towards sustainability.
SAP : Stable Abstractions
▪ A component should be as abstract as it is persistent.
SAP : Stable Abstractions
SAP : Stable Abstractions
SAP : Stable Abstractions
The abstract things, like interfaces, will remain the same over a longer period of time
If we depend on an abstract thing, it is likely that we will not be negatively influenced by
it—it’s supposed to be very stable.
TDA : Tell, Don’t Ask
Instead of asking the object for data and working with it, we should
tell the object what to do.
Martin Fowler
Thank You!

Pavlo Zhdanov "Mastering solid and base principles for software design"

  • 1.
    SOLID and Baseprinciples of software design
  • 4.
    What is «Simplesystem»? ▪ There are all tests passed. ▪ The system code is clear and reveals ideas. ▪ There are no code doubling. There are no hierarchy doubling. ▪ There are used minimum possible amount of classes and methods.
  • 5.
    Base principles ofsoftware design ● DRY : Don’t Repeat Yourself ● SCP : Speaking Code ● OCP : Open Closed ● LSP : Liskov Substitution ● DIP : Dependency Inversion ● ISP : Interface Segregation ● CRP : Common Reuse ● CCP : Common Closure ● ADP : Acyclic Dependencies ● SDP : Stable Dependencies ● SAP : Stable Abstractions ● TDA : Tell, Don’t Ask ● SRP : Single Responsibility Principle
  • 6.
    SRP : SingleResponsibility Principle (SOLID) A class should have one, and only one, reason to change.
  • 7.
    SRP : SingleResponsibility Principle (SOLID)
  • 8.
    SRP : SingleResponsibility Principle (SOLID)
  • 9.
    OCP : OpenClosed (SOLID) The code should be open to extension. The code should be closed to changes.
  • 10.
    OCP : OpenClosed (SOLID)
  • 11.
    LSP : LiskovSubstitution (SOLID) If S is a subtype of T, then objects of type T may be replaced with objects of type S without altering any of the desirable properties of the program
  • 12.
    LSP : LiskovSubstitution (SOLID) class Rectangle { double height; double width;; int CalculateRectangleArea() {...} };; class Square : Rectangle { void set_height(int) {} void set_width(int) {} };
  • 13.
    LSP : LiskovSubstitution (SOLID) class Rectangle { double height; double width;; int CalculateRectangleArea() {...} };; class Square : Rectangle { void set_height(int) {} void set_width(int) {} }; Rectangle CreateRecatgle() { return new Square(); } void Main() { Rectangle r = CreateRecatgle(); r.Width = 3; r.Height = 2; assert(6, r.CalculateRectangleArea()); }
  • 14.
    ISP : InterfaceSegregation (SOLID) The big interfaces should be divided to particular small interfaces.
  • 15.
    ISP : InterfaceSegregation (SOLID) class Car { virtual void StartEngine() = 0; virtual void StopEngine() = 0; virtual int GetSpeed() = 0; virtual void Turbo() = 0; };
  • 16.
    ISP : InterfaceSegregation (SOLID) class SportsCar { virtual void Turbo() = 0; }; class Car { virtual void StartEngine() = 0; virtual void StopEngine() = 0; virtual int GetSpeed() = 0; };
  • 17.
    DIP : DependencyInversion (SOLID) 1. High level modules should not depend on low level modules. Both should depend on abstractions 1. Abstraction shouldn't depend on details. Details should depend upon abstractions.
  • 18.
    DIP : DependencyInversion (SOLID) class Ractangle { void draw(); }; class Circle { void draw(); }; class UI { void display() { rect.draw(); circ.draw(); } };
  • 19.
    DIP : DependencyInversion (SOLID) class Ractangle { void draw(); }; class Circle { void draw(); }; class UI { Rectangle rect; Circle circ; void display() { rect.draw(); circ.draw(); } };
  • 20.
    DIP : DependencyInversion (SOLID) class Ractangle { void draw(); }; class Circle { void draw(); }; class UI { Rectangle rect; Circle circ; void display() { rect.draw(); circ.draw(); } }; class Geometry { virtual void draw() = 0; }; class Circle: public Geometry{ void draw() override; }; class Rectangle: public Geometry{ void draw() override; }; class UI { vector<Geometry*> geometries; void display() { for(auto g : geometries) g->draw(); } };
  • 21.
    DRY : Don’tRepeat Yourself You shouldn’t repeat code you written.
  • 22.
    SCP : SpeakingCode The code should be well-documented.
  • 23.
    CRP : CommonReuse All classes inside the component should be used together. If you can reuse one class you will use the rest.
  • 24.
    CCP : CommonClosure ▪ The classes in a package should be closed together against the same kind of changes. A change that affects a package affects all classes in that package. ▪ So “common closure” actually means SRP for packages. The SRP says that one class shouldn’t have more than one reason to be changed. The CCP says the same is applicable to packages.
  • 25.
    ADP : AcyclicDependencies ▪ There are shouldn’t be cyclic dependencies between the components at the dependencies graph. You worked hard. You fixed a lot of issues at the specific part of a program, but you observed it didn't work anymore. Why did it happen, because somebody left a work after you. On the next day it turned out that something broke but it shouldn't have.
  • 26.
    SDP : StableDependencies Dependencies should be directed towards sustainability.
  • 30.
    SAP : StableAbstractions ▪ A component should be as abstract as it is persistent.
  • 31.
    SAP : StableAbstractions
  • 32.
    SAP : StableAbstractions
  • 33.
    SAP : StableAbstractions The abstract things, like interfaces, will remain the same over a longer period of time If we depend on an abstract thing, it is likely that we will not be negatively influenced by it—it’s supposed to be very stable.
  • 34.
    TDA : Tell,Don’t Ask Instead of asking the object for data and working with it, we should tell the object what to do. Martin Fowler
  • 35.