[개발자가 반드시 정복해야 할 객체 지향과 디자인 패턴] 객체 지향

·2022년 10월 26일
0
post-thumbnail
post-custom-banner
[개발자가 반드시 정복해야 할 객체 지향과 디자인 패턴]을 읽고 정리한 글 입니다.

[1] 절차 지향과 객체 지향

절차 지향 (Procedural Oriented)

  • 프로시저(procedure)로 프로그램을 구성하는 기법
  • 각 프로시저들이 데이터를 사용하여 기능 구현
  • 필요에 따라 다른 프로시저 사용
  • 여러 프로시저가 동일한 데이터 공유
  • 구현은 쉽지만, 이후 프로그램 규모가 커짐에 따라 변화된 요구사항 반영이 어려움 (코드의 수정이 어렵)

객체 지향 (Object Oriented)

  • 데이터와 프로시저를 객체(Object) 단위로 묶음
  • 객체는 다른 객체에 기능을 제공하기 위해 프로시저 사용
  • 프로시저는 자신이 속한 객체의 데이터에만 접근 가능 다른 객체에 속한 데이터에는 접근 불가
  • 구현 및 설계는 다소 어렵지만, 변화된 요구사항 빠르게 반영 가능 (프로그램 수정이 상대적으로 쉽다)

[2] 객체 (Object)

객체의 핵심: 기능 제공

  • 실제로 어떻게 해당 기능을 구현한지는 알 수도 없고, 알 필요도 X
  • Just 어떠한 기능을 제공한다는 사실이 중요할 뿐!

인터페이스와 클래스

  • 오퍼레이션(operation): 객체가 제공하는 기능
  • 인터페이스(interface): 객체가 제공하는 모든 오퍼레이션 집합
    • 시그니처(Signature)
      • 기능 식별 이름
      • 파라미터 및 파라미터 타입
      • 기능 실행 결과 값
  • 타입(type): 서로 다른 인터페이스를 구분할 때 사용되는 명칭

메시지

  • 오퍼레이션 실행을 요청(request)하는 것을 ‘메시지(message)를 보낸다.’고 표현

[3] 객체의 책임과 크기

  • 객체의 책임(responsibility): 객체가 제공하는 기능
    • 객체가 책임을 갖는다 == 객체가 역할(role)을 수행한다.
  • 한 객체가 갖는 책임을 정의한 것: 타입/인터페이스
  • 객체별 책임 할당은 어떻게..?
    1. 프로그램을 만들기 위해 필요한 기능 목록을 정리하라!

    2. 이 기능을 어떻게 객체에 분배할지 고민하라

      이 때, 객체가 갖는 책임의 크기는 작을수록 좋다

      단일 책임 원칙 (Single Responsibility Principle; SRP)

      : 변경의 유연함을 얻기 위한 가장 기본 원칙

[4] 의존

  • 한 객체가 다른 객체를 생성하거나 다른 객체의 메서드를 호출할 때, 이를 그 객체에 의존(dependency)한다고 표현함.
  • 파라미터로 전달받는 경우도 의존으로 볼 수 있음
  • 다른 타입에 의존한다? ⇒ 의존하는 타입에 변경이 발생할 때 나도 함께 변경될 가능성이 높다
  • 순환의존이 발생하지 않도록 해야함 ⇒ 의존 역전 원칙 (Dependency inversion principle; DIP)

의존의 양면성

  • 의존은 클래스 상호간에 영향을 줌
    • 내가 변경되면 나에게 의존하고 있는 코드에 영향을 준다.
    • 나의 요구가 변경되면 내가 의존하고 있는 타입에 영향을 준다.

[5] 캡슐화

  • 객체지향의 장점: 한 곳의 구현 변경이 다른 곳에 변경을 가하지 않도록 해준다 ⇒ 캡슐화를 통해 해당 장점 살림
  • 캡슐화(encapsulation): 객체가 내부적으로 어떻게 구현하는지를 감추는 것

절차 지향 방식 코드

  • 절차 지향 방식은 데이터를 직접적으로 사용하기 때문에, 데이터의 구조나 쓰임새가 변경되면 이로 인해 데이터를 사용하는 코드들도 연쇄적으로 수정이 발생함.

캡슐화 된 기능 구현

  • 구조나 쓰임새가 변경되더라도 내부 구현만 변경될 뿐, 기능을 사용하는 코드는 변경되지 않는다.

캡슐화의 결과는 내부 구현 변경의 유연성 획득

  • 앞선 내용에 따르면, 캡슐화를 통해서 내부 기능 구현 변경의 유연함을 얻을 수 있음

캡슐화를 위한 두 개의 규칙

  1. Tell, Don’t Ask

    • 데이터를 물어보지 않고, 기능을 실행해 달라고 말하라.
  2. 데미테르의 법칙(Law of Demeter)

    • 메서드에서 생성한 객체의 메서드만 호출
    • 파라미터로 받은 객체의 메서드만 호출
    • 필드로 참조하는 객체의 메서드만 호출
    public void processSome(Member member) {
    		if (member.**getDate().getTime()** < ... ) { // 데미테르 법칙 위반
    			...
    		}
    }

    파라미터로 전달받은 member의 getDate() 메서드를 호출한 뒤, 다시 getDate()가 리턴한 Date 객체의 getTime() 메서드 호출함 ⇒ 데미테르 법칙 위반

    • 데미테르 법칠을 지키지 않는 전형적인 증상
      1. 연속된 get 메서드 호출

        value = someObject.getA().getB().getValue();
      2. 임시 변수의 get 호출이 많음

        A a = someObject.getA();
        B b = a.getB();
        value = b.getValue();

        코드가 흩어져 있을 경우 발견하기 어려울 수 있음

[6] 객체 지향 설계 과정

  • 객체 지향 설계의 단계
    1. 제공해야 할 기능을 찾거나 세분화하고, 그 기능을 알맞은 객체에 할당한다.
      1. 기능을 구현하는데 필요한 데이터를 객체에 추가한다.

        객체에 데이터를 먼저 추가하고 그 데이터를 이용하는 기능을 넣을 수도 있다.

      2. 기능은 최대한 캡슐화해서 구현한다.

    2. 객체 간에 어떻게 메시지를 주고받을 지 결정한다.
    3. 과정1과 과정2를 갭라하는 동안 지속적으로 반복한다.
post-custom-banner

0개의 댓글