소프트웨어 설계 원칙: 관심사의 분리, 오브젝트 팩토리, DI와 디자인 패턴, 그리고 의존성 역전 원칙

궁금하면 500원·2024년 7월 1일

미생의 스프링

목록 보기
13/48

1. 관심사의 분리 (Separation of Concerns)

Static 제거와 this 컨텍스트

this 컨텍스트를 사용하지 않는 경우에는 메소드나 필드를 static으로 선언하는 것이 올바를 수 있습니다.
이를 통해 인스턴스에 종속되지 않는 메소드나 필드를 정의할 수 있습니다.

public class Utility {
    // 인스턴스와 무관하게 사용될 수 있는 메소드는 static으로 선언
    public static int add(int a, int b) {
        return a + b;
    }

    // 인스턴스의 상태에 따라 달라지는 메소드는 static으로 선언하지 않음
    public int multiply(int a, int b) {
        return a * b;
    }
}

validUntil과 exRate의 관계

validUntil과 exRate는 종종 서로 밀접한 관계를 가집니다.
예를 들어, 환율(exRate)의 유효 기간을 validUntil로 정의할 수 있습니다.

public class ExchangeRate {
    private double rate;
    private LocalDate validUntil;

    public ExchangeRate(double rate, LocalDate validUntil) {
        this.rate = rate;
        this.validUntil = validUntil;
    }

    public boolean isValid(LocalDate date) {
        return !date.isAfter(validUntil);
    }

    public double getRate() {
        return rate;
    }
}

시간 축의 복잡성

시간과 관련된 데이터 처리는 종종 복잡할 수 있습니다.
예를 들어, 날짜와 시간에 따른 유효성 검사가 필요할 수 있습니다.

public class TimeBasedService {
    public boolean isServiceAvailable(LocalDateTime currentTime) {
        LocalDateTime startTime = LocalDateTime.of(2024, 1, 1, 9, 0);
        LocalDateTime endTime = LocalDateTime.of(2024, 12, 31, 18, 0);

        return !currentTime.isBefore(startTime) && !currentTime.isAfter(endTime);
    }
}

2. 오브젝트 팩토리 (Object Factory)

ObjectFactory의 의존성

ObjectFactory는 PaymentService와 WebApiExRateProvider를 가리키고 있지만,
코드에서는 ExRateProvider 인터페이스를 명시적으로 다루고 있습니다.

public interface ExRateProvider {
    double getExchangeRate();
}

public class WebApiExRateProvider implements ExRateProvider {
    @Override
    public double getExchangeRate() {
        // 웹 API에서 환율을 가져오는 로직
        return 1.2;
    }
}

public class ObjectFactory {
    public ExRateProvider createExRateProvider() {
        // WebApiExRateProvider의 인스턴스를 생성
        return new WebApiExRateProvider();
    }
}

3. 구성정보를 가져오는 다른 방법

애노테이션과 자동 주입

@Autowired를 사용하여 생성자나 필드에 자동으로 빈을 주입할 수 있습니다. 하지만 애노테이션 외에도 XML 설정 등 다른 방법을 사용할 수 있습니다.

@Component
public class MyService {
    private final MyRepository myRepository;

    @Autowired
    public MyService(MyRepository myRepository) {
        this.myRepository = myRepository;
    }
}

4. DI와 디자인 패턴 (Dependency Injection and Design Patterns)

validUntil과 exRate의 캐시 만료 관계

validUntil과 exRate 사이의 관계를 이해하고, 캐시 관리와 관련된 디자인 패턴을 적용하여 캐시 만료를 효과적으로 처리합니다.

public class CacheManager {
    private final Map<String, CacheEntry> cache = new HashMap<>();

    public void put(String key, Object value, LocalDateTime validUntil) {
        cache.put(key, new CacheEntry(value, validUntil));
    }

    public Object get(String key, LocalDateTime currentTime) {
        CacheEntry entry = cache.get(key);
        if (entry != null && !currentTime.isAfter(entry.validUntil)) {
            return entry.value;
        }
        return null;
    }

    private static class CacheEntry {
        private final Object value;
        private final LocalDateTime validUntil;

        public CacheEntry(Object value, LocalDateTime validUntil) {
            this.value = value;
            this.validUntil = validUntil;
        }
    }
}

@Qualifier의 사용

@Qualifier는 빈의 이름을 명시적으로 지정하여 구분할 때 사용됩니다.
데코레이터 패턴에서의 사용 가능성을 이해합니다.

@Service
public class MyService {
    private final PaymentProcessor paymentProcessor;

    @Autowired
    public MyService(@Qualifier("creditCardProcessor") PaymentProcessor paymentProcessor) {
        this.paymentProcessor = paymentProcessor;
    }
}

5. 의존성 역전 원칙 (Dependency Inversion Principle)

인터페이스의 모듈 분리

인터페이스를 별도의 모듈로 분리하는 것이 DIP에 부합할 때가 많습니다. 클라이언트와 독립적인 인터페이스의 위치를 결정합니다.

// 도메인 모델 계층
public interface Repository<T> {
    void save(T entity);
    T findById(Long id);
}

// 데이터베이스 계층
public class JpaRepository<T> implements Repository<T> {
    @Override
    public void save(T entity) {
        // JPA를 사용하여 저장
    }

    @Override
    public T findById(Long id) {
        // JPA를 사용하여 검색
        return null;
    }
}

[출처]
토비의스프링 6

profile
에러가 나도 괜찮아 — 그건 내가 배우고 있다는 증거야.

0개의 댓글