오브젝트 3장 4장 끄적거림
다양한 ~ Driven Development들이 있는데 결국
공통의 목표 (경제성이 뛰어난 프로그램 ->유연한 프로그램 -> 응집성 높고 결합도 낮고 캡쥴화 잘된 프로그램)
를 일련의 과정(제약)을 주면서 자연스럽게 이룰 수 있도록 하는 방법론인것 같은 생각
Responsibility Driven Development (책임 주도 설계)
Behavior Driven Development (행위 주도 설계)
Domain Driven Design (도메인 주도 설계)
Test Driven Development( 테스트 주도 설계)
그래서 결국에 다양한 방법론들이 있지만 완성된 프로그램은 비슷한 구조를 가질 것 같은데..?
다른 공통점으로써 드는 생각은 전부 구현을 개발 단계중 제일 뒤로 미루는 방식
예시로 나온 책임 주도 설계의 경우 객체의 역할을 중심으로 인터페이스를 먼저 짜서 책임과 역할을 분배한 다음
다시말해 설계가 끝난 뒤에 객체(구현체)를 만드는 것 같음
스터디 메모
TDD는 사이클을 돌면서 하나씩 양파까듯이
DDD는 바라보는 관점을 고정해 놓고 이렇게 협력하기로 하기로 정하고 TDD로 넘어갈 수 도 있어.
관점을 정하고 어떤 협력을 하게 될 텐데 어떤 테스트를 통과해야될까에서 봤을 때 계속 하면서 리팩토링되는것-> 보는 눈을 어떻게 가지고 TDD를 어디 넣을지에 대해서
상태를 가지는 객체는 어디서 어긋날지 모름.
상태를 가질 수 있는 변수가 늘어날 때마다 발생 가능한 경우의 수는 배로 늘어남.
(그래서 전역변수 쓰면 빠따맞는다는 건가)
책의 예시에서도 객체의 상태에 따라 초점을 맞춘 설계를 DDD(Data driven Development) 를 안좋은 예시로 소개하는데
상태에 따라 구현하게 되고 객체 내부 구현 변경에 따라 행위를 나타내는 인터페이스도 항상 변경되어야함
그래서 구현에 대한 결정을 뒤로 미루면서 객체의 행위를 고려하는게 중요
그래서 결국 객체의 상태보단 행동이 중요
역할이라는 개념을 이용해서 설계 과정을 더 번거롭게 만든다, 역할없이도 객체 만으로 충분히 협력을 설계할 수 있는것 아닌가
-> 설계할 수 있지만 역할없이 객체를 직접적으로 노출하면 결국 결합도가 높아짐
역할 = 인터페이스(프로토콜) 같은 의미로 이해되는데 왜냐하면
필요한 행위(역할)을 먼저 정의하고 (인터페이스를 정의하고) 역할을 수행할 객체를 구현 (인터페이스 상속 또는 프로토콜 준수)
그래서 뭐가 유연해지느냐? ->
책에서는 예시로 "예매하라" 라는 메시지를 처리하기 위해 Screening객체를 선택하는데 이 과정은 한단계로 보이지만
사실은 2단계로 볼 수 있음
1. 적절한 역할이 무엇인지 찾기
2. 역할을 수행할 인스턴스 찾기
하나의 역할에 대해 여러 객체가 해당 역할을 맡을 수 있고
하나의 객체는 여러 역할을 맡을 수 있음 (프로토콜은 다중 준수? 가능)
Discount Policy 를 보고 command pattern이 생각남
비동기 상태를 처리하기 위해 만들어진 Rx인데 rx는 상태를 가지지 않는것 처럼 느껴짐 -> stream으로 연결되서 처리하니까
하나의 장점으로 볼 수 있는걸까
객체 -> 역할 책임 협력
객체를 테스팅의 관점에서도 3가지를 전부 테스트 해야될것 같은데
책임 = 비즈니스 로직 테스트
협력 = mock, stub 객체의 함수 콜 카운트
역할 =....? 뭘 테스트 하지..? type casting 되는지..?
안드로이드는 리포지토리 패턴으로 왜 우리는 DAO VO DTO 구분해서 쓰던데 iOS는 뭔가 덜 쓰는..? 것 같은데 자바 컨벤션인가..? 는 당연히 아니겠지만 모델을 벨류타입으로 써서 그런가? 언어의 차이인가?
좋은 프로그램 척도: 변경의 범위가 작은지
- 캡슐화
- 응집도
- 결합도
객체 구성
- 역할
- 협력
- 책임
그렇다면 캡슐화를 하려면 객체간의 역할을 잘 부여하고
응집도를 높이려면 객체의 책임이 하나여야 되도록..? (SRP..?)
결합도를 낮게 하려면 협력에 있어서 메시지를 받는쪽에 처리하도록..?
enum 을 사용하는게 좋은건가
결국 enum은 케이스를 나눈거고 케이스가 추가될 때 마다 enum이 수정되어야 한다.
타입으로 구분하면 추가만 하면되지 않을까라는 멍청한 생각을 해본다.
멍청한 생각 계속해보면
비디오인지 오디오인지를 나타내는 enum type이 있다.
여기에 이미지가 추가되면 enum type도 수정하고 막 뭐 수정 더 해야겠지?
서버에서 가져오는데 이 타입에 따라 플레이어를 선택하는 로직이 있다면
enum 안쓰고 할수있냐? -> 각각의 비디오, 오디오 클래스가 있고 원래 타입에 따라 분기되던 로직들을 클래스에 옮기고..? 추상화 시켜서 프로토콜에 정의된 메서드만 쓰도록..? 그러면 중복 코드가 클래스마다 많아지는데..?
지금 그냥 개발하고 있는 이건 무슨 주도 개발이지?
절차적 프로그래밍?
근데 리팩토링에서 결국 좋은 코드는 좋은 데이터 설계로 부터 온다고 하는데
그런 관점에서 적절한 곳에 적절한 데이터가 있는 DDD는 괜찮지 않나?
데이터 주도 설계는 객체들이 데이터를 가지고 있고 해당 데이터를 조합해서 쓸 Main 클래스가 있는데
책임주도설계는 객체의 역할(메소드) 가 객체 안에 있다.
그 관점에서 엔티티에 관련된 비즈니스 로직이 엔티티 내부에 있도록 하는 도메인 주도 설계랑 비슷한듯
캡슐화 = 단순히 객체 데이터를 감추는게 아닌 변할 수 있는 모든것을 다 감추는것
추상화, 캡슐화나 개발 방법론들의 공통점 -> 구현 시기를 최대한 뒤로 미룬다 인듯
스터디 메모
설계의 이유
그림 그릴때 머릿속으로는 엄청난 작품을 만들어 놨는데 손이 안따라오니까 여러사람이 협력할 수 있게 하는게
그림을 다같이 그리는데 어디에 뭐가 있었으면 좋겠다 라는 원칙을 정하고 밑그림을 그린 다음에 맡은 부분을 그린다.
어느 위치에 있다라는 큰 그림이 있어서 어쨋든 돌아갈 수 있는 환경
1,2,3장에서는 객체지향이 뭔가에 대한 내용
책임: 메소드, 기능역할: 프로토콜, 인터페이스 처럼 보일 수도 있는데 책임들을 모아놓은 하나의 클래스라고도 생각하셨음협력: 클래스나 객체들이 모여서 각자의 책임, 기능들을 함께 수행하는 것
결국에는 기능과 기능을 엮어서 더 큰 책임을 만드는게 협력
캡슐화가 구현 변경이 많이 되는 부분을 구현이라고 하고 변경이 적게 되는 부분을 인터페이스라는 관점에서 구현부분을 항상 숨기고 인터페이스를 항상 노출하는건데 학교에서는 단순하게 가르친 것 같음 -> 강제의 규칙 보다는 어떤 규율의 관점
강의에서 하고 있는 서비스 자체가 큰 책임인데 그런 책임안에서 비디오, 음악 서비스를 제공하는게 작은 책임이고 또 책임이 나눠진다.
서비스가 하는 동작을 책임으로 봤고 책임을 수행하다보면 역할만 추상화 시켜서 메시지를 던지는데 추상화가 역할 같고 협력은 책임을 수행하는데 필요한 역할간의 소통
정보 전문가 패턴: Screening class가 왜 reservation을 해? -> 사람의 관점에서 좀 이상할 수 있음
DiscountPoilicy가 상속의 좋은예
데이터 중심 설계와 책임 중심 설계는 마인드 차이..?
-> 역할을 먼저 생각하긴 하는데 데이터 짤때도 역할을 생각하고 짤텐데..?
커멘드 패턴으로 수정하는게 옮은가 -> 강의에서도 if 문이 많아지면 함수의 프로토콜만 넘겨줘라라는게 있는데
서버 개발하신 분들은 라이브러리 배포가 잦으면 안되니까 자주 수정이 일어날 수 있는 부분을 커멘드 패턴을 이용