캡슐화 vs 추상화

bp.chys·2020년 3월 19일
6

OOP & Design Pattern

목록 보기
4/17

캡슐화(ENCAPSULATION)

  • 캡슐화는 내부 구현에 대해 유연함을 제공해 주는 기법이다.
  • 객체가 내부적으로 기능을 어떻게 구현했는지 감추는 것
  • 변경 가능성이 높은 부분은 내부에 숨기고 외부에는 상대적으로 안정적인 부분만 공개함으로써 변경의 여파를 통제한다.
    • 변경될 가능성이 높은 부분을 구현이라고 하고 상대적으로 안정적인 부분을 인터페이스라고 한다.
  • 외부에 영향을 주지 않고 객체 내부의 구현을 변경할 수 있게 함
// 캡슐화 전
public void verifyEmail(String token) {
    Member mem = findByToken(token);
    if (mem == null) {
        throw new BadTokenException();
    }
    
    if (mem.getVerificationEmailStatus() == 2) {
        throw new AlreadyVerifiedException();
    } else {
        mem.setVerificationEmailStatus(2);
    }
    // .. 수정 사항 DB 반영
}
// 캡슐화 후
public void verifyEmail(String token) {
    Member mem = findByToken(token);
    if (mem == null) {
        throw new BadTokenException();
    }
    
    mem.verifyEmail();
    // .. 수정 사항 DB 반영
}

public class Member {

    ...
    public void verifyEmail() {
        if (isEmailVerified()) {
            throw new AlreadyVerifiedException();
        } else {
            this.verificationEmailStatus = 2;
        }
    }
    ...
    
}

구현 은닉 (implementation hiding)

  • 은닉과 캡슐화를 구분해서 사용하기도 하나, 보통 캡슐화에 은닉의 의미를 담음
  • 접근 제어 매커니즘은 클래스의 내부와 외부를 명확하게 경계 지을 수 있게 하는 동시에 클래스 작성자가 내부 구현을 은닉할 수 있게 해준다.
  • 변경될 가능성이 있는 세부적인 구현 내용을 private 영역 안에 감춤으로써 변경으로 인한 혼란을 최소화할 수 있다.

Tell, Don't Ask

  • 데이터 달라 하지 말고, 해 달라고 하기

Demeter's Law

  • 메서드에서 생성한 객체의 메서드만 호출
  • 파라미터로 받은 객체의 메서드만 호출
  • 필드로 참조하는 객체의 메서드만 호출

추상화(ABSTRACTION)

  • 데이터나 프로세스 등을 의미가 비슷한 개념이나 의미 있는 표현으로 정의하는 과정을 추상화라 한다.
  • 구현 세부사항 대신 기능 측면에서 클래스를 개발하는 것이다.
  • 추상화의 목적은 클래스 구현 세부 사항과 동작을 분리하는 것을 목표로 한다.
  • 추상화를 사용하면 세부적인 내용을 무시한 채 상위 정책을 쉽고 간단하게 표현할 수 있다.
    • 상위 개념만으로도 도메인의 중요한 개념을 설명할 수 있게 한다.
    • 추상화를 통해 상위 정책을 기술한다는 것은 기본적인 애플리케이션의 협력 흐름을 기술한다는 것을 의미.

타입 추상화

  • 여러 구현 클래스를 대표하는 상위 타입 도출 ex) Notifier
  • 흔히 인터페이스 타입으로 추상화
  • 추상화 타입구현은 타입 상속으로 연결 (implements, extends)
  • 사용할 대상을 추상화를 하면 사용 대상이 변경되어도 사용하는 코드에서는 변화하지 않아도 된다.

추상화는 의존 대상이 변경되는 시점에 한다

  • 무분별한 추상화는 전체 추상 타입 증가와 이로 인한 코드 복잡도 증가를 불러일으킨다.
  • 아직 존재하지 않는 기능에 대한 이른 추상화는 주의해야 한다.
  • 실제 변경, 확장이 발생할 때 추상화를 시도하는 것이 좋다.

Open-Closed Principle(OCP)

  • 개방 폐쇄 원칙 : 확장에는 열려있고, 수정에는 닫혀있는 객체지향 설계원칙 중 하나
  • 의존 하는 대상을 바꾸거거나, 확장할 수 있으면서, 의존 대상을 사용하는 코드는 수정하지 않는다.

결론

캡슐화와 추상화는 개발 비용을 낮춰주는 객체 지향의 두 가지 특징이다. 캡슐화는 기능 구현을 외부로부터 감추고, 내부의 구현 변경이 외부로 전파되는 것을 막아준다. 추상화는 의존 대상을 추상 타입으로 간접 참조하고 사용하고 있는 의존 대상의 변경이 사용하는 입장에는 영향을 주지 않는다.

둘은 상호 보완적인 개념이다. 추상화는 객체의 동작, 기능 자체에 중점을 두지만 캡슐하는 객체의 동작 구현에 중점을 두는 반면 캡슐화는 객체 내부 상태에 대한 정보를 숨기는 방식으로 이루어지므로 추상화를 제공하기 위해 사용되는 전략중 하나로 볼 수 있다.

설계를 주도하는 것은 변경이다. 개발자로서 변경에 대비할 수 있는 방법이 두 가지 있다.

  1. 코드를 이해하고 수정하기 쉽도록 최대한 단순하게 설계하는 것
  2. 코드를 수정하지 않고도 변경을 수용할 수 있도록 코드럴 더 유연하게 만드는 것

대부분의 경우에는 전자의 방법이 더 좋지만, 유사한 변경이 반복적으로 발생하고 있다면 복잡성이 상승하더라도 유연성을 추가하는 두 번째 방법이 더 좋다.


참고자료

  • NHN 기술세미나, 객체지향 입문 - 최범균
  • 오브젝트 - 조영호
profile
하루에 한걸음씩, 꾸준히

0개의 댓글