반응형
🌟 DI와 스프링으로 더 나은 코드 설계하기
✨ 핵심 개념 한눈에 보기
- DI의 힘: 객체 연결을 유연하게, 코드 설계를 깔끔하게.
- 스프링의 도구: 반복 작업 줄이고 생산성 높임.
- 목표: 변경에 강하고 유지보수 쉬운 코드 만들기.
- 철학: 객체지향 설계를 실현하는 기반 제공.
🛠️ 설계 단계별 상세 정리
1️⃣ 변경 가능한 데이터 외부화
- 왜 필요한가?:
- SQL, 설정값 같은 텍스트 데이터가 코드에 섞이면 수정할 때마다 컴파일 필요 → 비효율적.
- 어떻게 하나?:
- 외부 리소스 사용: .sql 파일, .properties, DB 테이블에 저장.
- 가져오기: 런타임에 동적으로 로드.
- 구체적 예시:
- SQL 쿼리를 queries.sql 파일에 저장 → SqlLoader 클래스로 읽기.
- @Value("${db.query}")로 .properties에서 값 주입.
- 장점:
- 코드와 데이터 분리 → 수정 시 코드 건드릴 필요 없음.
- 배포 없이 설정 변경 가능.
2️⃣ 혼잡한 클래스 정리
- 문제:
- 하나의 클래스에 데이터 처리, 비즈니스 로직, UI 로직 등이 섞여 있음.
- 예: UserManager가 DB 쿼리, 사용자 인증, 로그 기록까지 다 함.
- 해결 과정:
- 인터페이스 정의:
- UserRepository(데이터), UserService(비즈니스), UserLogger(로깅)로 역할 분리.
- 코드 분리: 각 인터페이스에 맞춰 구현 클래스 작성.
- 접근 방식: 다른 기능은 인터페이스를 통해 호출.
- 예: UserService가 UserRepository를 DI로 사용.
- 인터페이스 정의:
- 검증 방법:
- 자기참조 빈:
- 클래스 내부에서 @Autowired로 자신을 주입해 테스트.
- 예: UserService 내부에서 this.repository.findUser() 호출로 동작 확인.
- 검증 후 → 별도 클래스로 분리(UserRepositoryImpl 등).
- 자기참조 빈:
- 실무 팁:
- 분리 전 단일 클래스에서 점진적 리팩토링 시작 → 안정성 확보 후 완전 분리.
3️⃣ 자주 쓰이는 의존 객체 관리
- 아이디어:
- 반복적으로 사용하는 객체를 디폴트 값으로 설정.
- 구체적 예시:
- DataSource나 HttpClient처럼 공통 객체를 @Bean으로 미리 정의.
- @Configuration 클래스에서 기본 설정 제공:
@Bean
public HttpClient defaultHttpClient() {
return new HttpClient("https://api.example.com");
}
장점:
- 모든 클래스에서 직접 생성하지 않아도 주입받아 사용.
- 설정 변경 시 한 곳만 수정하면 됨.
🚀 스프링의 도구 활용 심층 탐구
4️⃣ XML과 객체 매핑
- 도구: 스프링의 OXM(Object-XML Mapping) 추상화.
- 상세 설명:
- XML 데이터를 자바 객체로 변환하거나 반대로 매핑.
- 지원 기술: JAXB, Castor, JiBX 등.
- 실무 예시:
- 외부 API에서 XML 응답(<user><name>John</name></user>)을 받아 User 객체로 변환:
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setClassesToBeBound(User.class);
User user = (User) marshaller.unmarshal(new StreamSource(xmlInput));
- 장점:
- 복잡한 파싱 코드 작성 불필요.
- XML 구조 변경 시 매핑 설정만 수정.
5️⃣ 리소스 사용 최적화
- 상황:
- 외부 파일(설정, SQL), 클래스패스 리소스, URL 등을 다룰 때.
- 도구:
- 리소스 추상화: Resource 인터페이스로 통일된 접근 제공.
- 리소스 로더: ResourceLoader(ApplicationContext가 기본 구현).
- 구체적 예시:
- 파일 읽기:
@Autowired
ResourceLoader resourceLoader;
Resource resource = resourceLoader.getResource("classpath:queries.sql");
String sql = new String(Files.readAllBytes(resource.getFile().toPath()));
- 다양한 경로: file:/path, classpath:, http://.
- 장점:
- 환경에 따라 리소스 경로만 바꿔도 코드 수정 없음.
- 테스트 시 가짜 리소스 주입 가능.
6️⃣ 내장형 DB 사용
- 상황:
- 개발/테스트용으로 애플리케이션에 DB를 내장.
- 도구:
- 내장형 DB 추상화: H2, HSQLDB 지원.
- 전용 태그: <jdbc:embedded-database>.
- 구체적 예시:
- XML 설정
<jdbc:embedded-database id="dataSource" type="H2">
<jdbc:script location="classpath:schema.sql"/>
</jdbc:embedded-database>
- 스프링 부트라면 application.properties에 spring.datasource.url=jdbc:h2:mem:testdb 추가.
- 장점:
- 외부 DB 없이 빠른 환경 구축.
- 테스트 후 데이터 자동 롤백.
🌈 DI와 객체지향 설계 심층 분석
7️⃣ DI의 설계적 장점
- 핵심:
- DI를 의식하면 객체지향 원칙(단일 책임, 개방-폐쇄 등)이 자연히 적용.
- 상세 설명:
- 객체가 스스로 의존 객체를 만들지 않고 외부에서 주입받음 → 느슨한 결합.
- 예: OrderService가 PaymentGateway를 직접 생성 대신 DI로 받음.
- 실무 이점:
- 새로운 결제 방식 추가 시 PaymentGatewayImpl만 교체.
- 테스트 시 MockPaymentGateway 주입으로 검증.
8️⃣ 인터페이스 활용
- 기본:
- DI는 인터페이스를 통해 의존성 주입.
- 상세 설명:
- 인터페이스 분리 원칙(ISP): 클라이언트가 필요 없는 기능까지 강요받지 않음.
- 예: UserService가 UserRepository 인터페이스만 의존 → JdbcUserRepository든 JpaUserRepository든 상관없음.
- 분리 방법:
- 새 인터페이스 생성:
- PaymentGateway와 RefundGateway를 별도로 정의.
- 인터페이스 상속:
- BasicUserRepository를 상속받아 AdvancedUserRepository 확장.
- 새 인터페이스 생성:
- 실무 팁:
- 클라이언트 요구사항별로 인터페이스 세분화 → 유연성 증가.
9️⃣ 의존 객체 특화
- 상황:
- 특정 기능에 맞춘 의존 객체 필요.
- 방법:
- 맴버 클래스:
- 예: OrderService 내에 PaymentProcessor를 내부 클래스로 정의.
- 맴버 클래스:
class OrderService {
private class PaymentProcessor {
void process() { /* 특화 로직 */ }
}
}
- 위임:
- 중복 로직은 부모 클래스나 별도 객체에 맡김.
- 예: CommonLogger를 재사용하며 특화 로직만 추가.
- 장점:
- 코드 중복 감소.
- 특화 기능과 공통 기능 분리.
📋 전체 흐름 요약
- 데이터 관리: 변경 가능 데이터는 외부로 분리.
- 코드 정리: 인터페이스로 역할 분리 → DI로 연결.
- 스프링 활용: OXM, 리소스 로더, 내장 DB로 효율성 UP.
- DI 설계: 인터페이스 기반으로 유연성 확보.
- 최적화: 맴버 클래스와 위임으로 깔끔히 마무리.
💡 핵심 키워드와 한 줄 정리
- 외부 리소스: "변경은 밖에서 관리해요."
- 인터페이스: "책임을 나눠주는 설계의 첫걸음."
- DI: "유연함을 선물하는 연결고리."
- OXM: "XML을 객체로 바꾸는 마법."
- 리소스 로더: "어디든 리소스를 찾아줘요."
- 맴버 클래스: "특화된 기능을 품은 조력자."
반응형
'public void static main > Book' 카테고리의 다른 글
[토비의스프링] 9장-스프링 프로젝트 시작하기 (1) | 2025.02.28 |
---|---|
[토비의스프링] 8장-스프링이란 무엇인가? (0) | 2025.02.28 |
[토비의스프링] 6장-AOP (0) | 2025.02.26 |
[토비의스프링] 5장-서비스 추상화 (1) | 2025.02.21 |
[토비의스프링] 3장-템플릿 (0) | 2025.02.21 |
댓글