꾸준하게

누가 개발블로그에 이런 거까지 쓰냐에서 '누'를 담당하고 있습니다:)

Steadily

IT/[ GDSC ] 객체지향의 사실과 오해

[ 객체지향의 사실과 오해 ] ch7. 함께 모으기

고구마개발자_인선 2024. 1. 19. 19:36

드디어 북스터디 마지막이다!

사실 저번주는 책을 읽었는데 정리를 못했다..(정말로)

오늘은 내가 그동안 정리한 스터디 중에 가장 열심히 정리했다...!(진짜로)

바로 스타트~

 

이건 주말에 먹은 티라미수ㅎㅎ

티라미수 원래 안좋아하는데 쿠키로 만든 티라미수는 아주 맛있다는 tmi날리며~ 이제 진짜 시작


Intro

마틴 파울러 : 객체 지향 설계 안에는 세 가지 상호 연관된 관점이 있다. -> "개념, 명세, 구현" 관점

 

1) 개념 관점 (Conceptual Perspective)

- 설계 : 도메인 안에 존재하는 개념과 개념들 사이의 관계를 표현하는 것

- 도메인 : 사용자들이 관심을 가지고 있는 특정 분야나 주제 , SW는 도메인에 존재하는 문제를 해결하기 위해 개발됨

-> 사용자가 도메인을 바라보는 관점 반영, 실제 도메인의 규칙과 제약을 최대한 반영하는 것이 핵심

 

2) 명세 관점(Specification Perspective)

-> 도메인(사용자의 영역)에서 소프트웨어(개발자의 영역)으로 초점이 옮겨짐 = 소프트웨어 안의 객체들의 책임에 초점

= 객체의 인터페이스 초점 = 객체가 협력을 위해서 '무엇'을 할 수 있는가 초점

 

3) 구현 관점 (Implementation Perspective)

- 실제 작업을 수행하는 코드와 연관된 관점

-> 객체들이 책임을 수행하는데 필요한 코드 작성에 초점 = 객체의 책임을 '어떻게' 수행할 것인가에 초점

 

Q. 개념->명세->구현 이 순서대로 개발해야함?

A. 놉, 개,명,구 관점은 동일한 클래스를 세 가지 다른 방향에서 보는 것을 의미함

     ex) 클래스가 의미하는 개념 = 도메인 관점 반영 -> 개념 관점

           클래스의 공용 인터페이스 -> 명세 관점

           클래스의 속성과 메소드 -> 구현 관점

 

클래스는 개명구 3가지 관점을 모두 수용할 수 있도록 개념, 인터페이스, 구현을 함께 드러내야함

+

코드 안데서 3가지 관점을 쉽게 식별할 수 있도록 깔끔하게 분리해야함

 

 

 

 

 

 

 


커피 전문점 도메인

 

커피주문 : 커피 전문점에서 커피를 주문하는 과정을 객체들의 협력 관계로 구현해보자

 

 

Step 1 : 커피 전문점을 구성하는 요소(객채) 정리

1) 메뉴판 : 아메리카노, 카푸치노, 카라멜 마키아또, 에스프레소

-> 객체지향 관점에서, 메뉴판은 1개의 객체! 4개의 메뉴 항목들도 각각이 1개의 객체!

-> 메뉴판 = 4개의 메뉴 항목 객체를 포함하고 있는 1개의 객체

 

2) 손님 : 메뉴판 보고 바리스타에게 원하는 커피를 주문함

-> 손님도 하나의 객체!

-> 객체 지향 관점에서, 손님 객체는 메뉴판 객체 안에 적힌 메뉴 항목 객체들 중 자신이 원하는 메뉴 항목 객체를 선택해 바리스타에게 전달할 것

 

3) 바리스타 : 주문을 받은 메뉴에 따라 적절한 커피 제조함

-> 바리스타도 자율적으로 커피를 제조하는 하나의 객체!

-> 바리스타가 제조하는 커피도 하나의 객체 (왜? 메뉴판, 메뉴 항목, 바리스타와 구별되는 자신만의 경계를 가지므로)

 

4)커피전문점(도메인) : 손님, 메뉴 항목, 메뉴판, 바리스타, 커피 (객체) 로 구성됨

 

 

Step 2 : 객체들 간의 관계 파악

1) 손님은 메뉴판에서 주문할 커피 선택 가능

= 손님은 메뉴판을 알아야함 = 두 객체 ( 손님과 메뉴판 ) 사이에 관계가 존재함

 

2) 손님은 바리스타에게 주문해야함

= 두 객체 (손님과 바리스타) 사이에 관계가 존재함

 

3) 바리스타는 커피를 만듬

= 두 객체( 바리스타와 커피) 사이에 관계가 존재함

 

 

Step3: 객체들을 타입으로 분류

- 동적인 객체를 정적인 타입으로 추상화 -> 복잡성 낮춤 

- 타입은 분류를 위해

- 상태와 무관하게 동일하게 행동하는 객체는 동일한 타입으로 분류

- 손님 객체 -> 손님 타입 / 바리스타 객체 -> 바리스타 타입 / 아,에,카마,카푸 커피 객체 -> 커피 타입 / 메뉴판 객체 -> 메뉴판 타입 ( 메뉴판 객체는 4개의 메뉴 항목 객체 포함 가능) 

-> 커피전문점 : 손님,메뉴판,메뉴,바리스타,커피 (타입)으로 구성  

 

 

Step4: 타입 간에 어떤 관계가 존재

1) 포함 Containment / 합성 Composition 관계

- 메뉴판 타입과 메뉴 항목간의 관계 ( 이 둘은 따로 떨어져서 존재하지 않음)

 

2) 연관 Association

- 손님 타입과 메뉴판 타입과의 관계 (손님은 메뉴판을 알고 있어야 원하는 커피를 선택할 수 있음)

- 손님 타입과 바리스타 타입의 관계

- 바리스타 타입과 커피 타입의 관계

- 한 타입의 인스턴스가 다른 타입의 인스턴스를 포함하지는 않지만 서로 알고 있어야할 경우

 

 

 

 

 

 

 


 

설계하고 구현하기

커피를 주문하기 위한 협력 찾기

 

1

- 객체지향 설계의 첫 번째 목표인 훌륭한 협력 설계를 통해 훌륭한 객체를 얻자!

- 협력 설계를 할 때 :  메시지가 객체를 선택하게 하는 것 = 메시지 먼저 선택하고, 메시지 수신에 적합한 객체 선택

 

< 커피 주문 >

현재 설계하고 있는 협력 : 커피를 주문하는 것

첫 번째 메시지 : ' 커피를 주문하라'

인자 : 아메리카노

나중에 구현 : '커피를 주문하라 (아메리카노)'

메시지를 수신할/처리할 객체 ( = 커피를 주문할 책임을 져야하는 객체 ) : 손님 타입의 인스턴스 -> 손님 객체는 커피를 주문할 책임을 할당받음

 

2

- 스스로 할 수 없는 일은 메시지를 전송해 다른 객체에게 도움을 요청한다

- 요청 : 객체에서 외부로 전송되는 메시지 의미

- 손님은 메뉴 항목에 대해서 알지 못함

요청 : 손님은 자신이 선택한 메뉴 항목을 누군가가 제공해줄 것을 요청함

새로운 메시지 : 메뉴 항목을 찾아라

인자 : 메뉴 이름

메시지를 수신할 객체 : 메뉴 항목을 가장 잘 알고 있는 메뉴판 객체

 

 

3

- 손님은 메뉴 항목에 맞는 커피를 제조해달라고 요청할 수 있음

새로운 메시지 : 커피를 제조하라

인자 : 메뉴 항목(전달)

반환값 : 제조된 커피

메시지를 수신할 객체 : 바리스타

 

 

 

 

 


인터페이스 정리하기

객체가 수신한 메시지가 객체의 인터페이스를 결정한다

 

- 메시지가 객체를 선택하고, 선택된 객체는 메시지를 자신의 인터페이스로 받아들임

- 각 객체를 협력이라는 문맥에서 떼어내어 수신가능한 메시지만 추리면, 객체의 인터페이스임

- 객체가 어떤 메시지를 수신할 수 있다는 것 = 객체의 인터페이스 안에 메시지에 해당하는 오퍼레이션이 존재함

 

ex : 손님 객체의 인터페이스 = ' 커피 주문해' 라는 오퍼레이션을 포함

메뉴판 객체의 인터페이스 = '메뉴 항목 찾아'라는 오퍼레이션 포함

바리스타 객체의 인터페이스 = '커피 제조해'

커피 객체의 인터페이스 = '생성해'

 

- 객체들의 협력 = 실행 시간에 컴퓨터 안에서 일어나는 상황을 동적으로 묘사한 모델

- 객체들을 포괄하는 타입을 정의한 후 식별된 오퍼레이션을 타입의 인터페이스에 추가함

- 근데 객체 타입 구현 어케? 클래스 이용!

ex : 인터페이스에 포함된 오퍼레이션은 외부에서 접근 가능하도록 public으로 선언

 

 

 

 

 

 


구현하기

클래스의 인터페이스를 식별했으니, 메소드를 통해 오퍼레이션을 수행하는 방법을 구현해보자

 

 

1.

 

2. 

 

3. 

 

4.

 

5. 

클래스 다이어그램

 

 


코드의 세 가지 관점

코드는 세 가지 관점을 모두 제공해야한다

 

자 정리하면

개념 관점 : 클래스가 보임 -> 클래스 자세히 보면, 커피 전문점 도메인을 구성하는 중요한 개념과 관계를 반영하고 있다는 사실을 알 수있음

 

명세 관점 : 클래스의 인터페이스가 보임 

- 객체의 인터페이스는 수정하기 어렵다는 사실을 명심

- 변화에 안정적인 인터페이스를 만들기 위해서는 인터페이스를 통한 구현과 관련된 세부 사항이 드러나지 않게 해야함

 

구현 관점 : 클래스의 내부 구현이 보임

-메소드의 구현과 속성의 변경은 원칙적으로 외부의 객체에게 영향을 미쳐서는 안된다

 

 

 

 

 

 


인터페이스와 구현을 분리하라

명세 관점 : 클래스의 안정적인 측면을 드러내야함

구현 관점 : 클래스의 불안정한 측면을 드러내야함

 

마틴 파울러 : 개념 관점과 명세 관점 사이는 그렇게 중요하지 않은 경우가 많지만, 명세 관점과 구현 관점을 분리하는 것은 매우 중요함

 

세 가지 관점 모두에서 클래스를 바라볼 수 있으려면 훌륭한 설계가 뒷받침되어야한다

 

 


드디어 스터디가 끝났다!!

우선 스터디장으로 이끄느라 너무 고생한 전🐨에게 감사를 ( 회색 니트를 즐겨입으니까!근데 올해 컬러는 연핑크임~ )

나에게 책을 빌려준 엔젤 이🐹에게 감사를 ( 햄스터가 야무지니까! 언니 없는 랩실은 노잼이다..쯧)

나한테 안드 지피티가 되어주는 채🦒에게 감사를 ( 앞으로도 신세질 예정이니까 참고 바라고~ )

가만보면 은근 성실한 신🐼에게 감사를 ( 판다가 차~분하니까,,응)

 

다음주부터는 엔젤 이🐹가 이끄는 코테스터디를 할 차례다!

코테,,걱정이 많지만 휴학생은 남는게 시간과 정신력이니

몰라 놀고 싶으면 놀래~ 언제 또 놀겠냐~

더 이상 의식이 흐름이 나오기전에

끝~!

반응형