All Projects β†’ ochococo β†’ Ood Principles In Swift

ochococo / Ood Principles In Swift

Licence: gpl-3.0
πŸ’Ž The Principles of OOD (SOLID) based on Uncle Bob articles.

Programming Languages

swift
15916 projects
shell
77523 projects
CSS
56736 projects

Projects that are alternatives of or similar to Ood Principles In Swift

OOD-Principles-Kotlin
The Principles of OOD in Kotlin 1.3.61
Stars: ✭ 12 (-99.3%)
Mutual labels:  liskov-substitution-principle, dependency-inversion-principle, interface-segregation-principle, single-responsibility-principle
Design Patterns In Swift
πŸ“– Design Patterns implemented in Swift 5.0
Stars: ✭ 13,146 (+668.77%)
Mutual labels:  computer-science, playground
composing-go-example
Project example demonstrating interface segregation in go
Stars: ✭ 21 (-98.77%)
Mutual labels:  solid, interface-segregation-principle
Curated resources
πŸ“š Curated lists for programming, books, movies, music, games, etc
Stars: ✭ 116 (-93.22%)
Mutual labels:  computer-science
Community Server
Community Solid Server: an open and modular implementation of the Solid specifications
Stars: ✭ 117 (-93.16%)
Mutual labels:  solid
Online Shopping System Advanced
Demo site
Stars: ✭ 127 (-92.57%)
Mutual labels:  computer-science
Kinx
Looks like JavaScript, feels like Ruby, and it is a script language fitting in C programmers.
Stars: ✭ 134 (-92.16%)
Mutual labels:  object-oriented
Foundational Knowledge For Programmers
List of resources about foundational knowledge for programmers (supposed to last a few decades)
Stars: ✭ 115 (-93.27%)
Mutual labels:  computer-science
Algo ds notes
It is a repository that is a collection of algorithms and data structures with implementation in various languages.
Stars: ✭ 1,897 (+10.94%)
Mutual labels:  object-oriented
Vuep.run
πŸƒ An online playground for Vue2.0
Stars: ✭ 125 (-92.69%)
Mutual labels:  playground
Thealgorithms
Algorithms repository.
Stars: ✭ 122 (-92.87%)
Mutual labels:  computer-science
Ios Design Patterns
Learning ground for iOS Design Pattern included with sample projects for MVC, MVP, MVVM, and VIPER
Stars: ✭ 120 (-92.98%)
Mutual labels:  playground
Doodle
A pure Kotlin UI framework for the Web.
Stars: ✭ 127 (-92.57%)
Mutual labels:  object-oriented
Ustc Course
β€οΈδΈ­ε›½η§‘ε­¦ζŠ€ζœ―ε€§ε­¦θ―Ύη¨‹θ΅„ζΊ
Stars: ✭ 11,274 (+559.3%)
Mutual labels:  computer-science
Testdrive
Quickly try out any Swift pod or framework in a playground
Stars: ✭ 1,612 (-5.73%)
Mutual labels:  playground
Fe Foundation
ε‰η«―εΌ€ε‘ε­¦δΉ ζŒ‡ε—
Stars: ✭ 113 (-93.39%)
Mutual labels:  computer-science
Rd3
Playground for React & D3.js
Stars: ✭ 128 (-92.51%)
Mutual labels:  playground
Whats New In Swift 5 1
An Xcode playground that demonstrates the new features introduced in Swift 5.1.
Stars: ✭ 122 (-92.87%)
Mutual labels:  playground
Reading
A list of computer-science readings I recommend
Stars: ✭ 1,919 (+12.22%)
Mutual labels:  computer-science
Pulsesensorplayground
A PulseSensor library (for Arduino) that collects our most popular projects in one place.
Stars: ✭ 126 (-92.63%)
Mutual labels:  playground

The Principles of OOD in Swift 5

A short cheat-sheet with Playground (OOD-Principles-In-Swift.playground.zip).

πŸ‘· Project maintained by: @nsmeme (Oktawian Chojnacki)

Translations

πŸ‡°πŸ‡· Korean: README-ko-KR.md

S.O.L.I.D.

πŸ” The Single Responsibility Principle

A class should have one, and only one, reason to change. (read more)

Example:

protocol Openable {
    mutating func open()
}

protocol Closeable {
    mutating func close()
}

// I'm the door. I have an encapsulated state and you can change it using methods.
struct PodBayDoor: Openable, Closeable {

    private enum State {
        case open
        case closed
    }

    private var state: State = .closed

    mutating func open() {
        state = .open
    }

    mutating func close() {
        state = .closed
    }
}

// I'm only responsible for opening, no idea what's inside or how to close.
final class DoorOpener {
    private var door: Openable

    init(door: Openable) {
        self.door = door
    }

    func execute() {
        door.open()
    }
}

// I'm only responsible for closing, no idea what's inside or how to open.
final class DoorCloser {
    private var door: Closeable

    init(door: Closeable) {
        self.door = door
    }

    func execute() {
        door.close()
    }
}

let door = PodBayDoor()

 
// ⚠️ Only the `DoorOpener` is responsible for opening the door.
let doorOpener = DoorOpener(door: door)
doorOpener.execute()

// ⚠️ If another operation should be made upon closing the door,
// like switching on the alarm, you don't have to change the `DoorOpener` class.
let doorCloser = DoorCloser(door: door)
doorCloser.execute()

βœ‹ The Open Closed Principle

You should be able to extend a classes behavior, without modifying it. (read more)

Example:

protocol Shooting {
    func shoot() -> String
}

// I'm a laser beam. I can shoot.
final class LaserBeam: Shooting {
    func shoot() -> String {
        return "Ziiiiiip!"
    }
}

// I have weapons and trust me I can fire them all at once. Boom! Boom! Boom!
final class WeaponsComposite {

    let weapons: [Shooting]

    init(weapons: [Shooting]) {
        self.weapons = weapons
    }

    func shoot() -> [String] {
        return weapons.map { $0.shoot() }
    }
}

let laser = LaserBeam()
var weapons = WeaponsComposite(weapons: [laser])

weapons.shoot()

// I'm a rocket launcher. I can shoot a rocket.
// ⚠️ To add rocket launcher support I don't need to change anything in existing classes.
final class RocketLauncher: Shooting {
    func shoot() -> String {
        return "Whoosh!"
    }
}

let rocket = RocketLauncher()

weapons = WeaponsComposite(weapons: [laser, rocket])
weapons.shoot()

πŸ‘₯ The Liskov Substitution Principle

Derived classes must be substitutable for their base classes. (read more)

Example:

let requestKey: String = "NSURLRequestKey"

// I'm a NSError subclass. I provide additional functionality but don't mess with original ones.
class RequestError: NSError {

    var request: NSURLRequest? {
        return self.userInfo[requestKey] as? NSURLRequest
    }
}

// I fail to fetch data and will return RequestError.
func fetchData(request: NSURLRequest) -> (data: NSData?, error: RequestError?) {

    let userInfo: [String:Any] = [requestKey : request]

    return (nil, RequestError(domain:"DOMAIN", code:0, userInfo: userInfo))
}

// I don't know what RequestError is and will fail and return a NSError.
func willReturnObjectOrError() -> (object: AnyObject?, error: NSError?) {

    let request = NSURLRequest()
    let result = fetchData(request: request)

    return (result.data, result.error)
}

let result = willReturnObjectOrError()

// Ok. This is a perfect NSError instance from my perspective.
let error: Int? = result.error?.code

// ⚠️ But hey! What's that? It's also a RequestError! Nice!
if let requestError = result.error as? RequestError {
    requestError.request
}

🍴 The Interface Segregation Principle

Make fine grained interfaces that are client specific. (read more)

Example:

// I have a landing site.
protocol LandingSiteHaving {
    var landingSite: String { get }
}

// I can land on LandingSiteHaving objects.
protocol Landing {
    func land(on: LandingSiteHaving) -> String
}

// I have payload.
protocol PayloadHaving {
    var payload: String { get }
}

// I can fetch payload from vehicle (ex. via Canadarm).

protocol PayloadFetching {
    func fetchPayload(vehicle: PayloadHaving) -> String
}

final class InternationalSpaceStation: PayloadFetching {


    // ⚠ Space station has no idea about landing capabilities of SpaceXCRS8.
    func fetchPayload(vehicle: PayloadHaving) -> String {
        return "Deployed \(vehicle.payload) at April 10, 2016, 11:23 UTC"
    }
}

// I'm a barge - I have landing site (well, you get the idea).
final class OfCourseIStillLoveYouBarge: LandingSiteHaving {
    let landingSite = "a barge on the Atlantic Ocean"
}

// I have payload and can land on things having landing site.
// I'm a very limited Space Vehicle, I know.
final class SpaceXCRS8: Landing, PayloadHaving {

    let payload = "BEAM and some Cube Sats"

    // ⚠️ CRS8 knows only about the landing site information.
    func land(on: LandingSiteHaving) -> String {
        return "Landed on \(on.landingSite) at April 8, 2016 20:52 UTC"
    }
}

let crs8 = SpaceXCRS8()
let barge = OfCourseIStillLoveYouBarge()
let spaceStation = InternationalSpaceStation()

spaceStation.fetchPayload(vehicle: crs8)
crs8.land(on: barge)

πŸ” The Dependency Inversion Principle

Depend on abstractions, not on concretions. (read more)

Example:

protocol TimeTraveling {
    func travelInTime(time: TimeInterval) -> String
}

final class DeLorean: TimeTraveling {
	func travelInTime(time: TimeInterval) -> String {
		return "Used Flux Capacitor and travelled in time by: \(time)s"
	}
}

final class EmmettBrown {
	private let timeMachine: TimeTraveling

    // ⚠️ Emmet Brown is given a `TimeTraveling` device, not the concrete class `DeLorean`!
	init(timeMachine: TimeTraveling) {
		self.timeMachine = timeMachine
	}

	func travelInTime(time: TimeInterval) -> String {
		return timeMachine.travelInTime(time: time)
	}
}

let timeMachine = DeLorean()

let mastermind = EmmettBrown(timeMachine: timeMachine)
mastermind.travelInTime(time: -3600 * 8760)

Info

πŸ“– Descriptions from: The Principles of OOD by Uncle Bob

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].