Thanks to visit codestin.com
Credit goes to github.com

Skip to content

saroar/solid

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

S.O.L.I.D

Check and play with playground code

The Single Responsibility Principle

Each class/model have only single Responsibility

The Open Closed Principle

Open for extension and close for modification

The Liskov Substitution Principle

Child class/subclass cant be change/ are not allow anything of parent class/ super class.
Any class should be able to be replaced by one of its subclasses without affecting its functioning.

Child class/subclass cant be change/ are not allow anything of parent class/ super class Any class should be able to be replaced by one of its subclasses without affecting its functioning. Наследующий класс должен дополнять, а не замещать поведение базового класса.
//public class Bird {
//  public var name: String
//  public flySpeed: Double
//
//  init(name: String) {
//    self.name = name
//  }
//}
//
//class Eagle: Bird { } all is good
//class Penguin: Bird {} here is broken Liskov subtitution principle
// Penguin cant fly but can swim
public protocol CanFly {
  var flySpeed: Double { get set }
}

public protocol CanSwim {
  var swimSpeed: Double { get set }
}

public class Bird {
  public var name: String

  init(name: String) {
    self.name = name
  }
}

public class Eagle: Bird, CanFly {
  public var flySpeed: Double
  
  public init(flySpeed: Double, name: String) {
    self.flySpeed = flySpeed
    super.init(name: name)
  }
}

public class Penguin: Bird, CanSwim {
  public var swimSpeed: Double
  
  public init(swimSpeed: Double, name: String) {
    self.swimSpeed = swimSpeed
    super.init(name: name)
  }
  
}

The Interface Segregation Principle

The Principle of segregation of the interface indicates that it is better to have different interfaces (protocols) that are specific to each client Клиенты не должны зависить от методов, которые они не используют. Много специализированных интерфейсов лучше, чем один универсальный.
public class Document {
  public init() {}
}

public protocol Machine {
  func prnt(d: Document)
  func scan(d: Document)
  func fax(d: Document)
} // This is broken Interface Segregation Principle
public class MultiFunPrinter: Machine {
  public func prnt(d: Document) {
    print("Print")
  }
  
  public func scan(d: Document) {
    print("Scan")
  }
  
  public func fax(d: Document) {
    print("Fax")
  }

}

public class OldFashionedPrinter: Machine {
  public func prnt(d: Document) {
    // good
  }
  
  public func scan(d: Document) {
    // unused
  }

  public func fax(d: Document) {
    // unused
  }
}

public protocol Printer {
  func prnt(d: Document)
}

public protocol Scanner {
  func scan(d: Document)
}

public protocol Fax {
  func fax(d: Document)
}

public class OrdinaryPrinter : Printer {
  
  public init() {}
  
  public func prnt(d: Document) {
    // All is good
    print("OrdinaryPrinter cant only print")
  }
}

public class Photocopier : Printer, Scanner {
  
  public init() {}
  
  public func prnt(d: Document) {
    print("Photocopier can print")
  }

  public func scan(d: Document) {
    print("Photocopier can scan")
  }
}

protocol MultiFunctionDevice : Printer, Scanner, Fax {}

public class MultiFunctionMachine : MultiFunctionDevice {
  public let printer: Printer
  public let scanner: Scanner
  public let fax: Fax

  public init(printer: Printer, scanner: Scanner, fax: Fax) {
    self.printer = printer
    self.scanner = scanner
    self.fax = fax
  }

  public func prnt(d: Document) {
    printer.prnt(d: Document())
  }
  
  public func scan(d: Document) {
    scanner.scan(d: Document())
  }
  
  public func fax(d: Document) {
    fax.fax(d: Document())
  }
  
}

The Dependency Inversion Principle

High level classes should not depend on low level classes. Both should depend on abstractions. Abstractions should not depend on the details. The details should depend on the abstractions.
public struct Order {
  public let amount: Double
  public let description: String
  public let createdAt: String
  
  public init(amount: Double, description: String, createdAt: String) {
    self.amount = amount
    self.description = description
    self.createdAt = createdAt
  }
}

public protocol OrderStorage {
  func saveOrder(order: Order)
}

/// high-level this class was broken rules
//public class Handler {
//  private let orderDatabaseOperation: OderDatabaseOperation
//
//  public init(database: OderDatabaseOperation) {
//    self.orderDatabaseOperation = database
//  }
//
//  public func saveOrder(order: Order)  {
//    guard order.amount != 0 else {
//      return
//    }
//
//    // save to database
//    orderDatabaseOperation.saveOrderr(order: order)
//  }
//}
/// high-lavel
public class Handler {
  private let orderStorage: OrderStorage
  
  public init(orderStorage: OrderStorage) {
    self.orderStorage = orderStorage
  }
  
  public func saveOrder(order: Order)  {
    guard order.amount != 0 else {
      return
    }
    
    // save to database
    orderStorage.saveOrder(order: order)
  }
}

// low-level
public class OderDatabaseOperations: OrderStorage {
  
  public init() {}
  
  public func saveOrder(order: Order) {
    // save orders to database
    print("Order: \(order.description) of \(order.amount) saved")
  }
}

About

SOLID

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages