GitHub

https://github.com/Choidongjun0830

공부

객체와 자료 구조의 차이

gogi masidda 2025. 3. 1. 16:30

인터페이스 설계 방식의 차이

잘못된 접근 방식

public interface Vehicle {
    double getFuelTankCapacityInGallons();
    double getGallonsOfGasoline();
}

위 인터페이스는 단순히 데이터를 가져오는 getter 메서드만 제공하며, 내부 데이터를 그대로 노출하는 방식이다.

public interface Vehicle {
    double getPercentFuelRemaining();
}

반면, 이 인터페이스는 내부 데이터를 숨기고, 필요한 정보만 제공하는 방식이다. 내부 구현을 감춘 채 기능을 제공하는 것이 객체지향적인 접근이다.

핵심 원칙

  • 데이터를 조회/설정하는 함수를 무분별하게 추가하는 것은 피해야 한다.
  • 객체는 데이터를 숨기고, 기능을 제공하는 방향으로 설계하는 것이 좋다.

 

자료/객체 비대칭

 

객체와 자료 구조는 서로 다른 목적을 가지며, 적절한 상황에 따라 선택해야 한다.

객체

  • 추상화 뒤로 데이터를 숨기고, 데이터를 다루는 함수만 공개한다.
  • 새로운 객체 타입을 추가하기는 쉽다. (기존 동작을 변경하지 않음)
  • 기존 객체에 새로운 동작을 추가하기는 어렵다.

자료 구조

  • 데이터를 그대로 공개하며, 별다른 기능을 제공하지 않음
  • 새로운 동작을 추가하기는 쉽다.
  • 새로운 자료 구조를 추가하기는 어렵다.

결국, 객체와 자료 구조는 상호보완적으로 활용해야 하며, 특정 상황에 따라 적절히 선택하는 것이 중요하다.

 

디미터 법칙 (Law of Demeter)

 

모듈은 자신이 직접 조작하는 객체의 내부 구조를 몰라야 한다.

원칙

  • 객체는 데이터를 숨기고, 기능만을 공개해야 한다.
  • 즉, 객체는 조회 메서드로 내부 구조를 노출해서는 안 된다.
  • 클래스 C의 메서드 f는 다음과 같은 객체의 메서드만 호출해야 한다.
    • 클래스 C 자체
    • f가 생성한 객체
    • f의 매개변수로 전달된 객체
    • C의 인스턴스 변수로 저장된 객체
  • 위 객체에서 허용된 메서드가 반환하는 객체의 메서드는 호출하면 안된다.
    • 이 원칙을 어기는 대표적인 예시가 "기차 충돌 (Train Wreck)"이다.

디미터 법칙 위반 예시 (기차 충돌)

final String outputDir = ctxt.getOptions().getScratchDir().getAbsolutePath();
  • ctxt → getOptions() → getScratchDir() → getAbsolutePath() 형태로 여러 객체를 연쇄적으로 호출하고 있다.
  • 내부 객체의 내부까지 탐색하는 방식이므로 디미터 법칙을 위반한다.

개선된 코드

Option opts = ctxt.getOptions();
File scratchDir = opts.getScratchDir();
final String outputDir = scratchDir.getAbsolutePath();

이렇게 중간 변수를 사용하면 기차 충돌을 완화할 수 있다. 하지만 여전히 ctxt, Options, ScratchDir이 객체인지 자료 구조인지에 따라 디미터 법칙을 위반하는지 여부가 달라진다.

  • 객체라면 내부 구조를 숨겨야 하므로 디미터 법칙을 위반한 것이다.
  • 자료 구조라면 내부 구조를 노출하는 것이므로 위반이 아니다.

 

DTO (Data Transfer Object)

 

DTO는 데이터를 전달하는 용도로 사용되는 자료 구조이며, 일반적으로 비공개 변수를 조회/설정하는 getter/setter 메서드를 가진다.

활성 레코드 (Active Record)

  • DTO의 특수한 형태로, 데이터베이스 테이블을 직접 반영하는 구조이다.
  • 데이터 저장 및 조회 기능(save, find 등)을 제공한다.

주의사항

  • 활성 레코드에 비즈니스 로직을 추가하지 말 것
  • 활성 레코드는 자료 구조로 취급해야 하며, 객체로 취급하지 않는다.
  • 비즈니스 로직을 포함하면서 내부 데이터를 숨기는 객체는 따로 생성하는 것이 좋다.

 

객체와 자료 구조의 차이를 이해하고, 상황에 맞는 방식을 선택하는 것이 중요하다.

728x90

'공부' 카테고리의 다른 글

SOLID 원칙  (3) 2025.03.26
템플릿 메서드 패턴 vs 전략 패턴  (2) 2025.03.16
상속과 합성: 코드 재사용과 확장의 방법  (0) 2025.03.09
equals()와 hashCode()의 개념과 관계  (0) 2025.03.01
단위 테스트  (0) 2025.03.01