프로토콜 지향 프로그래밍(Protocol - Oriented - Programming)
객체지향 프로그래밍
장점
- 상속을 이용한 코드의 재사용성
단점
- 하나의 클래스만 상속이 가능하다.(다중 상속 불가능)
- 상위클래스의 메모리 구조를 따라갈 수 밖에 없음.(필요하지 않은 속성/메서드도 상속된다.)
- 클래스(참조타입)에서만 사용 가능
프로토콜 지향 프로그래밍
스위프트의 표준 라이브러리의 타입과 관련된 것을 살펴보면 대부분 구조체로 구현이 되어있다.
객체지향 프로그래밍 패러다임에 기반을 둔 언어는 대부분 클래스의 상속을 사용해 타입에 공통된 기능을 구현한다.
상속도 되지 않는 구조체로 다양한 공통 기능을 가질수 있는가..
이는 프로토콜과 익스텐션으로 이루어져있다.
프로토콜은 특정 역할을 수행하기 위한 메서드, 프로퍼티, 기타 요구사항의 청사진이다.
프로토콜을 채택(Adoped)한 타입은 프로토콜이 요구하는 기능을 준수(Conform)해야 한다.
프로토콜을 정의하고 여러 타입에서 이 프로토콜을 준수하게 만들어 타입마다 똑같은 메서드, 프로퍼티, 서브스크립트를 구현해야 하긴 어렵다. 많은 중복코드가 생길것이고 유지보수는 매우 힘들어질것이다.
이 때에 필요한게 익스텐션과 프로토콜의 결합이다.
자격증과 같은 개념
- 어디서도 채택을 하면 요구사항을 구현해서 사용할 수 있다.
- 여러개의 프로토콜 채택 가능(다중 상속과 유사)
- 메모리 구조에 대한 특정 요구사항 없음.
- 필요한 속성 / 메서드만 채택할 수 있다 (@optional)
- 모든 타입에서 채택 가능
- 프로토콜의 확장을 통해 구체적인 정의가 가능하고 재정의화를 사용할 수 있다.
- 타입으로 사용이 가능하다.
- 조합의 장점을 살려서 보다 나은 구성/재사용성을 높일 수 있다.
- 애플이 미리 만들어놓은 String, UIView, UILabel 등에도 채택하여 소급적 활용이 가능하다.
프로토콜의 선언
protocol Remote {
func turnOn()
func turnOff()
}
Remote를 채용한 프로토콜은 위의 두 개의 함수를 필수적으로 구현해야한다.
프로토콜의 확장
프로토콜의 확장을 이용하면 프로토콜에서 정의한 함수들에 대한 기본 구현을 정의할 수 있다.
타입 내에서 프로토콜을 구현해도 되지만, 타입 내에서 구현하지 않고 확장에서 구현했다면 확장에서 구현한 기능이 기본적으로 제공된다.
extension Remote {
func turnOn() {
print("리모콘 켜기")
}
func turnOff() {
print("리모콘 끄기")
}
func doAnotherAction() {
print("리모콘 또 다른 동작")
}
}
프로토콜의 채용
class Person: Remote{
프로토콜 확장의 적용 제한
extension Laser where Self: Remote{
..
}
class Phone: Remote, Laser{
}
Self는 자신을 채용한 타입 자체를 의미한다 그렇다면 여기선 Phone클래스가 Self가 된다.
Laser 프로토콜의 확장은 Laser프로토콜을 채용한 경우, Remote프로토콜을 함께 채용한 경우에만 적용된다는 뜻이다
==> where절을 통해 특정 프로토콜을 채용한 경우에만 확장이 적용된다.
class Phone: Laser{
처럼 Laser만 채용하고 Remote를 채용하지 않은 경우엔 Laser확장이 적용되지 않는다.