DI와 디자인 패턴
2024. 7. 4. 16:50ㆍ토비의 스프링 6
디자인 패턴을 구분하는 두 가지 방식이 있다.
하나는 사용 목적(purpose)이고 다른 하나는 스코프(scope)이다.
스코프에 의해서 분류하면 클래스 패턴과 오브젝트 패턴으로 나눌 수 있다.
클래스 패턴은 상속(inherence)을 이용해서 확장성을 가진 패턴으로 만들어지고, 오브젝트 패턴은 합성(composition)을 이용한다. 대부분의 디자인 패턴은 오브젝트 패턴이다. 가능하면 오브젝트 합성을 상속보다 더 선호하라는 디자인 패턴의 기본 객체지향 원리를 따른 것이다.

오브젝트 합성을 이용하는 디자인 패턴을 적용할 때 스프링의 의존관계 주입(Dependenct Injection)을 사용



WebApiExRateProvider에 캐시 기능을 추가하려면?
WebApiExRateProvider 코드 수정
->데코레이터(Decorator) 디자인 패턴 : 오브젝트에 부가적인 기능/책임을 동적으로 부여한다.

- CachedExRateProvider를 사용할 때 WebApiExRateProvider를 불러와야한다.
최종 구조

CachedExRateProvider
package tobyspring.hellospring;
import java.io.IOException;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
public class CachedExRateProvider implements ExRateProvider{
private final ExRateProvider target;
private BigDecimal cachedExRate;
private LocalDateTime cachedExpiryTime;
public CachedExRateProvider(ExRateProvider target) {
this.target = target;
}
@Override
public BigDecimal getExRate(String currency) throws IOException {
if(cachedExRate==null || cachedExpiryTime.isBefore(LocalDateTime.now())){
cachedExRate=this.target.getExRate(currency);
cachedExpiryTime = LocalDateTime.now().plusSeconds(3);
System.out.println("Cache Updated");
}
return cachedExRate;
}
}
ObjectFactory
package tobyspring.hellospring;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class ObjectFactory {
@Bean
public PaymentService paymentService() {
return new PaymentService(cachedExRateProvider());
}
@Bean
public ExRateProvider cachedExRateProvider(){
return new CachedExRateProvider(exRateProvider());
}
@Bean
public ExRateProvider exRateProvider(){
return new SimpleExRateProvider();
}
}
Client
package tobyspring.hellospring;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.concurrent.TimeUnit;
public class Client {
public static void main(String[] args) throws IOException, InterruptedException {
BeanFactory beanFactory = new AnnotationConfigApplicationContext(ObjectFactory.class);
PaymentService paymentService = beanFactory.getBean(PaymentService.class);
Payment payment1 = paymentService.prepare(100L,"USD", BigDecimal.valueOf(50.7));
System.out.println("Payment1 : " + payment1);
System.out.println("-----------------------------------------------\n");
TimeUnit.SECONDS.sleep(3);
Payment payment2 = paymentService.prepare(100L,"USD", BigDecimal.valueOf(50.7));
System.out.println("Payment2 : " + payment2);
}
}'토비의 스프링 6' 카테고리의 다른 글
| 테스트 (0) | 2024.07.06 |
|---|---|
| 의존성 역전 원칙(Dependency Inversion Principle) (0) | 2024.07.04 |
| 싱글톤 레지스트리 (0) | 2024.07.03 |
| 구성정보를 가져오는 다른 방법 (0) | 2024.07.03 |
| 스프링 컨테이너와 의존관계 주입 (0) | 2024.07.03 |