728x90
UserFactory에서 'new User()' vs '{ ...dto } as User' 어떤 게 더 좋을까?
"객체 생성 시 new User()로 명시적으로 생성할지, 아니면 return { ...dto, ... } as User로 간결하게 처리할지 고민된다면, 이 글이 방향을 잡는 데 도움이 될 거예요."
상황: Factory를 도입했는데 객체 생성 방식이 고민된다
auth-service를 use-case 기반으로 리팩토링하면서 UserFactory를 도입했습니다. 그런데 다음 두 가지 방식 중 어떤 게 더 좋은 방식일까 고민이 생겼습니다
방식 A: Spread + Type Assertion
return {
...dto,
password: hashedPassword,
privacyAgreementDate: dto.agreedToPrivacyPolicy ? new Date() : null,
privacyAgreementExpireAt: dto.agreedToPrivacyPolicy
? new Date(Date.now() + 1000 * 60 * 60 * 24 * 365)
: null,
} as User;
방식 B: 명시적 생성 + 필드 지정
const user = new User();
user.name = dto.name;
user.email = dto.email;
user.password = hashedPassword;
user.phone = dto.phone;
user.agreedToPrivacyPolicy = dto.agreedToPrivacyPolicy;
user.privacyAgreementDate = dto.agreedToPrivacyPolicy ? new Date() : null;
user.privacyAgreementExpireAt = dto.agreedToPrivacyPolicy
? new Date(Date.now() + 1000 * 60 * 60 * 24 * 365)
: null;
return user;
결론 : 실제 서비스에서는 B 방식 (new User())이 더 적합하다
두 방식 비교
기준Spread + as 방식new User() 방식
가독성 | 간결하고 짧다 | 필드가 많으면 길어짐 |
타입 안정성 | as User는 컴파일러를 속인다 | 타입 체크가 철저히 적용됨 |
Entity 확장 대응력 | 클래스에 로직 추가 시 깨질 수 있음 | 확장에 안전 |
데코레이터 작동 | @BeforeInsert 등 작동 안 함 | 작동함 |
실무 적합성 | 테스트/Mock용으로 적절 | 실제 서비스에 적절 |
언제 무엇을 선택해야 할까?
상황 | 추천 방식 |
테스트용 객체 빠르게 만들기 | Spread + as 사용 가능 |
실제 DB 저장용 Entity 생성 | new User() 방식 사용 |
typeorm 데코레이터 쓰는 경우 | 반드시 new User() 사용 |
로직이 점점 복잡해질 예정 | new 방식이 확장에 안전 |
실무 팁
- as User는 TypeScript의 타입 안전성을 무시하고 강제로 타입을 부여하는 방식입니다. 구조가 다르더라도 통과될 수 있으므로 신중히 사용해야 합니다.
- TypeORM은 new Entity() 방식으로 생성했을 때만 @BeforeInsert나 lifecycle 훅들이 제대로 작동합니다.
회고
이번 리팩토링을 하면서 "간결한 코드가 반드시 좋은 코드일까?"에 대해 다시 생각해보게 됐습니다.
Factory는 책임 분리를 위해 도입되었고, 그렇다면 Entity 생성이라는 책임은 '정확하게' 수행되어야 합니다.
TypeScript와 TypeORM을 사용하는 백엔드 개발자로서, 앞으로도 단순함보다는 신뢰성과 확장성을 우선하는 코드를 작성해 나가려 합니다.
정리 문장
테스트에서는 spread + as 방식도 유용하지만,
실제 서비스에서는 반드시 new User()를 통한 생성이 안전하다.
이 글은 신입 백엔드 개발자로서 포트폴리오용 auth-service를 리팩토링하며 얻은 경험을 바탕으로 작성되었습니다.
반응형
'백엔드 개발 > API · 아키텍처 설계' 카테고리의 다른 글
DTO → Command → UseCase 패턴으로 본 구조적 백엔드 설계 (0) | 2025.05.26 |
---|---|
SOLID 원칙 완벽 이해와 실전 적용: 리팩토링 전후 코드로 배우는 객체 지향 설계 전략 (0) | 2025.05.22 |
Procedural 구조에서 Use Case 구조로, 내가 구조를 다시 짠 이유 (0) | 2025.05.08 |
[MSA] API Gateway는 왜 필요한가? – 인증, 보안, 확장성 중심의 설계 가이드 (0) | 2025.04.24 |
사이드 프로젝트 채팅 시스템 설계 Q&A – 안드로이드 & 백엔드 협업 정리 (2) | 2024.02.14 |