Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

💎 The Principles of OOD (SOLID) based on Uncle Bob articles.

License

NotificationsYou must be signed in to change notification settings

ochococo/OOD-Principles-In-Swift

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

51 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

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:

protocolOpenable{mutatingfunc open()}protocolCloseable{mutatingfunc close()}// I'm the door. I have an encapsulated state and you can change it using methods.structPodBayDoor:Openable,Closeable{privateenumState{case opencase closed}privatevarstate:State=.closedmutatingfunc open(){        state=.open}mutatingfunc close(){        state=.closed}}// I'm only responsible for opening, no idea what's inside or how to close.finalclassDoorOpener{privatevardoor:Openableinit(door:Openable){self.door= door}func execute(){        door.open()}}// I'm only responsible for closing, no idea what's inside or how to open.finalclassDoorCloser{privatevardoor:Closeableinit(door:Closeable){self.door= door}func execute(){        door.close()}}letdoor=PodBayDoor() // ⚠️ Only the `DoorOpener` is responsible for opening the door.letdoorOpener=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.letdoorCloser=DoorCloser(door: door)doorCloser.execute()

✋ The Open Closed Principle

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

Example:

protocolShooting{func shoot()->String}// I'm a laser beam. I can shoot.finalclassLaserBeam:Shooting{func shoot()->String{return"Ziiiiiip!"}}// I have weapons and trust me I can fire them all at once. Boom! Boom! Boom!finalclassWeaponsComposite{letweapons:[Shooting]init(weapons:[Shooting]){self.weapons= weapons}func shoot()->[String]{return weapons.map{ $0.shoot()}}}letlaser=LaserBeam()varweapons=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.finalclassRocketLauncher:Shooting{func shoot()->String{return"Whoosh!"}}letrocket=RocketLauncher()weapons=WeaponsComposite(weapons:[laser, rocket])weapons.shoot()

👥 The Liskov Substitution Principle

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

Example:

letrequestKey:String="NSURLRequestKey"// I'm a NSError subclass. I provide additional functionality but don't mess with original ones.classRequestError:NSError{varrequest:NSURLRequest?{returnself.userInfo[requestKey]as?NSURLRequest}}// I fail to fetch data and will return RequestError.func fetchData(request:NSURLRequest)->(data:NSData?, error:RequestError?){letuserInfo:[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?){letrequest=NSURLRequest()letresult=fetchData(request: request)return(result.data, result.error)}letresult=willReturnObjectOrError()// Ok. This is a perfect NSError instance from my perspective.leterror:Int?= result.error?.code// ⚠️ But hey! What's that? It's also a RequestError! Nice!iflet requestError= result.erroras?RequestError{    requestError.request}

🍴 The Interface Segregation Principle

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

Example:

// I have a landing site.protocolLandingSiteHaving{varlandingSite:String{get}}// I can land on LandingSiteHaving objects.protocolLanding{func land(on:LandingSiteHaving)->String}// I have payload.protocolPayloadHaving{varpayload:String{get}}// I can fetch payload from vehicle (ex. via Canadarm).protocolPayloadFetching{func fetchPayload(vehicle:PayloadHaving)->String}finalclassInternationalSpaceStation: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).finalclassOfCourseIStillLoveYouBarge:LandingSiteHaving{letlandingSite="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.finalclassSpaceXCRS8:Landing,PayloadHaving{letpayload="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"}}letcrs8=SpaceXCRS8()letbarge=OfCourseIStillLoveYouBarge()letspaceStation=InternationalSpaceStation()spaceStation.fetchPayload(vehicle: crs8)crs8.land(on: barge)

🔝 The Dependency Inversion Principle

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

Example:

protocolTimeTraveling{func travelInTime(time:TimeInterval)->String}finalclassDeLorean:TimeTraveling{func travelInTime(time:TimeInterval)->String{return"Used Flux Capacitor and travelled in time by:\(time)s"}}finalclassEmmettBrown{privatelettimeMachine: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)}}lettimeMachine=DeLorean()letmastermind=EmmettBrown(timeMachine: timeMachine)mastermind.travelInTime(time:-3600*8760)

Info

📖 Descriptions from:The Principles of OOD by Uncle Bob

Releases

No releases published

Sponsor this project

    Packages

    No packages published

    Contributors4

    •  
    •  
    •  
    •  

    [8]ページ先頭

    ©2009-2025 Movatter.jp