Professional Documents
Culture Documents
SOLID PRICIPLES
SOLID
SOLID is an acronym for the first five object-oriented
design (OOD).
These principles establish practices that lend to developing
software with considerations for maintaining and extending
as the project grows.
Adopting these practices can also contribute to avoiding
code smells, refactoring code, and Agile or Adaptive
software development.
SOLID 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
Single-responsibility Principle (SRP) states:
A class should have one and only one reason to
change, meaning that a class should have only one
job.
Example: Single responsibility
class Person {
protected String firstname;
protected String lastname;
public String void printData() {
System.out.println(this.firstname + this.lastname);
}
}
Example: Single responsibility
class Student extends Person{
protected String group;
public void printData() {
System.out.println(this.firstname + this.lastname + this.group);
}
}
class Lector extends Person{...}
class Employee extends Person{...}
Example: Single responsibility
New tasks:
output data in html, json, csv, xml
make abbreviation or custom format like
F.LastName(group);
Create reports
...
Example: Single responsibility
Example: Single responsibility
class PersonPrinter {
protected Person p;
printHTML(){ ... }
printJSON(){ ... }
...
}
Open-Closed Principle
Open-closed Principle (OCP) states:
Objects or entities should be open for extension but
closed for modification.
This means that a class should be extendable
without modifying the class itself.
Open-Closed Principle
public class Rectangle
{
public double Width { get; set; }
public double Height { get; set; }
}
Open-Closed Principle
public class AreaCalculator
{
public double Area(Rectangle[] shapes)
{
double area = 0;
foreach (var shape in shapes)
{
area += shape.Width*shape.Height;
}
return area;
}
}
Open-Closed Principle
public double Area(object[] shapes)
{
double area = 0;
foreach (var shape in shapes)
{
if (shape is Rectangle)
{
Rectangle rectangle = (Rectangle) shape;
area += rectangle.Width*rectangle.Height;
}
else
{
Circle circle = (Circle)shape;
area += circle.Radius * circle.Radius * Math.PI;
}
}
return area;
}
Open-Closed Principle
public abstract class Shape
{
public abstract double Area();
}
Open-Closed Principle
public class Rectangle : Shape
{
public double Width { get; set; }
public double Height { get; set; }
public override double Area()
{
return Width*Height;
}
}
public class Circle : Shape
{
public double Radius { get; set; }
public override double Area()
{
return Radius*Radius*Math.PI;
}
}
Open-Closed Principle
public double Area(Shape[] shapes)
{
double area = 0;
foreach (var shape in shapes)
{
area += shape.Area();
}
return area;
}
Liskov Substitution Principle
Liskov Substitution Principle states:
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.
This means that every subclass or derived class
should be substitutable for their base or parent
class.
Liskov Substitution Principle
class figure{
public int square(){...}
}
class circle extends figure {
public int square(){...}
}
Liskov Substitution Principle
public class Bird{
public void fly(){}
}
public class Duck extends Bird{}
public class Ostrich extends Bird{} ???
Liskov Substitution Principle
public class Bird{}
public class FlyingBirds extends Bird{
public void fly(){}
}
public class Duck extends FlyingBirds{}
public class Ostrich extends Bird{}
Interface Segregation Principle
Interface segregation principle states:
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 Segregation Principle
interface ShapeInterface
{
public function area();
public function volume();
}
Interface Segregation Principle
interface ShapeInterface
{
public function area();
}
interface ThreeDimensionalShapeInterface
{
public function volume();
}
Interface Segregation Principle
class Cuboid implements ShapeInterface, ThreeDimensionalShapeInterface
{
public function area()
{
// calculate the surface area of the cuboid
}
public function volume()
{
// calculate the volume of the cuboid
}
}
Dependency Inversion Principle
Dependency inversion principle states:
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.
This principle allows for decoupling.
Dependency Inversion Principle
High-level modules should not depend on low-
level modules. Both should depend on the
abstraction.
Abstractions should not depend on details.
Details should depend on abstractions.
Dependency Inversion Principle
class Logger {
private NtfsFileSystem _fileSystem = new NtfsFileSystem ();
public void Log (string text) {
var fileStream = _fileSystem.OpenFile ("log.txt");
fileStream.Write (text);
fileStream.Dispose ();
}
}
Dependency Inversion Principle
it is still tightly coupled, even though we have
inverted the dependent object creation to the
factory class.
Dependency Inversion Principle
public interface ILoggable
{ void Log(string textToLog); }
class NtfsFileSystem : ILoggable {
public void Log (string textToLog) {
//file handling, writing and disposing.
}
}
Dependency Inversion Principle
class Logger2 {
private ILoggable _logService;
public Logger (ILoggable logService) {
if (logService == null) throw new ArgumentNullException ();
_logService = logService;
}
public void Log (string text) {
_logService.Log (text);
}
}
Dependency Inversion Principle
class Program () {
void Main () {
var ntfsLogger = new Logger2 (new NtfsFileSystem ());
var noSqlLogger = new Logger2 (new DbNoSql ());
ntfsLogger.Log("some text");
noSqlLogger.Log("other text");
}
}