좀더 명확한 정보를 이해하기 위해 특정 절차나 물체를 의도적으로 생략하거나 감춤으로써 복잡성을 극복
추상화는 사물의 본질에 집중하여 복잡성을 극복
첫 번째 차원 : 구체적인 사물들 간의 공통점은 취하고 차이점을 버리는 일반화하여 단순화
두번째 차원 : 중요한 부분을 강조하기 위해 불필요한 세부 사항을 제거함으로써 단순화
개념 이란?
공통점을 기반으로 객체들을 묶기 위한 그릇
객체를 여러 그룹으로 분류
개념의 세가지 관점
심볼 : 개념을 가리키는 간략한 이름 또는 명칭
내연 : 개념의 완전한 정의, 객체가 개념에 속하는지 여부 파악
외연 : 개념에 속하는 모든 객체의 집합
객체의 분류
분류란?
객체의 특정한 개념을 적용하는 작업
첫번째 차원 (일반화) : 하트 왕, 하트 왕비, 정원사, 병사 등을 트럼프라는 개념으로 묶어 객체 간의 차이를 무시하고 공통점만 취함
두번째 차원 (불필요한 세부사항 제거) : 트럼프 객체 집합의 공통점 중에서도 중요한 특징은 몸이 납작하고 네모난 모서리에 팔 다리가 달려있다는 것이다. 그 외의 사항들은 문맥상 어떤 도움도 되지 않기 때문에 불필요한 세부 사항을 제거
타입
타입 = 개념
데이터 타입
메모리 내에 저장된 데이터의 종류를 분류하는데 사용하는 메모리 집합에 관한 메타데이터
데이터에 대한 분류는 암시적으로 어떤 종류의 연산이 해당 데이터에 대해 수행될 수 있는지 결정
객체의 타입
어떤 객체가 어떤 타입에 속하는지 결정하는 것은 객체의 행동, 어떤 객체들이 동일한 행동을 수행할 수 있다면 동일 타입으로 분류
객체의 내부적인 표현은 외부로부터 철저하게 감춰진다, 객체의 행동을 가장 효과적으로 수행할 수 있다면 객체 내부의 상태를 어떤 방식으로 표현해도 무방
행동
다형성 : 동일한 타입에 속한 객체는 내부의 데이터 표현 방식이 다르더라도 동일한 메시지를 수신하고 이를 처리할 수 있다. 다형성이란 동일한 요청에 대해 서로 다른 방식으로 응답할 수 있는 능력을 뜻한다. 동일한 메시지를 서로 다른 방식으로 처리하기 위해서는 객체들은 동일한 메시지를 수신할 수 있어야하기 때문에 결과적으로 다형적인 객체들은 동일한 타입(또는 타입 계층)에 속하게 된다.
캡슐화 : 데이터 내부 표현 방식과 무관하게 행동만이 고려 대상이라는 사실은 외부에 행동만을 제공하고 데이터는 감춰야 한다는 것을 의미한다. 이 원칙을 흔히 캡슐화라고 한다. 공용 인터페이스 뒤로 데이터를 캡슐화하라는 격언은 객체를 행동에 따라 분류하기 위해 지켜야 하는 기본적인 원칙이다. 데이터가 캡슐의 벽을 뚫고 객체의 인터페이스를 오염시키는 순간 객체의 분류 체계는 급격히 위험에 노출되고 결과적으로 유연하지 못한 설계를 낳는다.
책임 주도 설계(Responsibility-Driven Design) : 객체가 외부에 제공해야 하는 행동을 먼저 생각해야 한다. 이를 위해서는 객체가 외부에 제공해야 하는 책임을 결정하고 그 책임을 수행하는 데 적합한 데이터를 나중에 결정한 후, 데이터를 책임을 수행하는 데 필요한 외부 인터페이스 뒤로 캡슐화해야 한다. 이러한 설계 방법에 대해 프레임워크를 제공하는 것이 책임 주도 설계이다.
타입의 계층
일반화 : 포괄적인 의미를 내품는 일반적인 개념 ( 트럼프 )
특수화 : 일반적인 개념보다 범위가 더 좁은 특수한 개념 ( 트럼프 인간 )
슈퍼타입과 서브타입
슈퍼타입 : 일반적인 타입
서브타입 : 특수한 타입
정적 모델
타입은 시간에 따라 동적으로 변하는 객체의 상태를 시간과 무관한 정적인 모습으로 다룰 수 있게 해줌
객체의 상태에 복잡성을 부과하는 시간이라는 요소를 제거하여 시간에 독립적인 정적 모습으로 객체를 생각할 수 있게 해줌
타입은 시간에 따른 객체의 상태 변경이라는 복잡성을 단순화할 수 있는 효과적인 방법
동적 모델과 정적모델
동적모델 : 객체가 특정 시점에 구체적으로 어떤 상태를 가지는 지 표현하는 스냅샷처럼, 객체가 살아 움직이는 동안 상태가 어떻게 변하고 어떻게 행동하는지를 포착하는 것
정적모델 ( 타입 모델 ) : 객체가 가질 수 있는 모든상태와 모든 행동을 시간에 독립적으로 표현하는 것
클래스와 타입은 동일하지 않다
타입은 객체 분류를 위해 사용되는 개념이고, 클래스는 타입을 구현할 수 있는 여러 매커니즘 중 하나일 뿐
📝 감상 및 리뷰
내용이 점점 딥해진다고 생각 들음
타입을 행동 중심으로 바라보며 클래스와의 차이를 명확히 이해할 수 있었.
객체지향에서 설계의 근본을 다시 생각하게 해주었습니다
🛠️ 실무/프로젝트 적용
행동 중심의 타입 설계를 통해 프로젝트의 유지보수를 용이하게 하고, 코드의 유연성과 확장성을 확보
// customPopup띄우는 한 객체의 일부 코드
class PopupView {
// ... BlackBox
func showPopupSingleButton(on view: UIView, message: String, confirmAction: @escaping () -> Void = { return }) {
if singleButtonPopup == nil {
singleButtonPopup = SingleButtonPopupView(frame: .zero)
}
singleButtonPopup?.messageLabelSetting(message: message)
singleButtonPopup?.show(on: view)
singleButtonPopup?.confirmAction = confirmAction
}
// ... BlackBox
}
// 사용하는 쪽
class MainViewController {
// ... BlackBox
PopupView.showPopupSingleButton(on: self?.view ?? UIView(), message: "다시 시도해 주세요.")
// ...BlackBox
}
MainViewController 는 함수(메세지)를 통해 popupView객체에게 “다시 시도해 주세요.” 라는 행동을 요청함
showPopupSingleButton() 함수는 메세지를 수신한 후 상태를 결정(팝업을 띄움) 함
위의 과정에서 MainViewController는 “다시 시도해 주세요.” 문구의 팝업을 띄워줘 라고 요청을 한 후, 그에 대한 결과(상태)에 대해 관여를 하지 않음 PopupView는 요청메세지를 수신한 후 내부에서 자율적으로 자신의 상태를 변경하고 요청에 대한 상태를 결정함
🔍 추가 자료
함수에서 리턴값으로 변경된 “상태”를 바로 읽어드리는 것은 올바른 객체지향적 설계가 아닌것인가?
캐시어가 주문을 받고, 동시에 직접 커피를 제조해서 손님에게 전달할 수 있다 ⇒ 대체가능성
책임을 수행하는 방법은 각 객체가 자율적으로 선택할 수 있다
예를들어, 아이스아메리카노를 주문할때, 손님이 직접 “얼음을 먼저 넣으시구요 물을 반만 채운 다음 에스프레소를 넣고 나머지 물을 채워주세요” 와 같은 주문을 하지 않아도, 바리스타 스스로
얼음을 먼저 채울수도, 물을 먼저 채울수도, 에스프레소를 먼저 채울수 도 있다.
역할, 책임, 그리고 협력
각 객체는 메세지를 통해 소통하며, 메세지의 요구조건을 수행하는 것을 메서드라고 표현할 수 있다.
객체들은 상호 협력적인 관계를 가져야한다, 또한 특정 역할을 수행하는 객체는 역할에 대한 책임을 가져야한다.
객체의 자율성
객체들은 서로 무엇을 수행하는지는 알수 있으나 어떻게 수행하는지는 몰라야한다.
객체지향 ≠ 클래스
클래스는 객체들의 협력 관계를 코드로 옮기는 도구에 불과
객체지향의 본질 Point!
상호작용하는 자율적인 객체들의 공동체로 시스템을 바라보고, 객체를 이용해 시스템을 분할
자율적인 객체란 상태와 행위를 포함해 스스로 자기자신을 책임지는 객체를 의미
객체는 다른 객체와 협력하며, 각 객체는 협력 내에서 정해진 역할을 책임을 갖고 수행해야한다
객체들간의 협력은 메세지를 통해 이루어지고, 메세지를 수신한 객체는 메세지 처리를 위해 적합한 메서드를 자율적으로 선택한다.
📝 감상 및 리뷰
객체지향 = 클래스 로 인식했던 과거를 반성하게 됨
객체지향에 대한 이론적 지식이 잡혀있지 않은 상태로 개발을 해왔으나, 왜 그러한 구조로 개발을 수행되어야 하는지 이해가 되었음
🛠️ 실무/프로젝트 적용
대략적인 공부
class Calcurator {
let a: Int
let b: Int
init(a: Int, b: Int) {
self.a = a
self.b = b
}
func add() -> Int {
return a + b
}
func divide() -> Double {
return a << b
}
func minus() -> Int {
return ((a * 3) - (b * 3)) / 3
}
}
class MainClass {
let cal = Calcurator(a: 1, b: 3)
print(cal.minus) // -2
}
코드를 보면, MainClass는 a-b 를 수행한다고 생각 할 수 있지만, 실제로 minus 함수를 보면 각 수에 3을 곱하고 뺀다음 3으로 나눈다, 하지만 아무 문제없다.
→ MainClass 입장에서 cal.minus는 a 에서 b 값을 뺀다(무엇) 는 것은 알수 있지만 어떻게 계산하는지는 모른다 ⇒ 객체의 자율성
그리고 이 세션을 들으며,, 나 진짜 swiftUI 열심히 공부해야겠다 싶더라구요,, 그리고 TCA에 대한 개념도,,
같이 듣던 친구가 TCA가 뭐의 약자냐고 해서 구글에 검색해봤더니 ㅋㅋㅋㅋㅋㅋㅋ
삼환계 항우울제 ...? 라고 뜨더라구요..? TCA 듣기만 했지 진짜 뭐의 약자인지 몰랐는데
The Composable Architecture 라고 하더라구요 TCA는 어떻게 동작하는지 어떻게 설계해야 하는지에 대해 알게된 세션이였습니다!
SwiftData 언박싱 대신해드립니다!를 보여 느낀점은,,
coreData 와 Realm을 대체할 강력한게 나왔다! 싶더라구요,,
사실 저는 realm을 사용해본적은 없고,, coreData는 아주아주아주 기초만 아는 정도인데 세션의 내용을 보니,, swiftData 이거이거,, 완전 물건입니다. 여러 장점들이 많았지만.
일단 코드량 자체가 화~악 줄어들더라구요 그래서 저도 이런 부분들에 대한 공부를 해야겠다고 생각하게 되었어요
토브님께서 예제를 포함한 깃허브도 공유해 주셔서 개인 맥북에 베타로 올려서 천천히 공부해볼까,,,🤔 싶기도 합니다!
이렇게 네개의 세션을 듣게 되었는데 뭐 하나 빠짐없이 너무나도 유익한 발표들 이였습니다!
하지만 많은 장점들 만큼이나 아쉬운 점도 있었는데요,, 개인적으로 느낀 아쉬운 점들을 나열 해 보겠습니다!
첫번째! 점심시간이 너무 짧은 느낌이였어요 오전세션 끝나고 식당가를 찾아 갔지만 점심시간인 만큼 거의 모든식당이 다 줄을 섰어야 했는데 줄서서 먹고 세션장 가니까 1:30분 세션은 이미 시작한 이후더라구요.. 조금 아쉬웠습니다!
두번째! 제가 컨퍼런스는 처음 가보는거라 원래 컨퍼런스들이 그런지 모르겠는데,, 듣고싶은 세션을 늦으면 못듣더라구요 ㅠㅠ 원래 계획은 애매하게 시간이 겹쳐있는 현대자동차 세션을 보고 난 후, 매크로 부수고 부셔지기를 보는것 이였는데 현대차 TCA를 보고 바로 이동을 했으나,, 인원이 많아서 세션장 입장이 안되는 상황이였습니다 매크로 세션 보고싶었으나 조금 아쉬웠어요!
세번째! 세션과 네트워킹의 두마리 토끼를 잡기엔 조금 힘들었어요 ㅜ_ㅜ 이것도 제가 컨퍼런스가 처음이라 원래 이런건지 잘 모르겠으나 세션들으러 왔다갔다 하느라 다른분들과의 네트워킹에는 집중 할 수가 없더라구요ㅠ ㅠ
아, ,물론 제가 낯가림이 심해서 못한것도 맞습니다 허허,, 이건 지극히 개인적인 아쉬움이에요!
낯가림을 빨리 없애서 저도 다른분들과 자유롭게 네트워킹 하는 그날까지! 성격을 고쳐보도록 하겠습니다 ㅜㅜ
전반적으로 너무 의미있고 뜻깊은 시간들 이였습니다~
오랜만에 만난 Apple Developer Academy @POSTECH 동문 분들 및 멘토분들도 너무너무 반가웠어요!
KWDC23 행사를 주최해주신 운영진분들, 스태프분들, 그리고 멋진 발표를 해주신 연사자분들 모두 고생 많으셨습니다!