본문 바로가기
반응형
오브젝트

3. 역할, 책임, 협력 - 4

by brightGarden02 2022. 10. 14.

코드스피츠 3강 강의

코드스피츠 83 오브젝트 - 3회차

  • 객체망과 객체간 통신
    • 설계란 구동하고 있는 코드를 어떻게 배치할 것인가의 문제이다.

 

객체

: 내부상태는 캡슐화

외부소통은 메소드(정보은닉)

 

객체끼리 메세지를 주고 받는다.

 

형(type)으로 개발해야 객체지향으로 쓴다

 

도메인을 객체망의 협력의 메세지망으로 표현할 수 있는가가 관건

 

순환하는 망이 생기면 안됨.

비선형 망이 생기게 해야함

 

의존성은 제거할 수 없다. 의존성은 필요하니까 만든것

의존성을 심플렉스로 만드는 것이 중요

단방향으로 만드는 것이 중요

 

  • 객체설계 난점
    • 인터페이스의 그룹화
      • 도메인A관점
      • 도메인B관점
      • 네트웍관점
      • 모델링관점
    • 여러 관점을 수용하는 객체
      • 다양한 객체
  • 알려진 기본 설계요령
    • SOLID 원칙
      1. SRP Single Responsibility 단일 책임 117
      2. OCP Open Closed 개방폐쇄(구현보다 인터페이스를 참고하라) → 다형성
      3. LSP Liskov Substitusion 업캐스팅 안전: 부모클래스 안에는 자식클래스를 넣을 수 있다
      4. ISP Interface Segregation 인터페이스분리
      5. 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의 인자로 넘어온 객체

 

 

내용들 다 암기하세요. 모든 코드를 짤때 숨쉬듯이 적용해야함

  • 의존성부패방지와 최소지식의 모순
    • 두 원칙을 지키면 해당 객체와 메시지를 주고 받는 것은 가능하나 내부를 들여다볼 방법이 없음 객체 통신망: 객체는 메세지를 주고 받는다. → 결국 객체가 제대로 작동하는가를 테스트하려면
    1. 객체통신망 테스트할 객체에게 메세지를 보낸 뒤
    2. 그 객체가 이웃 객체에게 메세지를 잘 보냈는지 확인
    3. 3번을 위해 통신한 이웃 객체를 조사하면 된다.
    • Mock객체를 활용한 검증
      • mockery(모조객체)와 mock(목객체)
        • mockery(모조객체): 테스트관리객체
        • mock(목객체): 테스트용모의객체
        • mockery = 모조객체 = context
          1. 필요한 목객체를 생성하고
          2. 테스트할 객체를 둘러싼 객체망을 구성한 뒤(DI)
          3. 트리거가 되는 메세지를 일으켜
          4. 각 목객체의 상태를 확인한다.
  • 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 추상적인 수준에서 책임을 정의하여 다양한 구상가능성으로부터 사용할 모듈을 보호하라.

어떻게 하는지는 모른다. 무엇을 하는지는 안다.

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

댓글


반응형
반응형