목차

오브젝트; 절차 추상화와 타입 추상화

🗓️

데이터 추상화와 추상 데이터 타입

추상 데이터 타입

  • 타입 : 변수에 저장할 수 있는 내용물의 종류와 변수에 적용될 수 있는 연산의 가짓수를 의미.

안타깝게도 프로시저만으로는 충분히 풍부한 추상화의 어휘집을 제공할 수 없다. 이것은 언어 설계에서 가장 중요한 추상 데이터 타입의 개념으로 우리를 인도한다. 추상 데이터 타입은 추상 객체의 클래스를 정의한 것으로 추상 객체에 사용할 수 있는 오퍼레이션을 이용해 규정된다. 이것은 오퍼레이션을 이용해 추상 데이터 타입을 정의할 수 있음을 의미한다. 추상 데이터 객체를 사용할 때 프로그래머는 오직 객체가 외부에 제공하는 행위에만 관심을 가지며 행위가 구현되는 세부적인 사항에 대해서는 무시한다. 객체가 저장소 내에서 어떻게 표현되는지와 같은 구현 정보는 오직 오퍼레이션을 어떻게 구현할 것인지에 집중할 때만 필요하다. 객체 사용자는 이 정보를 알거나 제공받을 필요가 없다.

추상 데이터 타입을 구현하려면 다음과 같은 특성의 지원이 언어 차원에서 필요하다.

  • 타입 정의를 선언할 수 있어야 한다.
  • 타입의 인스턴스를 다루기 위해 사용할 수 있는 오퍼레이션의 집합을 정의할 수 있어야 한다.
  • 제공된 오퍼레이션을 통해서만 조작할 수 있도록 데이터를 외부로부터 보호할 수 있어야 한다.
  • 타입에 대해 여러 개의 인스턴스를 생성할 수 있어야 한다.

리스코프는 추상 데이터 타입을 정의하기 위해 제시한 언어적인 메커니즘을 오퍼레이션 클러스터 Operation cluster 라고 불렀다.

클래스

클래스는 추상 데이터 타입인가?

  • 클래스와 추상 데이터 타입은 모두 데이터 추상화를 기반으로 시스템을 분해한다. 그러나..
  • 클래스 : 상속, 다형성 지원
    • 객체지향 프로그래밍
    • 절차 추상화 Procedural abstraction : 내부에서 수행되는 절차는 다르지만 다형성은 절차에 대한 차이점을 감춘다.
    • 타입을 기준으로 오퍼레이션을 묶음
  • 추상 데이터 타입 : 상속, 다형성 지원하지 않음
    • 객체기반 프로그래밍
    • 타입 추상화 Type abstraction : 개별 오퍼레이션이 모든 개념적인 타입에 대한 구현을 포괄하도록 해 하나의 물리적인 타입 안에 전체 타입을 감춤.
    • 오퍼레이션을 기준으로 타입을 묶음
public interface Stack<E> {
    void push(E item);
    E pop();
    E peek();
    boolean isEmpty();
    int size();
}
  • Stack 제네릭 : 추상 데이터 타입
  • Stack 내 인터페이스 : 절차 추상화

변경을 기준으로 선택하라

  • 객체지향에서는 타입 변수를 이요한 조건문을 다형성으로 대체한다
  • 클라이언트가 객체의 타입을 확인한 후 적절한 메서드를 호출하는 것이 아니라 객체가 메시지를 처리할 적절한 메서드를 선택한다.
  • 조건문을 기피하는 이유는 변경의 파급효과 때문이다.

개방-폐쇄 원칙 Open-Closed Principle, OCP

기존 코드에 아무런 영향도 미치지 않고 새로운 객체 유형과 행위를 추가할 수 있는 특성

설계는 변경과 관련된 것이다. 설계의 유용성은 변경의 방향성과 발생 빈도에 따라 결정된다. 그리고 추상 데이터 타입과 객체지향 설계의 유용성은 설계에 요구되는 변경의 압력이 ‘타입 추가’에 관한 것인지, 아니면 ‘오퍼레이션 추가’에 관한 것인지에 따라 다르다.

  • 타입 추가의 경우.. -> 객체지향
  • 오퍼레이션 추가의 경우.. -> 추상데이터 타입

데이터 주도 설계

레베카 워프스브록은 추상 데이터 타입의 접근법을 객체지향 설계에 구현한 것을 데이터 주도 설계라고 부른다. 워프스브록이 제안한 책임 주도 설계는 데이터 주도 설계 방법을 개선하고자 하는 노력의 산물이였다. 티모시 버드는 모듈과 추상 데이터 타입이 데이터 중심적인 관점을 취하는데 비해 객체지향은 서비스 중심적인 관점을 취한다는 말로 둘 사이의 차이점을 깔끔하게 설명했다

협력이 중요하다

  • 협력이라는 문맥을 고려하지 않고 객체를 고립시킨 채 오퍼레이션의 구현 방식을 탕비별로 분배하는 것은 올바른 접근법이 아니다.
  • 객체를 설계하는 것은 여전히 책임 주도 설계의 흐름을 따라야 한다.
  • 객체가 참여할 협력을 결정하고 협력에 따라 필요한 책임을 수행하기 위해 어떤 객체가 필요한지에 관해 고민하라.
  • 그 책임을 다양한 방식으로 수행해야 할 때만 타입 계층 안에 각 절차를 추상화 하라.