Search

원시 값을 포장하는 Value Object

Tags
OOP
Date
2024/08/06

1. 개요

우리는 종종 원시 값을 포장한 Value Object를 볼 수 있습니다. Value Object는 원시 값을 클래스로 포장하여 의미를 명확히 하고, 해당 값의 유효성을 검증할 수 있는 장점을 제공합니다.

2. 내부 검증

원시 값 포장을 통해서 우리는 값을 더욱 더 안전하게 사용할 수 있습니다. Value Object는 객체 생성 시 값을 검증하여 잘못된 값이 사용되는 것을 방지할 수 있습니다. 예를 들어, 나이를 나타내는 값을 포장한 객체를 생각해봅시다.
public class Age { private final int value; public Age(int value) { if (value < 0 || value > 150) { throw new IllegalArgumentException("나이는 0 이상 150 이하이어야 합니다."); } this.value = value; } public int getValue() { return value; } }
Java
복사
위 예제에서 Age 클래스는 나이 값이 유효한지 검증하고, 잘못된 값이 들어올 경우 예외를 던집니다. 이렇게 함으로써 나이를 사용할 때 항상 유효한 값만 사용하도록 보장할 수 있습니다.

3. 진정한 객체 지향

다음 코드를 함께 봅시다.
class Car { private String driver; private int position; public void accelerate() { this.position++; } }
Java
복사
위 클래스는 단순히 driver라는 이름의 String 값과 position이라는 이름의 int 값을 가지고 있는 클래스일 뿐입니다. 이 클래스는 단순히 데이터를 저장하고 몇 가지 동작을 수행할 수 있지만, 진정한 객체 지향의 이점을 충분히 활용하지는 못하고 있습니다.
우리가 진정한 객체 지향 설계를 사용하여 Car 클래스를 개선해봅시다. 예를 들어, driver와 position을 별도의 Value Object로 분리하고, 각 Value Object가 자신의 유효성을 검증하도록 할 수 있습니다.
class Car { private Driver driver; private Position position; public Car(Driver driver, Position position) { this.driver = driver; this.position = position; } public void accelerate() { this.position = this.position.increment(); } public String getDriverName() { return this.driver.getName(); } public int getPosition() { return this.position.getValue(); } } class Driver { private final String name; public Driver(String name) { if (name == null || name.isEmpty()) { throw new IllegalArgumentException("운전자의 이름은 비어있을 수 없습니다."); } this.name = name; } public String getName() { return name; } } class Position { private final int value; public Position(int value) { if (value < 0) { throw new IllegalArgumentException("위치는 음수일 수 없습니다."); } this.value = value; } public Position increment() { return new Position(this.value + 1); } public int getValue() { return value; } }
Java
복사
위 예제에서 Car 클래스는 Driver와 Position이라는 Value Object를 가지고 있습니다. Driver와 Position은 각각 자신의 유효성을 검증하며, Car 클래스는 이 Value Object들을 조합하여 동작합니다. 이렇게 함으로써 각 클래스의 책임이 명확해지고, 코드의 재사용성과 유지보수성이 향상됩니다.