오브젝트 7 : 객체 분해

김서영·2022년 12월 10일

객체 분해


한 번에 다뤄야 하는 정보의 수를 줄이기 위해,
본질적인 정보를 남기고 불필요한 세부 사항을 걸러 문제를 단순화하자 ⇒ 추상화

01) 프로시저 추상화와 데이터 추상화

추상화 메커니즘

  • 프로시저 추상화(procedure abstraction) : 소프트웨어가 무엇을 해야 하는지를 추상화한다.
    • 기능 분해(functional decomposition) == 알고리즘 분해(algorithmic decomposition)
  • 데이터 추상화(data abstraction) : 소프트웨어가 무엇을 알아야 하는지를 추상화한다.
    • 데이터를 중심으로 타입을 추상화(type abstraction) == 추상 데이터 타입(Abstract Data Type)
    • 데이터를 중심으로 프로시저를 추상화(procedure abstraction) == 객체지향(Object-Oriented)

소프트웨어는 데이터를 이용해 정보를 표현하고 프로시저를 이용해 데이터를 조작한다.

02) 프로시저 추상화와 기능 분해

프로시저란?

반복적으로 실행되거나 거의 유사하게 실행되는 작업들을 하나의 장소에 모아놓음으로써 로직을 재사용하고 중복을 방지할 수 있는 추상화 방법.

전통적인 기능 분해 방법은 하향식 접근법(Top-Down Approach)를 따른다. 가장 최상위 기능을 정의하고, 좀 더 작은 단계의 하위 기능으로 분해해 나가는 방법. 가장 상위 기능이 제일 추상적이고, 아래로 내려갈수록 구체적이다.

급여 관리 시스템 Top-Down

하향식 기능 분해의 문제점

  • 시스템은 하나의 메인 함수로 구성돼 있지 않다.
    • 새로운 요구 사항에 의해 계속해서 기능이 커지고 하나의 기능 이라는 것이 사라짐.
  • 기능 추가나 요구사항 변경으로 인해 메인 함수를 빈번하게 수정해야 한다.
    • 하향식 분해 기법의 경우 새로운 기능을 추가할 때마다 메인함수를 수정해야한다.
  • 비즈니스 로직이 사용자 인터페이스와 강하게 결합된다.
    • 사용자 인터페이스는 자주 수정되는 부분. 비즈니스 로직은 변경이 적게 발생한다.
    • 따라서 사용자 인터페이스가 자주 변경되면, 하향식 접근법에서는 비즈니스 로직까지 덩달아 불안정한 아키텍처를 만든다.
  • 하향식 분해는 너무 이른 시기에 함수들의 실행 순서를 고정시키기 때문에 유연성과 재사용성이 저하된다.
    • 설계란, 무엇을 해야 하는 지가 아니라, 어떻게 동작해야 하는 지에 집중해야 한다.
    • 그런데, 하향식 분해 방법은 분해를 먼저 해야하기 때문에, 실행 순서나 조건, 반복과 같은 제어 구조를 미리 결정하기 때문에 중앙집중 제어 스타일의 형태를 띄게 된다.
  • 데이터 형식이 변경될 경우 파급효과를 예측할 수 없다.
    • 하향식 기능 분해의 가장 큰 문제점은 어떤 데이터를 어떤 함수가 사용하고 있는 지를 추적하기 어렵다. 즉, 데이터가 변경된다면 어떤 함수가 영향을 받을 지 모른다.
    • 데이터 변경으로 인한 영향을 최소화하려면, 데이터와 함께 변경되는 부분과 그렇지 않은 부분을 명확하게 분리해야 한다.

03) 모듈

모듈이란?

  • 시스템의 변경을 관리하는 기본적인 전략은 함께 변경되는 부분을 하나의 구현 단위로 묶고 퍼블릭 인터페이스를 통해서만 접근하도록 만드는 것
  • 기능을 기반으로 시스템을 분해하는 것이 아닌 변경의 방향에 맞춰 시스템을 분해하는 것이다.

모듈은 변경될 가능성이 있는 비밀을 내부로 감추고,

잘 정의되고 쉽게 변경되지 않을 퍼블릭 인터페이스를 외부에 제공해서 내부의 비밀에 함부로 접근하지 못하게 함.

시스템 → (분해) → 모듈 → (분해) → 기능 분해

모듈은 두 가지 비밀을 감추자!

  • 복잡성
    • 외부에 모듈을 추상화할 수 있는 간단한 인터페이스를 제공해서 모듈의 복잡도를 낮춘다.
  • 변경 가능성
    • 변경 발생 시 하나의 모듈만 수정하면 되도록 변경 가능한 설계 결정을 모듈 내부로 감추고 외부에는 쉽게 변경되지 않을 인터페이스를 제공한다.

모듈의 장점

  • 모듈 내부의 변수가 변경 되더라도 모듈 내부에만 영향을 미친다.
  • 비즈니스 로직과 사용자 인터페이스에 대한 관심사를 분리한다.
  • 전역 변수와 전역 함수를 제거함으로써 네임스페이스 오염을 방지한다.

모듈의 한계

  • 인스턴스의 개념을 제공하지 않는다는 점이다. 좀 더 높은 수준의 추상화를 위해서는 독립적인 단위로 다룰 수 있어야 한다. ⇒ 추상 데이터 타입

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

타입(type)이란?

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

추상 데이터 타입은 프로시저 추상화 대신 데이터 추상화를 기반으로 소프트웨어를 개발.

추상 데이터 타입을 구현하려면…?

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

예를 들어, 직원에 대해 정의하기 위해 추상 데이터 타입을 이렇게 구현!

Employee = Struct.new(:name, :basePay, :hourly, :timecard)

사람들이 일반적으로 생각하는 (세상을 바라보는) 방식과 유사

05) 클래스

사실 클래스는 추상 데이터 타입과 다르다.

공통점

두 메커니즘 모두 외부에서는 객체의 내부 속성에 직접 접근할 수 없으며 오직 퍼블릭 인터페이스를 통해서만 외부와 의사소통할 수 있다.

차이점

클래스는 상속과 다형성을 지원하는 데 비해 추상 데이터 타입은 지원하지 못한다는 점이다.

클래스는 상속과 다형성을 지원하는 객체지향 프로그래밍(Object-Oriented Programming)

추상 데이터 타입 기반의 프로그래밍 패러다임을 객체기반 프로그래밍(Object-Based Programming)

변경을 기준으로 선택하라

단순히 클래스를 구현 단위로 사용한다는 것이 객체지향 프로그래밍을 의미하지는 않음.

타입을 기준으로 절차를 추상화하지 않았다? ⇒ 객체지향 분해가 아님.

클래스가 추상 데이터 타입의 개념을 따르는지를 확인할 수 있는 가장 간단한 방법은,
클래스 내부에 인스턴스의 타입을 표현하는 변수가 있는 지를 살펴보는 것.

인스턴스 변수에 저장된 값을 기반으로 메서드 내에서 타입을 명시적으로 구분하는 방식은 객체 지향을 위반

새로운 타입을 빈번하게 추가한다? 객체지향의 클래스 구조
새로운 오퍼레이션을 빈번하게 추가한다? 추상 데이터 타입

profile
하지만 저는 이겨냅니다. 김서영이죠?

0개의 댓글