코드스피츠 3강 강의
- 객체망과 객체간 통신
- 설계란 구동하고 있는 코드를 어떻게 배치할 것인가의 문제이다.
객체
: 내부상태는 캡슐화
외부소통은 메소드(정보은닉)
객체끼리 메세지를 주고 받는다.
형(type)으로 개발해야 객체지향으로 쓴다
도메인을 객체망의 협력의 메세지망으로 표현할 수 있는가가 관건
순환하는 망이 생기면 안됨.
비선형 망이 생기게 해야함
의존성은 제거할 수 없다. 의존성은 필요하니까 만든것
의존성을 심플렉스로 만드는 것이 중요
단방향으로 만드는 것이 중요
- 객체설계 난점
- 인터페이스의 그룹화
- 도메인A관점
- 도메인B관점
- 네트웍관점
- 모델링관점
- 여러 관점을 수용하는 객체
- 다양한 객체
- 인터페이스의 그룹화
- 알려진 기본 설계요령
- SOLID 원칙
- SRP Single Responsibility 단일 책임 117
- OCP Open Closed 개방폐쇄(구현보다 인터페이스를 참고하라) → 다형성
- LSP Liskov Substitusion 업캐스팅 안전: 부모클래스 안에는 자식클래스를 넣을 수 있다
- ISP Interface Segregation 인터페이스분리
- DIP Dependency Inversion 다운캐스팅 금지
- → 추산화 된 것은 구체적인 것에 의존하면 안된다. 구체적인 것이 추상화된 것에 의존해야한다. 2. DI Dependency Injection 의존성주입 (IoC Inversion of Control 제어역전) 3. DRY Don’t Repeat Yourself 중복방지 4. Hollywood Principle 의존성 부패방지 → 묻지말고 시켜라(물으면 많은 것을 알게됨) 5. Law of demeter 최소 지식 1. classA.methodA의 최대 지식 한계 1. classA의 필드 객체 2. methodA가 생성한 객체 3. methodA의 인자로 넘어온 객체
- SOLID 원칙
내용들 다 암기하세요. 모든 코드를 짤때 숨쉬듯이 적용해야함
- 의존성부패방지와 최소지식의 모순
- 두 원칙을 지키면 해당 객체와 메시지를 주고 받는 것은 가능하나 내부를 들여다볼 방법이 없음 객체 통신망: 객체는 메세지를 주고 받는다. → 결국 객체가 제대로 작동하는가를 테스트하려면
- 객체통신망 테스트할 객체에게 메세지를 보낸 뒤
- 그 객체가 이웃 객체에게 메세지를 잘 보냈는지 확인
- 3번을 위해 통신한 이웃 객체를 조사하면 된다.
- Mock객체를 활용한 검증
- mockery(모조객체)와 mock(목객체)
- mockery(모조객체): 테스트관리객체
- mock(목객체): 테스트용모의객체
- mockery = 모조객체 = context
- 필요한 목객체를 생성하고
- 테스트할 객체를 둘러싼 객체망을 구성한 뒤(DI)
- 트리거가 되는 메세지를 일으켜
- 각 목객체의 상태를 확인한다.
- mockery(모조객체)와 mock(목객체)
- GRASP(General Responsibility Assignment Software Pattern)
- Information Expert
- 정보 담당자: Information Expert
- 해당 정보를 갖고 있는 객체에게 책임을 할당하라. 객체의 본질과 데이터 은닉을 지킬 수 있는 패턴
- 소유권한: Creator
- 객체 시스템의 이질적인 부분인 생성 시에도 정보전문가 패턴을 따르자. 어떤 객체가 대상을 포함하거나, 이용하거나, 부분으로 삼거나, 잘 알고 있다면 그 대상을 생성하게 시키자.
- 컨트롤러: Controller
- 미디에이터 패턴의 설계판 확장으로 서브시스템으로 묶을 수 있다면 컨트롤러를 도입하자
- 낮은 연결: Low Coupling 결합도를 낮추고 응집도를 높이는 패턴은 다른 양상으로 나타남. 결합도를 낮추려면 아는 객체 수를 줄여야함. 하지만 더 중요한 것은 단방향 의존성임. 이에 비해 응집도를 높이려면 객체를 도출할 때부터 변화율을 고려해야함. Low Coupling: 단방향 의존성. 양방향 참조는 무조건 안됨 → 객체가 많아지게 됨. 그래도 괜찮음.
- 높은 응집도: High Cohesion SRP를 따르자. 변화하는 이유를 하나로 만들어라.
- 간접 참조: Indirection 직접 참조관계를 피하고 중계 객체를 이용하면 개별 객체의 충격을 중계 객체에서 흡수할 수 있다. SOLID에서 open-closed 원칙을 따르고 있음
- 다형성: Polymorphism 전략패턴처럼 분기가 예상되는 책임이라면 다형성을 이용하라.
- 순수 조립: Pure Fabrication 공통된 기능이나 순수 기능적인 객체는 따로 모아서 작성한다. 디자인패턴 중 가장 많이 쓰는 패턴: 템플릿 메서드 패턴, 스트래터지 패턴 (밥 먹듯이 서로 바꿀 수 있어야함)
- 변화 보호: Protected Variations 추상적인 수준에서 책임을 정의하여 다양한 구상가능성으로부터 사용할 모듈을 보호하라.
- 정보 담당자: Information Expert
- Information Expert
어떻게 하는지는 모른다. 무엇을 하는지는 안다.
public class TicketSeller {
private TicketOffice ticketOffice;
public void setTicketOffice(TicketOffice ticketOffice) {
this.ticketOffice = ticketoffice;
}
Reservation reserve(Customer customer, Theater theater, Movie movie, Screening screening, int count) {
Reservation reservation = Reservation.NONE;
// 아래줄이 잘못되었다는 것을 알 수 있어야함. TicketSeller가 movie 내부 메서드를 알게됨
Money price = movie.calculateFee(screening, count);
// 이렇게 바꿔야함.
Money price = ticketOffice.calculateFee(movie, screening, count);
// customer.getAmount() 이렇게 하지 않았음. 내부를 열어보지 않고 명령을 했다는 거임.
if(customer.hasAmount(price)){
// 중계형으로만 썼으니 아래줄 코드는 괜찮음
reservation = ticketOffice.reserve(theater, movie, screening, count);
if(reservation != Reservation.NONE){
// 그럼 아래줄도 잘못된건가? TicketSeller가 customer의 내부 메서드를 알게되니.
// 그럼 이거는 어떻게 바꿀까
// -> 명령
customer.minus.Amount(price);
// 이런식으로?
ticketOffice.minus.Amount(customer, price);
}
}
return resevation;
}
}
'오브젝트' 카테고리의 다른 글
5. 책임 할당하기 - 1 (0) | 2022.10.14 |
---|---|
4. 설계 품질과 트레이드오프 (0) | 2022.10.14 |
3. 역할, 책임, 협력 - 3 (0) | 2022.10.14 |
3. 역할, 책임, 협력 - 2 (0) | 2022.10.14 |
3. 역할, 책임, 협력 - 1 (0) | 2022.10.14 |
댓글