애플은 2015년 WWDC에서 Swift 2.0을 출시하고, 이를 프로토콜 지향 프로그래밍 언어(Protocol-Oriented Language)라고 소개했습니다.
하지만 기존의 객체 지향 언어는 많이 들어봤어도, 새로운 패러다임인 프로토콜 지향 언어는 생소할거라 생각합니다.
이 패러다임을 이해하기 위해서는 먼저, 프로토콜에 대한 이해가 필요합니다.
애플 공식 문서 Swift Language Guide에서 프로토콜을 아래와 같이 설명하고 있습니다.
A protocol defines a blueprint of methods, properties, and other requirements that suit a particular task or piece of functionality.
프로토콜은 특정 작업에 적합한 메서드, 프로퍼티 또는 다른 요구사항을 정의하는 청사진이다.
The protocol can then be adopted by a class, structure, or enumeration to provide an actual implementation of those requirements.
프로토콜은 클래스, 구조체, 열거형의 요구사항 구현을 위해 채택되어질 수 있다.
요약하자면, 프로토콜은 특정 작업에 적합한 메서드, 프로퍼티 등을 정의해놓은 설계도면이고,
이는 클래스, 구조체, 열거형에 채택되어 구현되어집니다.
프로토콜을 구현하는 일은 마치 건축하기 전, 건축물의 설계도면을 구상하는 것 같은 역할을 합니다.
프로토콜은 아래와 같은 문법으로 구현할 수 있습니다.
protocol SomeProtocol {
// Definition of protocol
}
클래스, 열거형, 구조체이 프로토콜을 채택할 때는 타입의 이름 옆에 프로토콜 이름을 적어주면 됩니다. 또, 여러 프로토콜을 채택할 때는 콤마(,)를 이용해 나열하여 작성하여 구현할 수 있습니다.
struct SomeStruct: SomeProtocol, AnotherProtocol {
// Definition of Struct
}
var
)로 선언되어야 합니다.protocol SomeProtocol {
var mustBeSettable: String { get set }
var doesNotNeedToBeSettable: String { get }
}
static
키워드를 붙여줘야합니다.protocol AnotherProtocol {
static var typeProperty: String { get set }
}
간단한 예시로, 아래 프로토콜을 채택하고 있는 구조체를 구현해보겠습니다.
protocol Blossomable {
var blossomSeason: String { get }
}
위 Blossomable
프로토콜은 blossomSeason
이라는 gettable 프로퍼티를 정의하고 있습니다.
struct Flower: Blossomable {
var blossomSeason: String
}
let daisy = Flower(blossomSeason: "April")
print(daisy.blossomSeason)
// daisy.blossomSeason = "April"
그리고 이를 채택하고 있는 Flower 구조체는 프로토콜에서 정의하고 있는 blossomSeason
프로퍼티를 구현해주었습니다.
이렇게 프로토콜의 요구사항들을 모두 충족한 상태를 프로토콜을 준수(conform)했다.라고 합니다. 위 예시로 말하자면, Flower
구조체는 Blossomable
프로토콜을 준수했다고 말할 수 있습니다.
static
키워드를 붙여줘야합니다.mutating
키워드를 붙여줘야합니다.protocol SomeProtocol {
static func someTypeMethod()
mutating func someModifyMethod()
}
protocol Blossomable {
var blossomSeason: String { get }
func blossom() -> String
}
struct Flower: Blossomable {
var blossomSeason: String
var presentSeason: String
func blossom() -> String {
guard blossomSeason == presentSeason else { return "buds" }
return "blossom"
}
}
let daisy = Flower(blossomSeason: "April", presentSeason: "October")
print(daisy.blossom())
// "buds"
앞선 예제에서 사용했던 Blossomable 프로토콜에 blossom
이라는 메서드를 추가했고, Flower
구조체에 blossom
메서드를 구현해줌으로써 프로토콜을 준수하였습니다.
required
키워드를 붙여줘야 합니다.protocol SomeProtocol {
init(someParameter: String)
애플은 이 프로토콜과 구조체를 주로 사용하여 타입들을 구현했습니다.
애플 공식 문서 Swift Standard Library를 보면 실제로 기본 타입들도 구조체로 구현되어있는 것을 볼 수 있습니다.
하지만 아무리 프로토콜을 이용했다 해도, 상속도 안되는 구조체를 이용해서 구현한 타입들이 어떻게 다양한 공통 기능을 가지게 되는지 의문이 들 수 있습니다.
이 때 등장하는 개념이 바로 Extension입니다.
애플 공식 문서 Swift Language Guide에서 프로토콜을 아래와 같이 설명하고 있습니다.
Extensions add new functionality to an existing class, structure, enumeration, or protocol type. This includes the ability to extend types for which you don’t have access to the original source code (known as retroactive modeling).
익스텐션은 이미 존재하는 클래스, 구조체, 열거형, 프로토콜 타입에 새로운 기능을 추가해준다.
이미 구현되어있어 기존 소스코드에 접근할 수 없는 타입들 역시 확장할 수 있다.
Extensions in Swift can:
- Add computed instance properties and computed type properties
- Define instance methods and type methods
- Provide new initializers
- Define subscripts
- Define and use new nested types
- Make an existing type conform to a protocol
스위프트에서 확장할 수 있는 것들
- 연산 인스턴스 프로퍼티와 연산 타입 프로퍼티를 추가할 수 있음
- 인스턴스 메서드와 타입 메서드를 정의 할 수 있음
- 새 이니셜라이저를 제공할 수 있음
- 서브스크립트를 정의할 수 있음
- 새로운 중첩 타입들을 정의하고 사용할 수 있음
- 이미 존재하는 타입을 프로토콜에 준수하게 만들 수 있음
앞서 설명한 프로토콜은 채택한 타입에게 프로토콜이 요구하는 기능들을 강제로 구현하게 만들고,
익스텐션은 프로토콜을 확장하여 프로토콜이 요구하는 기능들을 미리 구현할 수 있게 합니다.
그래서 프로토콜과 익스텐션을 잘 조합하여 초기구현을 잘해놓는다면, 타입에 프로토콜을 채택하는 것만으로 프로토콜이 요구하는 기능을 가지게 할 수 있습니다.
이것이 바로 프로토콜 지향 언어의 프로그래밍 방식입니다.
즉, 프로토콜 지향 프로그래밍은 "프로토콜과 익스텐션의 결합"으로 이루어집니다.
앞서 예시로 든 Blossomable
프로토콜은 Flower
타입에만 채택되었지만, 만약 다른 타입들에게도 채택하게 된다면 프로토콜에서 요구하는 기능들을 타입마다 전부 구현해주어야 할 것 입니다. 이런 코드의 중복을 피하기 위해 Extension을 이용합니다.
protocol Blossomable {
var blossomSeason: String { get set }
var presentSeason: String { get set }
func blossom() -> String
}
extension Blossomable {
func blossom() -> String {
guard blossomSeason == presentSeason else { return "buds" }
return "blossom"
}
}
struct Flower: Blossomable {
var blossomSeason: String
var presentSeason: String
}
struct Person: Blossomable {
var blossomSeason: String
var presentSeason: String
}
let daisy = Flower(blossomSeason: "April", presentSeason: "November")
print(daisy.blossom())
// "buds"
let eric = Person(blossomSeason: "Young", presentSeason: "Youth")
print(eric.blossom())
// "buds"
Extension을 이용하여 blossom
메서드를 구현하고나니, Blossomable
프로토콜을 채택하고있는 다른 타입들은 요구 메서드를 정의하지 않아도 오류가 나지 않고, blossom
메서드도 사용가능한 걸 볼 수 있습니다.
객체지향 프로그래밍(OOP)이랑 크게 다르지도 않은 것 같은데, 왜 굳이 프로토콜지향 프로그래밍(POP)을 배워야 하나요??
우선 이들은 대립적인 개념이 아닙니다. 단지 OOP가 만능이 아니기에, Swift 개발 설계과정에서 발생하는 OOP의 불편한 점을 POP로 해결하길 애플에서 권장하는 것일 뿐입니다.
간단한 예시를 들어 설명하자면,
게임에 나오는 몬스터들을 OOP로 코딩한다고 가정해봅시다.
class Creature {
let name: String
init(name: String) {
self.name = name
}
func fight() {
print("👊")
}
}
몬스터 종류를 구별해 지상을 돌아다니는 몬스터와 하늘을 돌아다니는 몬스터로 나누어 클래스를 생성해보겠습니다.
class LandCreature: Creature {
func walk() {
print("🚶🏻♀️")
}
func run() {
print("🏃🏻")
}
}
class SeaCreature: Creature {
func swim() {
print("")
}
}
지상 몬스터 wolf
를 만들었을 때는 전혀 이상없어 보이지만 바다 몬스터 killerWhale
를 만들었을 때 문제가 발생하게 됩니다.
let wolf = LandCreature(name: "woolf")
wolf.walk() // 🚶🏻♀️
wolf.run() // 🏃🏻
wolf.fight() // 👊
let killerWhale = SeaCreature(name: "killer")
killerWhale.walk() // ??
killerWhale.run() // ??
SeaCreture
클래스는 Creature
클래스를 상속받았기 때문에, walk
메서드와 run
메서드를 사용할 수 있는데, 범고래가 뛰고 걷는건 개발자의 의도가 아니기 때문에, 코드 설계에 문제가 있다고 볼 수 있습니다.
class Creature {
let name: String
init(name: String) {
self.name = name
}
func fight() {
print("👊")
}
}
class LandCreature: Creature {
func walk() {
print("🚶🏻♀️")
}
func run() {
print("🏃🏻")
}
}
그래서 walk
, run
메서드를 LandCreature
클래스의 메서드로 두어 문제를 해결했습니다.
하지만 지상에서 걷고 뛰며, 바다에서 헤엄칠 수 있는 스피노사우르스를 추가하려니 또 다른 문제가 발생했습니다.
class Spinosaurus: LandCreature { }
let spinosaurus = Spinosaurus(name: "spinosaurus")
spinosaurus.swim()
spinosaurus.walk() // error!
spinosaurus.run() // error!
// LandCreature에는 walk, run 메서드가 없다.
스피노사우르스뿐만 아니라 다양한 몬스터들을 추가하다보면 분명 이런 상황을 맞닥드릴 것입니다.
이런 상황에서는 OOP로 접근하는 것이 쉽지 않아 보입니다.
그래서 이번엔 POP로 접근해보겠습니다.
struct Creature {
let name: String
init(name: String) {
self.name = name
}
}
protocol Strikeable {
func fight()
}
extension Strikeable {
func fight() {
print("👊")
}
}
extension Creature: Strikeable { }
Creature
객체의 메서드로 있던 fight
를 Strkieable
프로토콜로 초기구현하여 Creature
에 준수시켰고,
다른 메서드들도 마찬가지로 프로토콜을 통해 초기구현 해주었습니다.
protocol Walking {
func walk()
}
extension Walking {
func walk() {
print("🚶🏻♀️")
}
}
protocol Running {
func run()
}
extension Running {
func run() {
print("🏃🏻")
}
}
protocol Swimming {
func swim()
}
extension Swimming {
func swim() {
print("🚶🏻♀️")
}
}
Swift에서는 다중상속이 안되어 하나의 타입이 여러가지 클래스를 상속 받지 못하지만, 프로토콜은 다양하게 채택할 수 있습니다.
class LandCreature: Creature,
Walking,
Running { }
class Spinosaurus: LandCreature, Swimming { }
let spinosaurus = Spinosaurus(name: "spinosaurus")
spinosaurus.walk()
spinosaurus.run()
spinosaurus.swim()
OOP로 접근했을 때는 복잡해보였던 Spinosaurus
클래스 설계가 POP로 접근하니 쉽게 설계되었습니다.
위 예시처럼 POP를 잘 이용하면 OOP로 접근했을 때의 단점들을 보완해줄 수 있습니다. 이 외에도 OOP의 단점들을 보완해주는 POP의 장점을 나열해보자면,
i) 값 타입(value type)과 참조 타입(reference type)을 자유롭게 사용할 수 있다.
상속을 하기위해서는 참조 타입(reference type)인 class만을 사용함으로써,
값 타입(value type)으로 만들어도 되는 모델을 참조 타입으로만 정의해야한다.
하지만 프로토콜은 struct, class, enum 등의 참조 타입(reference type)과 값 타입 (value type)을 자유롭게 사용할 수 있다.
ii) 여러 개의 프로토콜을 채택할 수 있다.
상속 구조에서는 다중상속이 되지않는다. 즉, 하나의 부모 클래스만을 가질 수 있다. 하지만 프로토콜은 여러 개의 프로토콜을 채택할 수 있어 타입의 기능 확장에 유리하다. 또 프로토콜을 채택하는 각각의 타입이 서로 독립적이기 때문에, 상속의 문제점으로 언급되는 죽음의 다이아몬드에서도 자유롭다.
객체지향 프로그래밍은 객체 그 자체에 집중하고, 프로토콜지향 프로그래밍은 객체의 기능이나 행동에 집중하는 것을 볼 수 있습니다. 이런 패러다임의 관점 차이를 고려한다면, 어느 패러다임이 더 우월한지를 생각하는 것보다 어느 패러다임이 현재 상황에 더 적합한지를 생각하게 되는 것 같습니다.
그리고 이런 패러다임의 이해를 바탕으로 적재적소에 OOP와 POP를 활용하는게 개발자의 역량이라고 말할 수 있을 것 같습니다.
https://wlaxhrl.tistory.com/77
https://tsh.io/blog/protocol-oriented-programming-swift/
https://blog.yagom.net/529/
https://docs.swift.org/swift-book/LanguageGuide/TheBasics.html
Regards for those content and additionally awesome helpful hints.. still Document equally suspect that exertions is normally crucial element of possessing financial success. view publisher site
In fact dependable, fantastic, fact-filled advice in this case. A items Have let down, and that also clearly is valid in this case to boot. Most people consistently can make for a worthwhile read through. How can you show So i am floored?: )#) Cultivate the nice content pieces. bulk bags
Wow i can say that this is another great article as expected of this blog.Bookmarked this site.. dj booking agency
The net will be bogged straight down together with fake sites without genuine concept nevertheless the submit has been great and also worth the particular examine. Many thanks regarding revealing this kind of with me at night. Commercial Iron Railings
I really appreciate this wonderful post that you have provided for us. I assure this would be beneficial for most of the people. dallas sober living
Thanks for taking the time to discuss this, I feel strongly about it and love learning more on this topic. If possible, as you gain expertise, would you mind updating your blog with extra information? It is extremely helpful for me. Thruster finance
An interesting dialogue is price comment. I feel that it is best to write more on this matter, it may not be a taboo topic however usually individuals are not enough to talk on such topics. To the next. Cheers. ดูบอลสด
Superbly written article, if only all bloggers offered the same content as you, the internet would be a far better place.. Learn More
Great Information sharing .. I am very happy to read this article .. thanks for giving us go through info.Fantastic nice. I appreciate this post. living room radiators
The website is looking bit flashy and it catches the visitors eyes. Design is pretty simple and a good user friendly interface. уеб линк
We've just lately commenced a new web site, the details anyone present on this internet site features made it easier for us drastically. Cheers pertaining to your occasion & operate. 분당셔츠룸
Awesome article! I want people to know just how good this information is in your article. It’s interesting, compelling content. Your views are much like my own concerning this subject. barrier gate oem
Hello I am so delighted I located your blog, I really located you by mistake, while I was watching on google for something else, Anyways I am here now and could just like to say thank for a tremendous post and a all round entertaining website. Please do keep up the great work. the best deal
Thank you for taking the time to publish this information very useful! IPTV Aanbieders
I wanted to thank you for this great read!! I definitely enjoying every little bit of it I have you bookmarked to check out new stuff you post. celer bridge
I found so many interesting stuff in your blog especially its discussion. From the tons of comments on your articles, I guess I am not the only one having all the enjoyment here! keep up the good work... slot depo via qris
I haven’t any word to appreciate this post.....Really i am impressed from this post....the person who create this post it was a great human..thanks for shared this with us. slot thailand
Nice post! This is a very nice blog that I will definitively come back to more times this year! Thanks for informative post. bandar toto macau
If you are looking for more information about flat rate locksmith Las Vegas check that right away. kad jemputan
Very good points you wrote here..Great stuff...I think you've made some truly interesting points.Keep up the good work. email warmup service
I appreciate everything you have added to my knowledge base.Admiring the time and effort you put into your blog and detailed information you offer.Thanks. permainan mod apk
Took me time to read all the comments, but I really enjoyed the article. It proved to be Very helpful to me and I am sure to all the commenters here! It’s always nice when you can not only be informed, but also entertained! เว็บตรง
I was reading some of your content on this website and I conceive this internet site is really informative ! Keep on putting up. best wiper blades in australia
Thank you so much for sharing this great blog.Very inspiring and helpful too.Hope you continue to share more of your ideas.I will definitely love to read. South Carolina Sportsbooks
I appreciate everything you have added to my knowledge base.Admiring the time and effort you put into your blog and detailed information you offer.Thanks. slot gacor gampang menang
You make so many great points here that I read your article a couple of times. Your views are in accordance with my own for the most part. This is great content for your readers. 실시간 스포츠
Hello, this weekend is good for me, since this time i am reading this enormous informative article here at my home. mid fade
I’m going to read this. I’ll be sure to come back. thanks for sharing. and also This article gives the light in which we can observe the reality. this is very nice one and gives indepth information. thanks for this nice article... pokerqq13
I love the way you write and share your niche! Very interesting and different! Keep it coming! バーチャルオフィス 渋谷 おすすめ
Took me time to read all the comments, but I really enjoyed the article. It proved to be Very helpful to me and I am sure to all the commenters here! It’s always nice when you can not only be informed, but also entertained! How to stop house repossession
I have bookmarked your blog, the articles are way better than other similar blogs.. thanks for a great blog! good extracts
I have read all the comments and suggestions posted by the visitors for this article are very fine,We will wait for your next article so only.Thanks! 총판커뮤니티
I can’t believe focusing long enough to research; much less write this kind of article. You’ve outdone yourself with this material without a doubt. It is one of the greatest contents. daftar klik88
I think this is an informative post and it is very useful and knowledgeable. therefore, I would like to thank you for the efforts you have made in writing this article. 대전출장마사지
I think this is an informative post and it is very useful and knowledgeable. therefore, I would like to thank you for the efforts you have made in writing this article. 광주출장마사지
I think this is an informative post and it is very useful and knowledgeable. therefore, I would like to thank you for the efforts you have made in writing this article. 대전출장마사지
I think this is an informative post and it is very useful and knowledgeable. therefore, I would like to thank you for the efforts you have made in writing this article. 서울출장마사지
I really impressed after read this because of some quality work and informative thoughts . I just wanna say thanks for the writer and wish you all the best for coming!.横浜市 リフォーム
I got what you mean , thanks for posting .Woh I am happy to find this website through google. 슬롯사이트
I got what you mean , thanks for posting .Woh I am happy to find this website through google. situs slot terpercaya
Wow, this is really interesting reading. I am glad I found this and got to read it. Great job on this content. I like it. slot demo
I am constantly surprised by the amount of information accessible on this subject. What you presented was well researched and well written to get your stand on this over to all your readers. Thanks a lot my dear.PETIR99 LOGIN
I am very happy to discover your post as it will become on top in my collection of favorite blogs to visit. 團體服外套
I am very happy to discover your post as it will become on top in my collection of favorite blogs to visit. 客製化t恤
Most of the time I don’t make comments on websites, but I'd like to say that this article really forced me to do so. Really nice post! iron tv pro
Wonderful article. Fascinating to read. I love to read such an excellent article. Thanks! It has made my task more and extra easy. Keep rocking. ชมฟุตบอลสด
Wow, What an Outstanding post. I found this too much informatics. It is what I was seeking for. I would like to recommend you that please keep sharing such type of info.If possible, Thanks. 이미테이션 사이트
Good website! I truly love how it is easy on my eyes it is. I am wondering how I might be notified whenever a new post has been made. I have subscribed to your RSS which may do the trick? Have a great day!sell a small business
Excellent and very exciting site. Love to watch. Keep Rocking. Silk
Excellent and very exciting site. Love to watch. Keep Rocking. 51 club game
Thank you a bunch for sharing this with all of us you actually realize what you are talking about! Bookmarked. Please also seek advice from my site =). We could have a hyperlink change contract between us!slot gacor hari ini
Your blog has chock-a-block of useful information. I liked your blog's content as well as its look. In my opinion, this is a perfect blog in all aspects. bokepterbaru
Pretty good post. I just stumbled upon your blog and wanted to say that I have really enjoyed reading your blog posts. Any way I'll be subscribing to your feed and I hope you post again soon. Big thanks for the useful info.nx303 slot
A person's popular music is definitely astounding. You may have quite a few pretty good music artists. I actually need you actually the perfect with being successful. pool covers