[사내 세미나] 객체 지향이 무엇인가

2020년도의 첫 정기 세미나는 최범균 개발자를 초대했다. 파킹클라우드의 20년도 1월 세미나 주제는, 객체 지향 이다. 객체 지향은 무엇인지 함께 알아보자!

비용

  • 소프트웨어는 적은 비용으로 변화에 대응할 수 있어야 함
  • 비용을 낮춰서 빠르게 대응하는 방법이 필요
    • 방법
      • 패러다임 : 객체 지향, 함수형 등
      • 코드, 설계, 아키텍쳐
      • 효율적인 프로세스/문화

객체

절차 지향 vs 객체 지향: 절차 지향

  • 절차 지향: 데이터를 공유하는 모형
    • 시간이 지날수록 비용을 증가시킬 수 있음
    • 시간이 갈수록 복잡해지고 수정이 어려워지기 때문
  • 객체 지향: 객체와 객체가 프로시저를 통해 서로 통신을 하는 형태
    • 처음부터 객체 지향으로 구상하는 것이 어려움
    • 수정이 쉽고 변경 비용이 낮음

객체란?

그 객체가 내부적으로 어떤 데이터를 가지고 있는냐가 아닌, 실제 어떤 기능을 제공 하느냐로 정의

기능 명세

  • 인터페이스: 객체가 제공하는 기능의 명세
  • 이름, 입력 ,결과로 구성됌
  • 메시지 전달
    • 객체에게 기능 실행을 요청(메소드 호출)

캡슐화

  • 객체가 내부적으로 기능을 어떻게 구현했는지 감추는 것
  • 외부에 영향을 주지 않고 객체 내부의 구현을 변경하게 함

캡슐화를 하지 않으면?

  • 변경이 연쇄적으로 퍼짐

객체지향, 캡슐화를 한다면?

  • 기능을 제공하고 구현 상세를 감춤
  • 내부 구현만 변경됌

캡슐화하는 방법

  • 데이터를 갖고 있는 객체가 판단해서 알려달라하기
  • 메서드를 연쇄적으로 호출하게 하지 말기

절차지향 방지책

  • 메서드 파라미터로 관련 데이터만 받기
    • 데이터 전체를 그냥 넘기지 말기

다형성과 추상화

  • 여러 모습을 가지는 것
    • 모습 -> 타입
    • 객체 지향 언어에서는 타입 상속으로 다형성 구현

      추상화를 잘하는 개발자가 진짜 잘하는 개발자!

추상화

  • 데이터나 프로세스 등을 의미가 비슷한 개념이나 의미있는 표현으로 정의하는 과정

타입 추상화

  • 여러 구현 클래스를 대표하는 상위 타입 도출
    • 흔히 인터페이스타입으로 추상화
    • 추상화 타입과 구현은 타입 상속으로 연결

추상 타입 상속

  • 추상 타입은 구현을 감춰서 기능의 구현이 아닌 의도를 더 잘 드러냄

추상 타입 이점

  • 유연함 (사용 대상 변경이 쉬움)

추상화 주의점

  • 추상화를 하여 추상 타입이 증가하면 복잡도가 증가함
    • 실제 요구사항의 변경/확장이 발생할 때 추상화를 시도해야 함

OCP(Open-Closed Principle)

  • 개방 폐쇄 원칙
    • 확장에는 열려 있고 수정에는 닫혀 있음
  • 의존하는 대상은 변경 혹은 확장 가능하지만, 의존 대상을 사용하는 코드는 수정하지 않음
    • 객체 지향에서는추상화(다형성, 상속)를 이용함

캡슐화와 다형성/추상화

  • 개발 비용을 낮춰주는 객체 지향의 두 가지 특징
    • 캡슐화
    • 다형성/추상화

기능과 책임 분리

  • 기능의 정의
    • 입력
    • 출력
    • 상태 변경

기능 분해

  • 기능은 하위 기능으로 분해
  • 기능은 곧 책임이므로 분리한 기능을 알맞게 분배해야 함

기능 분해가 제대로 되지 않는다면?

  • 큰 클래스, 큰 메서드가 만들어짐

책임 분배/분리 방법

  • 패턴 적용
  • 계산 기능 분리
  • 외부 연동 분리
  • 조건별 분기는 추상화

패턴 적용

  • 전형적인 역할 분리
    • ex) 웹: 컨트롤러, 서비스, Dao

계산 분리

  • 계산 기능을 별도 분리
    • 분리한 입력과 출력은 다른 코드에 덜 엮이게

연동 분리

  • 네트워크, 메시징, 파일 등 연동 처리 코드 분리

조건 분기는 추상화

  • 연속적인 if-else는 추상화 고민

알맞은 책임 분리와 테스트

  • 테스트가 용이함
  • 테스트가 가능한 코드를 만들수록 책임 분리가 잘 될 가능성이 높아짐(TDD)

의존

  • 기능 구현을 위해 다른 구성 요소를 사용하는 것
  • 결합도(coupling)
    • 구성 요소가 서로 의존하는 정도
  • 의존은 변경이 전파될 가능성을 의미함
    • 의존하는 대상이 바뀌면 다른 무언가도 변경될 가능성이 높아짐(영향력)
    • 의존 대상이 적을 수록 변경의 영향이 적음

의존 대상이 많을 때

1. 기능이 많은 경우

  • 한 클래스에서 많은 기능을 제공
    • 기능 별로 알맞게 분리할 것을 고민할 필요가 있음

2. 묶어보기

  • 몇 가지 의존 대상을 단일 기능으로 묶어서 생각해보면 대상을 줄일 수 있음

의존 대상 객체를 직접 생성한다면?

  • 생성 클래스가 바뀌면 의존하는 코드도 바뀜
    • 추상화에서 언급
  • 의존 대상 객체를 직접 생성하지 않는 방법
    • 의존 주입
    • 서비스 로케이터
    • 팩토리

서비스 로케이터 vs DI

  • 프레임워크가 지원한다면 DI
    • DI가 서비스 로케이터보다 의존 객체 변경에 유연함
  • 프레임워크 지원 X 라면, 서비스 로케이터
    • 서비스 로케이터 단점
      • 의존 관계가 잘 드러나지 않음 등

DIP(Dependency Inversion Principle)

  • 개발자의 추상화 능력을 높여줌
  • 의존 역전 원칙
    • 저수준 모듈이 고수준 모듈에서 정의한 추상 타입에 의존해야 함
  • 고수준 모듈 관점에서 저수준 모듈을 추상화

고수준 모듈, 저수준 모듈

  • 고수준 모듈: 의미있는 단일 기능을 제공
    • 상위 수준의 정책 구현
  • 저수준 모듈: 고수준 모듈의 기능을 구현하기 위해 필요한 하위 기능의 실제 구현

고수준이 저수준에 직접 의존하는 경우

  • 저수준 모듈 변경이 고수준 모듈에 영향을 줌
  • 이와 같은 문제로, DIP(의존 역전 원칙)이 필요함

고수준 관점에서 추상화

  • 고수준 입장에서 저수준 모듈을 추상화
    • 구현 입장에서 추상화하지 말기

DIP의 이점

  • 좋은 설계 가능성이 높아짐
  • 고수준 모듈의 변경을 최소화함녀서 저수준 모듈의 변경 유연함을 높임
  • 처음부터 바로 좋은 설계가 나오지는 않음
    • 요구사항 이해가 높아지면서 저수준 모듈을 인지하고, 상위 수준에서 저수준 모듈 추상화를 시도해야 함

정리

  • 기능을 알맞은 크기로 잘 나누고 조합하자
  • 적절한 추상화로 유연하게 만들자

Q&A

  • 리팩토링을 하면 클래스를 어느 패키지에 둬야 하나요?
    • 패키지를 어디에 놓느냐는 어떤 패턴을 사용하느냐에 따라 달라질 수 있다. 즉, 규칙에 따라 달라지는데, 도메인 규칙이라면 도메인 패키지에 넣으려고 한다. 업무 흐름상 어플리케이션 로직과 관련된 규칙이라면 보통 서비스 쪽에 넣으려고 한다.

객체 지향에 대해서 깔끔하고 자세하게 설명해주셔서 쉽게 이해할 수 있었고, 중간 퀴즈도 있어서 집중하며 들을 수 있었다. 기능을 알맞는 크기로 나누고 조합하여 멋진 개발자가 되어봅시다!

업데이트:

댓글남기기