[WWDC15] Protocol Oriented Programming in Swift

brick·2023년 7월 30일
0

Watch WWDC 📽️

목록 보기
4/5
post-thumbnail

Class(OOP) VS Struct, Enum(POP)

  • Encapsulation: 그룹화
  • Access Control: 접근 제어자
  • Abstraction: 추상화
  • Namespace: software가 커지면서 발생하는 충돌을 막아준다
  • Expressive Syntax: 저장/연산 프로퍼티, 메소드, 서브스크립션..
  • Extensibility: 나중에 필요한거 추가 가능

Access Control, Abstraction, Namespace는 특히 복잡성(Complexity)을 관리하게 해줍니다.

  • struct, enum도 할 수 있음.
  • Swift에서 이름 지을 수 있는 모든 type은 일급객체이고 위에 모든 특징을 갖을 수 있다.

  • 상속은 class만 가능

  • 상속을 통해 코드공유, 커스텀 가능(override)

  • struct도 커스텀 가능

  • class는 강력하지만 cost가 크다


The Three Beefs

1. Implicit Sharing

  • 값 타입은 참조를 공유해 의도하지 않은 변화가 발생해 문제될 수 있다.

  • 참조 타입은 cost가 크다

2. Inheritance All Up In Your Business

  • Superclass 1개만 갖을 수 있다.
  • 필요 없는것도 다 상속 받음
  • class를 정의하는 순간 super class를 정해야한다.(extension으로 상속 불가능)
  • Superclass에 저장 프로퍼티가 있다면
    • 상속 받아야만 한다.
    • 저장프로퍼티들을 초기화 해줘야한다.
    • superclass의 invariant를 깨면안된다.
  • method들이 override될 건가 알아야한다.(final 키워드 명시)
  • cocoa에서 delegate 패턴을 사용하는 이유입니다.

3. Lost Type Relationships

  • Ordered의 precedes의 구현부에 어쩔수 없이 불안한 구현
  • Number의 precede의 other은 Label이 될 수 도 있다.(static type safety hole)

  • as! ASubclass은 code smell 이다.
  • as! ASubclass은 type relationship이 손상됐음을 의미한다.
  • Swift는 정적 타입 언어로 변수, 상수의 타입이 컴파일 시점에 결정되는데 타입 캐스팅을 사용하면 런타임에 타입이 정해져 캐스팅에 실패하는 경우 런타임에 오류가 발생할 수 있다.

  • protocol로 하면됨

Swift Is a Protocol-Oriented Programming Language


Start with a Protocol

Your first stop for new abstractions

  • Ordered의 불필요한 구현부 삭제(fatal error 신경쓰지 않아도 됨)


  • override 여부를 신경쓰지 않아도 됨
  • 상속을 사용하지 않음으로 class -> struct로 변경

  • 강제 타입캐스팅(static type safety hole) 제거
  • Self는 자기 자신의 타입을 나타낸다.

Using Our Protocol

  • Ordered는 Label이 될 수 도있고 Number가 될수도있는 heterogeneous인 array라 컴파일러가 Homogeneous인 array로 바꾸라고한다.

  • generic을 사용하면 Homogeneous인 array로 인식시킬 수 있다.


Protocols and Generics for Testability

  • mocks은 테스팅 코드를 세부 구현과 연결해야 하지만 프로토콜은 연결을 끊을 수 있어 테스트하기 용이합니다.

  • protocol은 우리에게 언어에 의해 강요되는 원칙적인 interface를 제공하기도 하고 우리가 필요한 도구들을 연결할 수 있는 hook을 제공하기도 합니다.

  • extension을 사용해 반복되는 구현을 한번만 구현해 사용한다.

  • circleAt은 요구사항에 있고, extension에 구현
  • rectangleAt은 요구사항에 없고, extension에 구현

  • type inference을 시킬 경우에는 둘다 새로 커스텀한게 실행된다.

  • type annotation 하면 요구상항에 없는 retangleAt은 커스텀한 부분이 아니라 protol의 extension에 구현한 부분이 실행된다.

More Protocol Extension Tricks

Scenes from the standard library and beyond

Constrained extensions

  • 어떤 collection의 요소들은 == 로 비교할 수 없다.

  • where을 사용해 Equatable Protocol을 따르는 element들만 연산할 수 있게 수정

Retroactive adaption

  • Int는 Ordered 프로토콜을 채택하지 않아 사용이 불가능함

  • Int, String 이 Ordered 프로토콜을 채택하게해 사용가능하게 함

  • Comparable 프로토콜에는 '<' 연산자가 이미 존해한다.
  • Comparable에서 extension을 통해 precedes를 구현해 개선

  • Comparable을 확장해 Double 타입이 precedes 메소드를 사용할 수 있지만 Ordered 프로토콜을 채택하지 않아 Double 타입에서 binarySearch 메소드는 사용 불가능하다

  • constrained extension 사용해 Ordered 확장해 Ordered를 채택한 타입만 precedes 메소드와 binarySearch 메소드를 사용할 수 있게 함

Generic beautification

  • Swift1 의 fully generallized binary search

  • Swift2 에서 Protocol을 사용해 개선

Interface generation

  • Protocol을 채택하면 extension에 구현된 인터페이스들 사용가능

Building bridges between the static and dynamic worlds

  • drawable 배열을 비교할 수 없다.

  • 배열의 count 가 같고 하나씩 비교해 같은지 확인
  • Drawable은 Equatable 프로토콜을 채택하지 않아서 == 연산자로 비교할 수 없다.

  • Equatable 프로토콜을 Self를 사용해 비교(Static Dispatch, Homogeneous)하는데 Drawable은 Circle이 될수도 Polygon이 될수도 있어(Dynamic Dispatch, Heterogeneous)서 충돌한다.

  • isEqualTo 메소드를 사용해 비교한다.

  • extension을 통해 다운 캐스팅을 통해서 type을 변형하면 Equatable을 채택하고 Self를 사용해 비교할 수 있다.
  • Static Dispatch -> Dynamic Dispatch로 변경
  • Heterogeneous -> Homogeneous로 변경

They(Classes) do have their place...

implicit한 공유가 필요할 때

  • 복사나 비교가 의미없는상태(Singleton 처럼 한번 만들어 놓고 쓰는거 말하는거 같음)(e.g., Window)
  • 인스턴스의 생명주기가 외부요인과 관련있을때(e.g., TemporaryFile)
    • reference type은 안전한 identity가 있어 외부의 entity와 correspond하는 먼가를 만든다면 참조 타입을 사용해야 한다.
  • 인스턴스는 데이터의 구조를 정의하고 상태를 저장하는데 사용되고 메서드는 해당 객체가 아닌 외부에서 수행한다.(e.g., CGCContext)

  • 주의 사항
    • final로 선언
    • base class 없이 Protocol 사용

Don't fight the system

  • 프레임워크를 바꾸려고 하지마라

On the other hand, be circumspect

  • software 안에서 구성요소가 너무 커지게 하면안된다.
  • class를 사용하기전에 class를 사용하지 않는 방법을 고려해 봐라

참고

0개의 댓글