열심히 끝까지

[10분 테코톡] 웨지의 OOP 본문

디바이스 융합 자바(Java)기반 풀스택 개발자 양성과정(과제)

[10분 테코톡] 웨지의 OOP

노유림 2022. 7. 11. 00:30

웨지의 OOP
https://www.youtube.com/watch?v=3etKkkna-f0

OOP : 객체지향 프로그래밍

1. 객체지향 프로그래밍이란?
   : 프로그래밍 개발방법론 중 하나
   : 사람이 현실을 바라보는 방법을 개발에 접목
       > 직관적으로 이해하기 쉬움
       > 유지 보수를 용이하게 만듦

2. 키워드로 알아보는 객체지향
  1. 객체
       : 객체는 현실의 무언가에 대응하는 개념
        > 현실의 무언가를 추상적으로 표현한 것

      ex ) 치킨배달 서비스에 필요한 것
        >> 오토바이, 배달이, 배달의 민족, 치킨
             >> 그런 현실 세계의 무언가를 추상화
             >> 현실의 개념에 대응하는 것 = 객체

       : 객체지향이 왜 직관적으로 이해하기 쉬운가?
        > 우리의 인지(현실의 개념)와 맞닿아 있기 때문이라 생각
       : 객체지향적 코드가 일종의 소설이라고 생각됨
           >> 소설의 현실의 기반으로 작성되기 때문!!
       : class는 객체를 표현하는 하나의 수단
          >> 어느 책에서는 class == 객체 라고 표현하는 곳도 존재
         (class != 객체) : 객체라는 개념을 설명하기 위해 
                               class와 객체를 구분!

      >> 철학적인 부분의 객체란?
         : 다른 객체와 협력(Collaboration)하는 역할(role)을 맡고 있는 대상
         : 역할(role)을 맡으면 임무를 수행할 책임(responsibility)이 생김
         : 책임을 다하기 위한 데이터와 프로세스를 가지게 됨

      
  2. 협력과 책임, 역할
     - 협력(Collaboration) 
          : 시스템 목표를 달성하기 위해 여러 객체가 참여하여 행동하는 것
               ex ) 치킨을 튀겨서 손님에게 배달해야 함
     - 책임(Responsibility)
          : 협력 속에서 본인이 수행해야 할 임무의 내용을 알고 수행하는 것
               ex ) 치킨을 튀길 객체는 치킨을 맛있게 조리할 책임을 지님
     - 역할(Role)
          : 동일한 목적을 가진 책임의 묶음
               ex ) 치킨을 조리할 책임을 가지는 역할
                       >> "요리사" 

   - 결론
     1. 협력이란 문제 상황을 해결하기 위해 
        여러 객체가 참여하여 행동하는 것
     2. 역할을 맡으면 임무를 수행할 책임이 생김
     3. 치킨을 손님에게 배달하기 라는 협력을 완수하기 위해,
         - 치킨 가게 객체 : 치킨을 튀기는 책임(역할)을 수행
         - 배달원 객체 : 손님에게 치킨을 전달하는 책임(역할)을 수행     

  3. 메시지
      - 어떻게 책임을 수행하는가? -> 메시지를 통해 책임을 요구
      : 객체는 '메시지'를 통해 다른 객체에 책임을 다하라고 요구
      : 메시지를 보내는 객체는 '무엇을' 할지만 요구
        '어떻게' 하는지는 신경쓰지 않아도 괜찮음
      : 객체는 '책임'을 수행하라고 요구받음
        >> 어떻게 처리할 지는 '자율'에 맡김

   ex ) 
   class ChickenShop { // 자바에선 메소드를 호출함으로써 메시지를 호출

         public void cookChicken() { // 메서드 이름과 리턴 타입은 '메시지'를 표현
                ... // 치킨을 요리하라는 메시지를 받아 요리 시작
                   // 나는 나만의 요리를 진행               
         }
    
         public void deliverChicken() {
                ... // 치킨을 다른 객체에게 전달
         }
   }

  4. 자율성(의인화)
     - 객체지향과 현실세계의 차이점
      > 자율적이라는 부분에서 현실세계와 객체지향 세계가 갈라짐
      > 객체지향은 현실세계 모방을 넘어 섬
   ex ) 
      class ChickenShop { 
            public void cookChicken() {
                   ... // 스스로 치킨을 튀김(튀기는 방법은 본인이 선택)               
            }   
            public void deliverChicken() {
                   ... // 치킨을 다른 객체에게 전달
            }   
      }
         >> 현실 세계의 치킨 가게 == 건물
         >> 객체지향 세계의 치킨가게 == 스스로 치킨을 튀기고 치킨을 건내줌

     - 즉, 객체지향에선 객체가 '자율'적으로 '능동'적으로 행동할 수 있다고
       '의인화' 하여야 함 
          > 자율적이라는 부분에서 현실세계와 객체지향 세계가 갈라짐
          > 객체지향은 현실세계 모방을 넘어 섬
     - 자율적으로 메시지를 처리하기 위해
       자신의 책임을 수행하는데 필요한 '데이터'와
       '프로세스'를 가짐

  5. 다형성
     - 다형성을 활용하는 목적
        : 서로 다른 유형의 객체가 동일한 메시지에 대해 다르게 반응하게 하기 위해서
          >> 동일하게 메시지를 처리함 == 같은 역할을 수행
          >> 다르게 반응 == 메시지 처리 방법은 자율적  
      ex ) 
         // ChickenShop과 같은 역할과 책임을 수행할 수 있음
         class ElectricChickenShop extends ChickenShop { 
               public void cookChicken() {
                      ... // 똑같이 치킨을 요리하지만 어떤 치킨을 튀길지는 자율             
               }   
               public chicken getChicken() {
                      ... // 전기구이 통닭을 리턴
               }   
         }

>> 세줄 정리
   1. 객체는 현실의 개념을 추상화 한 것
   2. 객체들은 서로 협력하고, 역할을 맡아 책임을 수행하여 문제 상황을 해결
   3. 하지만 현실의 사물과 달리 객체는 능동적이고 자율적인 존재

3. 객체지향적인 치킨집 만들기

  - 객체지향적으로 설계해보기
    : 책임 주도 설계 해보기

  >> 빠지기 쉬운 함정 존재
     : 현실 세계를 반영하기 위한 설계를 시작하면 자칫 데이터 중심의 설계를 하기 쉬움
     ex) 치킨집 => 요리사, 전화기를 가지고 있음
          배달원 => 배달 도착지, 치킨, 받아야 할 돈 가지고 있음

      >> 어떠한 객체가 무엇을 가지고 있어야 하는가..와 같은 사고
           > "데이터 중심적인 사고"를 하기 쉬움.. 
           > 이때의 단점
               - getter, setter가 과도하게 추가되어 결합도가 높아짐
                  ->서로 알고 있는 객체가 많아짐
                  >> 결합도가 높아지게 되면?
                        - 특정 타입이 변경하려고 하면 
                              >> 타입과 관련된 get, 프로세스도 수정이 되어야 함
                              >> 하나의 변경이 일어났을 때, 다수의 수정이 일어나게 되는
                                   "유지보수성이 떨어짐" 단점 존재
               - 데이터를 처리하는 작업과 데이터가 분리되어 응집도가 낮아짐
                 (여러가지 이유로 변경되어야 함)
                  >> 하나의 일을 여러 객체가 같이 행하고 있음을 의미

- 어떻게 해야 "데이터 중심적인 설계"가 아닌 
  "객체지향적인 설계"를 할 수 있는가?
   1. 시스템이 사용자에게 제공해야 하는 기능인 시스템 책임을 파악
       >> 협력이 무엇인지 확인
       -> 치킨 주문을 받아 손님에게 배달해야 함

   2. 시스템 책임을 더 작은 책임으로 분할
       >> 책임을 만드는 것
        -> 메시지를 생성
            - 치킨 주문을 받음
            - 치킨을 요리
            - 치킨을 손님에게 배달

   3. 분할된 책임을 수행할 수 있는 적절한 객체 또는 역할을 찾아 책임을 할당
        -> 인간 --------------------------> 치킨가게
                     "치킨 주문을 받아라"

   4. 객체가 책임을 수행하는 도중 다른 객체의 도움이 필요한 경우
       이를 책임질 적절한 객체, 또는 역할을 찾을 것
        -> 치킨가게 -------------------------> 요리사
                             "치킨을 요리하라"

             요리사 ----------------------------> 배달원
                             "치킨을 배달하라"

             >> 노출된 책임을 mapping 후

   5. 해당 객체 또는 역할에게 책임을 할당함으로써 두 객체가 협력하게 할 것
         ->
             class ChickenShop {

                 private Chef chef = new Chef();

                 public void takeOrder() { // 치킨 가게에 메시지 전달
                       chef.cook(); // 요리사에게 요리하라고 전달
                 }
              }
       ----------------------------------------------------          
              class Chef {

                  private Driver driver = new Driver();
                  private Chicken chicken;

                  public void cook() {
                       chicken = new FriedChicken();
                       driver.deliver(chicken); // 배달원에게 메시지 요청
                  }
               }
 
               class Driver {

                   public void deliver(Chicken chicken){ // 전달할 수 있으면 수단은 상관 없음
                        ...
                    }
                }