프리코스 2주차 미션을 진행하며 코드리뷰로 피드백 받은 '일급 객체','원시값포장' 도입에 대한 피드백을 받아 정리해 보고자 한다.
원시값 포장
원시값 포장(Primitive Wrapping)은 Java에서 원시 타입(Primitive Type) 데이터를 객체로 감싸는 작업을 의미한다.
일반적으로 데이터의 안전한 관리를 위해 사용되며, 원시 타입과 객체 간의 기능적 차이를 보완하고 객체 지향적 프로그래밍(OOP)의 장점을 활용하기 위한 기법이다.
원시값 포장의 개념
원시 타입(Primitive Type)은 값만을 저장하는 경량 데이터 타입으로, Java의 가장 기본적인 데이터 형태이다.
그러나 원시 타입은 메서드를 가지지 않고, 객체로 취급되지 않으며, 컬렉션과 같은 데이터 구조에서 사용할 수 없는 제약이 있다.
원시값 포장의 목적
- 값에 의미 부여: 단순한 숫자나 문자열 값에 의미를 부여하여 더 안전하고 명확하게 관리.
- 추가 기능 제공: 원시값과 관련된 유틸리티 메서드를 추가하여 로직을 캡슐화.
- 불변성 보장: 변경할 수 없는 값을 만들어 데이터의 안정성을 유지.
- 객체와의 통합: 컬렉션(List, Map 등)이나 객체지향적인 API 사용이 가능.
Java의 Wrapper 클래스
Java에서는 원시 타입을 포장하기 위한 Wrapper 클래스를 기본 제공하며, 이는 java.lang 패키지에 포함되어 있다.
int | Integer |
long | Long |
double | Double |
float | Float |
boolean | Boolean |
char | Character |
byte | Byte |
short | Short |
원시값 포장의 장점
객체지향적 프로그래밍 지원
- 원시값에 객체처럼 메서드를 호출하거나 로직을 추가 가능.
- 예: Integer 클래스의 메서드 활용.
Integer value = Integer.valueOf(42);
System.out.println(value.compareTo(100)); // -1
컬렉션 활용
- Java의 컬렉션(List, Set, Map 등)에서 원시값은 사용 불가능하며, 객체만 허용된다. Wrapper 클래스를 사용하면 원시값도 컬렉션에서 활용 가능하다.
List<Integer> numbers = new ArrayList<>();
numbers.add(42);
numbers.add(100);
System.out.println(numbers); // [42, 100]
불변성
- 원시값을 포장하여 변경 불가능한 상태로 유지하면, 데이터를 안전하게 관리 가능.
public final class Money {
private final int amount;
public Money(int amount) {
if (amount < 0) {
throw new IllegalArgumentException("금액은 음수일 수 없습니다.");
}
this.amount = amount;
}
public int getAmount() {
return amount;
}
}
의미 있는 데이터 타입
- 원시값을 포장하여 데이터의 의미를 명확히 표현 가능.
public class Age {
private final int value;
public Age(int value) {
if (value < 0) {
throw new IllegalArgumentException("나이는 음수일 수 없습니다.");
}
this.value = value;
}
public int getValue() {
return value;
}
}
원시값 포장의 단점
성능저하
- 원시값은 스택 메모리에 저장되지만, 객체는 힙 메모리에 저장되어 메모리 사용량 증가.
- 추가적인 메서드 호출 및 객체 생성 비용 발생.
NullPointerException위험
- 포장된 객체가 null일 경우, 잘못된 접근으로 NullPointerException 발생 가능.
Integer number = null;
System.out.println(number + 1); // NullPointerException
원시값 포장과 값 객체
원시값 포장은 단순히 값을 감싸는 것을 넘어서, 값 객체(Value Object)로 발전할 수 있다.
값 객체란?
- 데이터를 나타내는 객체로, 불변성을 갖고, 값으로 비교되는 객체.
- Equals/HashCode를 오버라이드하여 객체 동등성을 값으로 판단.
원시값 포장 vs Wrapper 클래스
원시값 포장
- 의미 부여: 원시값에 대해 더 많은 의미를 부여.
- 불변성: 값 변경 불가.
- 추가 로직: 데이터 검증, 연산 등을 포함.
Wrapper 클래스
- 단순히 원시 타입을 객체로 감싸는 역할.
- 주로 컬렉션 및 API 호환성을 위해 사용.
원시값 포장의 활용 사례
1. 도메인 객체
- 나이, 금액, 거리 등 도메인 로직에서 중요한 값을 객체로 포장하여 검증 및 제약 조건 추가.
2. 데이터 타입 명시
- 단순한 int 대신, 의미 있는 타입명을 사용하여 코드 가독성 및 안전성 향상.
요약
- 원시값 포장은 원시 타입 데이터를 객체로 감싸는 작업으로, 의미 부여와 안전성을 확보하기 위해 사용.
- Java에서는 기본 Wrapper 클래스(Integer, Double, 등)를 제공하며, 컬렉션 및 객체 지향적 프로그래밍을 지원.
- 원시값 포장은 도메인 객체와 불변성 객체 설계에서 중요한 역할을 하며, 추가적인 검증 및 기능 구현에 유용.
- 성능과 복잡성을 고려하여, 필요에 따라 적절히 사용하는 것이 중요.
VO
VO는 Value Object의 약자로, 객체 지향 프로그래밍에서 값을 표현하는 데 사용되는 객체이다. VO는 불변성을 유지하며, 값 그 자체로 동등성을 판단하고, 복잡한 비즈니스 로직을 단순화하는 데 도움을 준다. 특히 도메인 주도 설계(DDD, Domain-Driven Design)에서 중요한 역할을 한다.
VO의 정의
VO는 특정한 값이나 속성을 표현하는 객체로, 다음과 같은 특징을 가진다:
- 불변성(Immutable): VO는 생성된 이후 값을 변경할 수 없으며, 상태를 변경하려면 새로운 VO를 생성해야 한다.
- 값 기반 동등성: VO는 객체의 참조(reference)가 아니라, 값(value)으로 동등성을 판단한다.
- 도메인 표현: VO는 원시값이나 데이터를 감싸서 의미와 역할을 부여한다.
- 부작용 방지: 값 변경을 방지하여, 데이터 무결성과 안정성을 보장한다.
VO의 특징
불변성
- VO는 불변 객체로 설계되어야 한다. 이는 데이터 변경에 따른 부작용을 방지하고, 멀티스레드 환경에서도 안전하게 사용할 수 있게 한다.
값 동등성
- VO는 값 자체로 동등성을 판단하며, 두 VO 객체의 값이 같다면 두 객체는 같다고 간주되어, equals()와 hashCode() 메서드를 반드시 오버라이드해야 한다.
작은 단위의 역할
- VO는 작은 단위로 값을 포장하여 비즈니스 로직에서 의미를 명확히 한다. 예를 들어, 금액(Money), 나이(Age), 이메일(Email) 등을 VO로 표현할 수 있다.
데이터 캡슐화
- VO는 원시값을 캡슐화하여 데이터와 관련된 검증 로직이나 연산을 포함할 수 있다.
VO와 DTO, POJO의 차이
특징 | VO | DTO | POJO |
주요 목적 | 값을 나타내고, 값으로 동등성 판단 | 데이터 전송 및 계층 간 데이터 전달 | 간단한 객체 표현 (getter/setter 중심) |
불변성 | 불변성 보장 | 일반적으로 가변 객체 | 가변 객체 |
사용 위치 | 도메인 계층 (모델 또는 비즈니스 로직에서 사용) | 계층 간 데이터 전송 (컨트롤러-서비스 간, 서비스-DB 간) | 어떤 계층에서도 사용 가능 |
행위 포함 여부 | 값을 다루는 행위(검증, 연산 등) 포함 | 데이터를 단순히 담는 역할 | 포함하지 않음 |
equals()/hashCode | 반드시 오버라이드 | 필요에 따라 오버라이드 | 보통 오버라이드하지 않음 |
VO 설계의 이유와 장점
도메인 간결화
- VO는 원시값이나 데이터를 의미 있는 객체로 표현하므로, 도메인 로직이 간결해지고 명확해진다. 예: int price 대신 Price 객체를 사용하여 가격에 대한 검증과 연산을 캡슐화.
불변성으로 안전성 보장
- VO는 불변 객체이므로, 데이터 변경으로 인한 부작용이 발생하지 않는다.
- 멀티스레드 환경에서도 안전하게 사용할 수 있다.
동일성 판단이 명확
- VO는 값 자체로 동등성을 판단하므로, 객체 간 비교가 직관적이고 명확하다.
재사용성
- VO는 값과 관련된 검증 및 연산 로직을 포함하므로, 여러 곳에서 재사용 가능하며 중복 코드를 줄일 수 있다.
VO의 설계 방법
불변성을 유지
VO의 상태는 생성 시에만 설정 가능하며, 이후 변경할 수 없어야 한다. 이를 위해 final 키워드와 private 필드를 사용한다.
유효성 검증
VO의 생성 시 값의 유효성을 검증하여 잘못된 값으로 VO가 생성되지 않도록 해야 한다.
값 동등성 보장
equals()와 hashCode() 메서드를 반드시 오버라이드하여, VO가 값으로 동등성을 판단하도록 설정한다.
VO의 사용 사례
도메인 로직 표현
VO는 도메인 로직에서 원시값을 객체로 감싸, 의미를 명확히 표현하는 데 사용된다 예: Money, Email, Age, Name 등.
값 검증
VO는 값 생성 시 유효성 검증을 포함하여, 비즈니스 로직의 복잡성을 줄인다.
불변 데이터 처리
VO는 불변 객체이므로, 데이터 변경이 발생하지 않는 안정적인 로직을 보장한다.
ID 관리
VO는 엔티티(Entity)와 함께 사용되어 고유 ID를 표현하는 데 사용된다. 예: UserId, ProductId.
VO와 DDD (도메인 주도 설계)
VO는 DDD에서 매우 중요한 역할을 한다.
DDD에서는 값 객체를 통해 도메인의 의미를 명확히 표현하고, 원시값 대신 VO로 비즈니스 로직을 다룬다.
- 도메인 의미 강화: VO는 원시값에 도메인의 의미를 부여하여 코드의 가독성과 유지보수성을 향상시킨다.
- 상태 캡슐화: VO는 상태를 캡슐화하고, 관련 동작을 포함하여 도메인 로직을 단순화한다.
요약
1. VO(Value Object)는 값 자체를 표현하고 관리하는 객체로, 불변성을 유지하며 값 기반으로 동등성을 판단한다.
2. VO는 비즈니스 로직에서 원시값 대신 의미 있는 타입을 사용하여 가독성과 유지보수성을 높인다.
3. VO는 데이터 검증, 연산, 값 관리 등의 로직을 포함하며, 특히 도메인 주도 설계(DDD)에서 핵심적인 역할을 한다.
4. VO를 설계할 때는 불변성, 값 기반 동등성 판단, 유효성 검증, 비즈니스 로직 캡슐화 등을 고려해야 한다.
일급 객체
일급 객체(First-Class Citizen)는 프로그래밍 언어에서 다른 객체와 동등하게 취급될 수 있는 객체를 말한다. 일반적으로 변수에 할당되거나 함수의 인자로 전달되고, 함수의 반환값으로도 사용될 수 있는 특성을 가진다.
Java에서는 클래스, 객체, 그리고 특히 함수형 프로그래밍 요소에서 일급 객체 개념이 주로 사용된다.
일급 객체의 조건
Alan J. Perlis의 기준에 따르면, 일급 객체는 다음과 같은 조건을 만족해야 한다.
- 변수에 할당 가능: 객체를 변수에 할당하거나 데이터 구조에 저장할 수 있어야 한다.
- 함수의 인자로 전달 가능: 객체를 함수의 매개변수로 전달할 수 있어야 한다.
- 함수의 반환값으로 사용 가능: 함수가 객체를 반환할 수 있어야 한다.
- 동적으로 생성 가능: 객체를 실행 시간에 동적으로 생성할 수 있어야 한다
일급 객체의 특징
- 모든 객체와 동등한 권리: 일급 객체는 다른 데이터와 동일하게 취급되며, 제한 없이 조작할 수 있다.
- 고차 함수 지원: 일급 객체를 사용하면 함수가 다른 함수를 인자로 받거나, 함수를 반환할 수 있다.
- 동적 처리: 실행 중에 객체를 생성하고 조작할 수 있는 유연성을 제공한다.
일급 객체의 예시
변수에 할당 가능
- 람다 표현식(Runnable task)은 변수에 할당될 수 있다.
Runnable task = () -> System.out.println("Hello, world!");
task.run();
함수의 인자로 전달가능
- 함수(executeTask)가 Runnable 객체(람다)를 인자로 받을 수 있다.
public void executeTask(Runnable task) {
task.run();
}
executeTask(() -> System.out.println("Task executed!"));
함수의 반환값으로 사용가능
- 함수(createTask)가 Runnable 객체를 반환한다.
public Runnable createTask() {
return () -> System.out.println("Task created!");
}
Runnable task = createTask();
task.run();
Java에서의 일급 객체
Java의 모든 객체는 원칙적으로 일급 객체이다. 하지만 Java에서는 함수 자체를 값으로 다룰 수 없었기 때문에 함수형 프로그래밍 요소가 등장하기 전까지 함수는 일급 객체가 아니었다.
Java 8 이후 (람다와 함수형 인터페이스 도입)
Java 8부터 람다 표현식과 함수형 인터페이스가 도입되면서, 함수도 일급 객체처럼 다룰 수 있게 되었다.
람다 표현식
람다는 익명 함수를 객체처럼 다룰 수 있게 해주는 표현식이다.
Function<Integer, Integer> square = x -> x * x;
System.out.println(square.apply(5)); // 25
메서드 참조
메서드 참조를 통해 함수 자체를 변수에 할당하거나 인자로 전달 가능하다.
Function<String, Integer> parseInt = Integer::parseInt;
System.out.println(parseInt.apply("123")); // 123
일급 객체와 고차 함수
일급 객체는 고차 함수(High-Order Function)를 지원하는 핵심 개념이다.
고차 함수는 다음 중 하나 이상의 조건을 만족하는 함수이다:
- 함수를 인자로 받을 수 있음.
- 함수를 반환할 수 있음.
예제: 함수 인자로 전달
public static void process(Function<Integer, Integer> func, int value) {
System.out.println(func.apply(value));
}
process(x -> x * x, 5); // 25
예제: 함수 반환
public static Function<Integer, Integer> createMultiplier(int factor) {
return x -> x * factor;
}
Function<Integer, Integer> multiplyBy2 = createMultiplier(2);
System.out.println(multiplyBy2.apply(5)); // 10
Java의 일급 객체 활용 사례
Stream API
Stream API는 일급 객체 개념을 활용하여 함수를 처리할 수 있게 한다.
List<Integer> numbers = List.of(1, 2, 3, 4, 5);
List<Integer> squares = numbers.stream()
.map(x -> x * x) // 함수(람다)를 전달
.toList();
System.out.println(squares); // [1, 4, 9, 16, 25]
이벤트 처리
GUI 프로그래밍에서도 이벤트 리스너로 일급 객체를 활용한다.
button.setOnAction(event -> System.out.println("Button clicked!"));
비동기작업
CompletableFuture와 같은 비동기 API에서도 람다를 통해 비동기 작업을 정의한다.
CompletableFuture.supplyAsync(() -> "Hello, Async!")
.thenAccept(System.out::println);
일급 객체의 장점
- 재사용성 증가: 일급 객체로 처리하면, 함수나 로직을 재사용할 수 있는 유연성이 증가.
- 가독성 향상: 코드의 의도를 명확하게 표현할 수 있음.
- 유연한 설계: 실행 중에 함수나 객체를 동적으로 전달할 수 있어, 더 유연한 설계가 가능.
- 모듈화: 로직을 함수로 분리하여 관리가 쉬워짐.
일급 객체와 불변성
Java에서 일급 객체를 활용할 때, 불변성(immutability)을 유지하면 함수형 프로그래밍의 장점을 극대화할 수 있다.
불변 객체와 일급 객체를 조합하면 다음과 같은 이점을 얻을 수 있다:
- 멀티스레드 환경에서 안전성 보장.
- 데이터 변조 방지로 인해 예측 가능한 코드 작성 가능.
- 코드의 부작용(side-effect) 감소.
일급 객체의 한계
Java의 함수는 완전한 일급 객체가 아니다.
- Java에서 함수는 여전히 객체로 취급되지 않으며, 함수형 인터페이스를 통해 우회적으로 다룰 수 있다.
- 완전한 함수형 언어(예: Haskell)와 비교했을 때 제한적이다.
성능 문제
- 람다와 고차 함수 사용은 객체 생성 및 메모리 비용이 추가로 발생한다..
요약
- 일급 객체란 변수에 할당, 함수 인자로 전달, 함수 반환값으로 사용이 가능한 객체이다.
- Java에서는 람다 표현식과 함수형 인터페이스를 통해 함수가 일급 객체처럼 동작한다.
- 주요 특징:
- 고차 함수를 지원하여 유연한 설계 가능.
- 코드 재사용성과 가독성을 향상시킴.
- Stream API, 비동기 작업 등에서 널리 활용.
일급 컬렉션
일급 컬렉션은 컬렉션(Collection)을 감싸는 객체로, 컬렉션과 관련된 로직을 캡슐화하여 관리하는 객체이다. 일급 컬렉션은 컬렉션을 직접 사용하는 대신 불변성을 유지하고 비즈니스 로직을 포함하여 코드의 응집도와 가독성을 높이는 역할을 한다.
일급 컬렉션의 정의
- 컬렉션(List, Set, Map 등)을 단일 값으로 취급하는 객체.
- 컬렉션과 관련된 모든 로직과 제약 조건을 캡슐화하여 외부에서 컬렉션을 직접 조작하지 못하도록 함.
- 불변 객체(Immutable Object)로 설계하여 안전성을 보장.
일급 컬렉션의 특징
단일 컬렉션만 포함
- 일급 컬렉션은 하나의 컬렉션만을 포함하며, 추가적인 필드를 가지지 않음.
- 이를 통해 컬렉션의 역할이 명확해지고, 불필요한 책임 분산을 방지.
불변성
- 컬렉션을 외부에서 수정할 수 없도록 보장하며, 모든 변경 작업은 새로운 일급 컬렉션 객체를 반환.
- 이를 통해 데이터의 일관성과 안정성을 유지.
비즈니스 로직 캡슐화
- 컬렉션과 관련된 로직(정렬, 필터링, 검증 등)은 모두 일급 컬렉션 내부에서 처리.
- 외부에서 컬렉션을 직접 조작하지 않고, 필요한 작업은 메서드를 통해 수행.
컬렉션의 책임 분리
- 일급 컬렉션을 사용하면 컬렉션을 직접 사용하는 코드가 줄어들어, 컬렉션과 관련된 로직이 분리되고 응집도가 높아짐.
일급 컬렉션의 장점
응집도와 책임 분리
- 컬렉션과 관련된 로직이 일급 컬렉션 내부로 제한되어, 코드가 더 응집적이 되고 책임이 명확해짐.
불변성을 통한 안정성
- 외부에서 컬렉션을 수정하지 못하므로, 멀티스레드 환경에서도 안전하게 사용할 수 있음.
컬렉션 캡슐화
- 컬렉션을 직접 노출하지 않으므로, 외부에서 잘못된 사용으로 인한 버그를 방지.
도메인 로직 포함
- 컬렉션과 관련된 도메인 로직을 객체 안에 포함하여 코드의 가독성과 유지보수성을 높임.
일급 컬렉션의 활용 사례
도메인 로직 캡슐화
- 예를 들어, 쇼핑몰에서 장바구니와 관련된 로직을 CartItems 일급 컬렉션으로 캡슐화.
public class CartItems {
private final List<CartItem> items;
public CartItems(List<CartItem> items) {
this.items = Collections.unmodifiableList(items);
}
public BigDecimal calculateTotalPrice() {
return items.stream()
.map(CartItem::getPrice)
.reduce(BigDecimal.ZERO, BigDecimal::add);
}
}
상태 변경 방지
- 불변 컬렉션을 사용하여 데이터 변경을 방지하고, 새로운 상태를 반환.
public CartItems addItem(CartItem item) {
List<CartItem> newItems = new ArrayList<>(items);
newItems.add(item);
return new CartItems(newItems);
}
컬렉션 조작 간소화
- 컬렉션의 필터링, 정렬, 검색 등의 작업을 일급 컬렉션 내부에서 처리.
public List<CartItem> findItemsByCategory(String category) {
return items.stream()
.filter(item -> item.getCategory().equals(category))
.collect(Collectors.toList());
}
일급 컬렉션과 불변성
일급 컬렉션은 반드시 불변 객체로 설계해야 하며 이를 통해 데이터 변경을 방지하고 안정성을 보장할 수 있다.
불변성을 유지하는 방법
- Collections.unmodifiableList() 사용.
- 컬렉션을 외부에 반환할 때, 깊은 복사(deep copy) 제공.
- 컬렉션에 대한 setter 제거.
일급 컬렉션 vs 일반 컬렉션
특징 | 일급 컬렉션 | 일반 컬렉션 |
데이터 접근 | 컬렉션 내부의 메서드를 통해 간접적으로 접근 | 직접 접근 가능 (List.get()) |
불변성 | 보장 (일반적으로 unmodifiable로 설정) | 보장되지 않음 |
비즈니스 로직 포함 여부 | 포함 (검증, 연산, 필터링 등) | 포함하지 않음 |
유지보수성 | 응집도가 높아 유지보수 용이 | 로직 분산으로 유지보수 어려움 |
요약
- 컬렉션을 감싸는 객체로 설계하며, 컬렉션과 관련된 모든 로직을 캡슐화.
- 컬렉션의 불변성을 보장하여 데이터 변경으로 인한 문제를 방지.
- 컬렉션을 사용하는 비즈니스 로직을 객체 내부로 숨겨, 코드 응집도와 가독성을 높임.
- 컬렉션의 책임을 분리하여 유지보수성과 안정성을 향상.
- 단점으로는 설계 복잡성과 메모리 사용량 증가가 있지만, 장점이 이를 압도적으로 상회.
원시값 포장, VO, 일급 객체, 일급 컬렉션 핵심 개념 및 차이점 정리
원시값 포장
개념: 단순한 원시 타입(int, String 등)을 하나의 객체로 감싸 의미와 책임을 부여한 것.
예시: Money 클래스가 금액(int)을 감싸고, 금액 검증 로직을 추가로 포함.
특징:값의 검증과 조작을 내부적으로 처리 가능 및 도메인에서 값을 명확히 표현 가능.
VO
개념: 값 자체로 식별되는 객체. 불변성을 가지며, 상태 비교를 주로 함.
예시: Address 객체(시, 구, 동)를 묶어 하나의 값으로 표현.
특징: 객체의 동일성보다 값의 동등성을 중시(equals, hashCode 재정의 필요) 및 불변 객체로 설계하여 상태 변화 방지.
일급 객체
개념: 함수나 데이터를 변수, 매개변수, 반환값으로 자유롭게 전달할 수 있는 객체.
예시: Java에서 함수형 인터페이스 또는 람다 표현식.
특징: 데이터와 로직을 묶어 동적으로 전달 가능 및 Java의 함수형 프로그래밍에서 활용(람다, Function)
일급 컬렉션
개념: 컬렉션(List, Map 등)을 단일 객체로 감싸 비즈니스 로직을 추가한 것.
예시: LottoNumbers 클래스가 번호 목록(List<Integer>)을 관리하며 중복 검사 로직 포함.
특징: 컬렉션을 직접 노출하지 않고, 상태와 로직을 캡슐화 및 데이터 조작이 아닌 비즈니스 의미를 담은 메서드 제공.
연관성과 차이점
계층 구조
원시값 포장 → VO → 일급 객체
↘
일급 컬렉션
기능의 확장
- 원시값 포장: 가장 단순한 형태 (검증 + 캡슐화)
- VO: 원시값 포장 + 값 동등성
- 일급 객체: VO + 행위/책임
- 일급 컬렉션: 컬렉션에 특화된 일급 객체
사용 시점
- 원시값 포장: 단순 검증이 필요할 때
- VO: 여러 값의 조합이 의미를 가질 때
- 일급 객체: 비즈니스 로직이 필요할 때
- 일급 컬렉션: 컬렉션에 대한 책임이 필요할 때
예시로 보는 차이
// 원시값 포장
class Age { private final int value; }
// VO
class Position {
private final int x;
private final int y;
}
// 일급 객체
class Price {
private final int amount;
public Price add(Price other) { ... }
public Price multiply(int quantity) { ... }
}
// 일급 컬렉션
class Cart {
private final List<Item> items;
public Money calculateTotal() { ... }
public boolean hasItem(Item item) { ... }
}
요약
개념 | 원시값 포장 | VO | 일급 객체 | 일급 컬렉션 |
핵심 | 원시값 + 의미 추가 | 값 자체로 식별 | 함수나 데이터를 동적으로 전달 | 컬렉션 + 의미와 비즈니스 로직 |
주요 특징 | 책임 부여, 검증 로직 포함 | 불변성, 값의 동등성 중시 | 동적 전달 가능 | 컬렉션 캡슐화, 비즈니스 로직 추가 |
예시 대상 | 금액, 전화번호, 나이 | 주소, 좌표, 기간 | 함수, 데이터 | 로또 번호, 주문 목록 |
차이점 | 단일 값을 포장 | 여러 값을 묶어서 표현 | 데이터가 아닌 함수에도 적용 가능 | 컬렉션에 초점, 데이터 그룹 의미화 |
- 원시값 포장과 VO는 의미 부여와 책임을 추가하기 위해 원시값을 객체로 감싸는 공통점이 있지만, VO는 주로 값의 불변성과 동등성을 강조.
- 일급 객체는 데이터를 객체처럼 전달하며 로직을 동적으로 활용.
- 일급 컬렉션은 컬렉션을 감싸 비즈니스 로직과 상태 캡슐화를 강조
프리코스 미션을 진행하며 왜 객체지향, 객체지향을 외치는지 점점 몸소 느끼고 있다..!
객체지향프로그래밍(OOP)에는 정말 많은 개념들이 서로 합쳐지고 하나의 개념에 뿌리를 두고 발전하며 너무나 강력한 무기들이 탄생하는것 같다. 이번 게시글에서 위 개념들을 정리하면서도 일부는 완전히 이해하며 박수를 치며 감탄했지만 일부는 약 50% 정도만 이해가 되었다. 하지만 이 또한 꾸준히 공부하다보면 온전히 체득할 수 있을 거라 믿는다 !! 프리코드 3주간 진행하며 이러한 믿음은 더더욱 커져간다 !
자자 이제 3주차 미션에 본격적으로 적용하러 가보자 !
'외부활동 > 우아한테크코스 [프리코스]' 카테고리의 다른 글
[우아한테크코스 7기] 프리코스 4주차 회고 (0) | 2024.11.12 |
---|---|
[우아한테크코스 7기] 프리코스 3주차 회고 (0) | 2024.11.05 |
정적 팩토리 메서드 톺아보기 (0) | 2024.11.01 |
상수관리에 Enum은 필수적인가 ? (0) | 2024.11.01 |
[우아한테크코스 7기] 프리코스 2주차 회고 (0) | 2024.10.29 |