디자인패턴, OOP
관심사의 분리 (Separation of Concerns, SoC)
TedDev
2025. 1. 12. 17:38
728x90
관심사의 분리는 소프트웨어 설계 원칙 중 하나로 시스템을 서로 다른 "관심사(Concern)"로 나누어 설계하는 것을 말한다. 관심사는 소프트웨어에서 처리해야 하는 특정한 문제나 기능의 집합으로 이를 분리하면 코드의 가독성, 유지보수성, 재사용성이 향상된다.
1. 관심사(Concern)란 무엇인가?
- 관심사는 소프트웨어 시스템에서 처리해야 할 특정 기능이나 책임을 말한다.
- 예를 들어, 웹 애플리케이션에서 다음과 같은 관심사를 식별할 수 있다
- UI 처리 : 사용자와 상호작용을 처리하는 역할
- 비즈니스 로직 : 시스템의 핵심 규칙과 동작
- 데이터베이스 접근 : 데이터를 저장하거나 조회하는 역할
- 로그 관리 : 애플리케이션의 동작을 기록
- 에러 처리 : 예외 상황을 처리
2. 관심사의 분리 원칙
관심사의 분리는 서로 다른 관심사를 분리하여 독립적으로 설계하고 구현하는 것을 목표로 한다. 이를 통해 다음과 같은 이점을 얻을 수 있다.
역할과 책임의 명확화
- 각 모듈이나 클래스가 명확한 책임을 가지며 특정 역할만 수행한다.
- 변경 사항이 생기더라도 한 모듈만 수정하면 되므로 변경의 영향을 최소화할 수 있다.
유지보수성 향상
- 코드가 독립적이고 명확하게 분리되어 있어 코드 이해와 수정이 용이하다.
코드 재사용성 증가
- 관심사가 분리된 모듈은 다른 프로젝트나 시스템에서 재사용하기 쉽다.
테스트 용이성
- 각 관심사가 독립적이므로 단위 테스트를 쉽게 작성할 수 있다.
3. 관심사의 분리를 실현하는 방법
다양한 설계 및 아키텍처 패턴을 통해 관심사의 분리를 실현할 수 있다.
레이어드 아키텍처
- 애플리케이션을 여러 계층으로 나누어 관심사를 분리한다.
- 프레젠테이션 계층 : 사용자와의 상호작용 담당 (UI, Controller)
- 비즈니스 로직 계층 : 핵심 비즈니스 로직 처리
- 데이터 접근 계층 : 데이터베이스와의 상호작용 담당
MVC 패턴
- 관심사를 Model, View, Controller로 분리한다.
- Model : 데이터와 비즈니스 로직
- View : 사용자에게 표시되는 화면
- Controller : 사용자 요청을 처리하고 Model과 View를 연결
모듈화
- 기능별로 모듈을 나누어 관심사를 분리한다.
- 예: 결제 모듈, 사용자 관리 모듈, 상품 관리 모듈 등
AOP (Aspect-Oriented Programming)
- 비즈니스 로직과 관계없는 공통적인 관심사(로깅, 트랜잭션 관리 등)를 분리하여 코드에 혼합되지 않도록 한다.
@Aspect
@Component
public class LoggingAspect {
@Before("execution(* com.example.service.*.*(..))")
public void logBefore(JoinPoint joinPoint) {
System.out.println("Method: " + joinPoint.getSignature().getName());
}
}
4. 관심사의 분리가 잘된 시스템의 특징
- 독립성 : 각 모듈이나 클래스가 특정한 관심사만 처리하며, 다른 관심사에 의존하지 않는다.
- 결합도 감소 : 모듈 간의 결합도가 낮아 변경에 대한 영향이 최소화된다.
- 응집도 증가 : 각 모듈이 자신의 책임에만 집중한다.
5. 관심사의 분리가 부족한 경우의 문제점
- 복잡성 증가 : 코드에 여러 관심사가 혼합되어 있어 이해하기 어렵다.
- 변경의 어려움 : 하나의 변경이 여러 곳에 영향을 미쳐 수정 시 리스크가 커진다.
- 재사용성 감소 : 특정 관심사와 강하게 결합된 코드는 다른 곳에서 재사용하기 어렵다.
- 테스트 어려움 : 관심사가 혼합되어 있어 독립적인 단위 테스트를 작성하기 어렵다.
6. 예제 : 관심사의 분리 적용 전후
적용 전
class UserManager {
void saveUser(String user) {
// 데이터베이스 저장
System.out.println("Saving user to DB: " + user);
// 이메일 전송
System.out.println("Sending email to user: " + user);
}
}
적용 후
class UserRepository {
void save(String user) {
System.out.println("Saving user to DB: " + user);
}
}
class EmailService {
void sendEmail(String user) {
System.out.println("Sending email to user: " + user);
}
}
class UserManager {
private final UserRepository userRepository;
private final EmailService emailService;
UserManager(UserRepository userRepository, EmailService emailService) {
this.userRepository = userRepository;
this.emailService = emailService;
}
void saveUser(String user) {
userRepository.save(user);
emailService.sendEmail(user);
}
}
7. 요약
관심사의 분리(Separation of Concerns)는 소프트웨어의 모듈성과 유지보수성을 높이는 중요한 설계 원칙이다.
이를 통해 각 관심사를 명확히 분리하여 코드의 가독성, 재사용성, 테스트 용이성을 확보할 수 있다. 다양한 설계 패턴(MVC, AOP 등)과 원칙(SRP 등)을 활용하여 효과적으로 구현할 수 있다.
반응형