PHP 실무에서 PHP Trait 남용을 피하는 방법
페이지 정보

영삼이
본문
✅ 실무에서 PHP Trait 남용을 피하는 방법
Trait는 PHP에서 다중 상속을 흉내낼 수 있게 해주는 기능으로, 여러 클래스 간 코드 재사용을 위해 도입되었습니다. 하지만 잘못 사용하면 코드 구조가 불명확해지고, 유지보수성이 급격히 낮아질 수 있습니다. 이 글에서는 Trait의 올바른 사용법과 남용을 피해야 하는 상황을 구체적으로 설명합니다.
🧩 Trait 기본 예시
[code=php]
trait LoggerTrait {
public function log(string $message): void {
file_put_contents('app.log', $message . PHP_EOL, FILE_APPEND);
}
}
class UserService {
use LoggerTrait;
public function register() {
$this->log("회원 가입 시도");
}
}
[/code]
-
공통 로직을 여러 클래스에서 공유 가능
-
중복 코드 제거에 유리
❌ 잘못된 사용 사례: 책임 혼란
[code=php]
trait AuthTrait {
public function checkPermission($user) {
// 권한 체크
}
public function logLogin($user) {
// 로그인 로그 남기기
}
public function sendLoginEmail($user) {
// 이메일 발송
}
}
[/code]
-
하나의 Trait에 역할이 다른 메서드들이 섞여 있음
-
재사용은 되지만 응집도 낮고 책임이 불명확
⚠️ Trait 남용 시 문제점
문제 | 설명 |
---|---|
책임 분리 실패 | 단일 책임 원칙 위반 (SRP) |
충돌 위험 | 여러 Trait이 동일한 메서드 포함 시 충돌 발생 가능 |
테스트 어려움 | Trait 단위 테스트 불가능 (클래스에 의존해야 함) |
IDE 탐색 불편 | 정의 위치가 분산되어 가독성 저하 |
✅ 올바른 사용 기준
1. 역할이 명확한 경우만 사용
[code=php]
trait TimestampTrait {
protected DateTime $createdAt;
public function setCreatedAt(DateTime $date): void {
$this->createdAt = $date;
}
}
[/code]
-
도메인 상 "모든 엔티티가 생성일시를 가져야 한다"는 일관된 목적일 경우 OK
2. 작고 독립적인 기능만 포함
-
하나의 Trait은 하나의 책임만 가지도록 구성
-
이름도
LoggerTrait
,SoftDeleteTrait
등 기능 중심으로 명확히
3. 가능하면 인터페이스 + 서비스 클래스로 분리 고려
[code=php]
interface LoggerInterface {
public function log(string $message): void;
}
class FileLogger implements LoggerInterface {
public function log(string $message): void {
file_put_contents('app.log', $message, FILE_APPEND);
}
}
[/code]
→ DI 컨테이너를 통해 주입하면 재사용성과 확장성이 훨씬 높아짐
---
### 💡 추천 사용 예
- 공통적인 상태 또는 유틸 함수 (예: `SoftDeletes`, `HasUuid`)
- 도메인 속성의 재사용 (`Timestamps`, `Blameable`)
- 의존성이 없고, 기능이 작고, 책임이 명확할 때
---
### 🧠 요약
- Trait은 **강력한 도구지만 양날의 검**
- 코드를 공유하려고 무작정 Trait에 때려 넣는 순간 유지보수 지옥
- 책임이 명확하고 작고 독립적인 기능만 포함할 것
- 클래스 구조가 복잡해지면 인터페이스와 서비스 클래스로 전환 고려
---
- 이전글PHP에서 상태 패턴(State Pattern) 활용 예시 25.03.28
- 다음글PHP 8.1 Fibers 고급 사용법 25.03.28
댓글목록
등록된 댓글이 없습니다.