https://developer.apple.com/videos/play/wwdc2016/419/
POP(protocol oriented programming)의 장점이 무엇이냐고 묻는다면,
Local Reasoning에 있다. Local Reasoning이란 코드를 여기 저기 살펴 보지 않아도 이해할 수 있을 수 있는 지를 말한다. 그 이유는 값 타입을 기반으로 설계되어지기 때문에 다른데서 수정될 여지가 적고, 캡슐화가 더 잘 되기 때문이다.
protocol oriented programming은 Vlaue type을 어떻게 더 잘 사용할 지에 대한 얘기기도 해서 protocol 뿐만아니라 Enum, Struct, Generic 과 같은 타입을 어떻게 사용해야는지 얘기한다. 또한 Class의 상속을 지양하기 때문에 (ref type이니까) 합성의 방법으로 코드를 설계하는 법 역시 중요하다.
합성과 캡슐화에 대한 얘기는 객체지향을 공부하면서도 들었던 내용인데 protocol oriented programming은 그러한 점에서 Swift가 객체지향 설계를 체화하는 방법이라고 할 수 있다.
영상에서는 Sample App인 Lucide Dreams를 가지고 Model, View, Controller에서 Value type을 사용해 코드를 개선한다.
Dream이라는 객체가 있는데 꿈에 대한 이미지와 설명 같은 속성들이 있다. 이를 Struct로 선언하여 활용하는데, 주로 복잡한 모델에서는 class를 사용해야한다는 편견이 있다. 하지만 Struct를 사용하면 Local Reasoning을 할 수 있고 암시적으로 Sharing되지 않기 때문에 이점이 있다.

위 레이아웃을 재사용하고 싶을 땐 protocol로 Layout을 만들고 원하는 Child View에 implement 시킬 수 있다.
Cell Layout을 Protocol로 만들 때 큰 장점은 UIView나 SKNode(sprite kit node)와 같이 공통 부모가 없는 클래스들도 하나로 묶어 레이아웃을 재사용할 수 있다는 것이다!
또 특정 TableviewCell 과 같은 부모 뷰에 상속받는 것이 아니기 때문에 부모 뷰가 무슨 일을 하는지 알 필요도 없다.

여기서 Generic이 사용될 수 있는 부분은 타입 안정성을 위해서 이다.
그림의 레이아웃에서 주황색 view와 노란색 view의 타입이 일치하게 만들고 싶을 때 Generic을 사용해 <Child: Layout> 과 같은 방식으로 선언하고 두 view에 Child를 사용하면 된다.
Generice의 이점은 타입 컨트롤 뿐만아니라 컴파일러가 우리가 무슨 코드를 작성할지 예상 가능하기 때문에 최적화의 이점도 있다.

이번에는 같은 레이아웃을 사용하되 다형적으로 왼쪽 주황색 View가 하나짜리와 여러개가 쌓여진 레이어로 구성된 View 두가지로 사용할 수 있게 만들고 싶다.
둘은 같은 레이아웃을 가지고 있기 때문에 코드를 공유할 수 있다.
어떻게 공유할 수 있을까?
상속으로 코드를 공유할 수 있게지만 영상에서 추천하는 방법은 합성이다!
합성은 두가지 작은 모듈을 합쳐서 하나의 큰 모듈을 만드는 방법이다.
합성을 사용할 때 Class 형태의 뷰를 사용하면 Drawing 없이 Layout으로만 존재하는 뷰가 만들어지고 이는 심한 낭비이다. (Class는 비싸기 때문에..!)
하지만 Vlaue 타입을 사용한다면 가볍기 때문에 합성해도 낭비가 크게 발생하지 않는다.

위 코드에서는 DecoratingLayout에 CascadingLayout을 합성했다.
여기서 Layout을 구성할 때 associatedType을 사용하면 타입을 확정 시켜 타입 안정성을 지킬 수 있다.
Undo 기능 구현
어떤 뷰에서 undo가 이루어질 때 변해야하는 속성들 마다 하나씩 undo를 하는 기능을 구현하는 것은 실수할 가능성이 높다. 까먹고 undo가 구현되지 않거나 빼먹는 문제가 있을 수 있기 때문이다.
영상에서는 Model이라는 Struct를 만들어 undo가 구현되는 하나의 single code path를 만들고 undo가 구현될 필요가 있는 속성들은 이 Model 안으로 들어간다. 또 이 Model 중 하나의 속성이 바뀌더라도 Model 전체를 Stack에 저장하는 방식으로 undo를 구현할 수 있다.

UI State 관리
State 관리 역시 View의 State를 옮길 때 몇가지 속성을 되돌리는 것을 까먹거나 할 수 있는 여지가 있다. 이를 Enum으로 관리하면 mutually exclusive하게 관리할 수 있다. 서로 상호 배타적으로 상태를 유지할 있다는 것이다. 그러면 이 State도 저 State도 아닌 중간 값에 위치하는 것을 방지 할 수 있다. 열거형에서 case 별로 state 상태에 따른 연관값을 두어 속성을 관리할 수 있다.
