[커널아카데미] 백엔드 12기 7주차 회고

david1-p·2025년 5월 11일

회고

목록 보기
7/27

 이번주는 SQL 모델링과 튜닝에 대해서 배웠다. 쉬우면서도 어려웠다. DB에서 내가 원하는 데이터를 추출해서 볼 수 있다는게 흥미로웠다. 데이터모델링과 SQL튜닝을 배우기 시작하지 암기할 것이 생각보다 많았다. 강사님께서는 당신이 말하신 것만 보면 된다고 했지만, 그것은 하나의 뼈대에 불과했고 약간의 살이 붙어야 이해가능했다. 뼈대라도 암기해야겠다.
 금주는 디자인 패턴 스터디를 하였는데, 내가 발표한 주제는 Facade 패턴이었다. Facade 패턴을 적용하기 전 코드, 적용 후의 코드를 비교 분석하여 간략하게 설명하겠다.

1. FACADE 패턴

1.1 Pacade 패턴 적용 전

// PersonWithoutFacade.java
public class PersonWithoutFacade {
    private final Refrigerator refrigerator;
    private final Grinder grinder;
    private final Filter filter;
    private final WaterPurifier waterPurifier;

    public PersonWithoutFacade() {
        this.refrigerator = new Refrigerator();
        this.grinder = new Grinder();
        this.filter = new Filter();
        this.waterPurifier = new WaterPurifier();
    }

    public Coffee makeCoffee() {
        CoffeeBean coffeeBean = refrigerator.getCoffeeBean();              // 냉장고에서 커피콩 꺼내기
        GrindedCoffeeBean grinded = grinder.grindCoffeeBean(coffeeBean);  // 커피 갈기
        filter.put(grinded);                                             // 필터에 갈은 커피 넣기
        String hotWater = waterPurifier.getHotWater();                   // 뜨거운 물 뽑기
        return putWaterToFilter(filter, hotWater);                       // 커피 추출
    }

    private Coffee putWaterToFilter(Filter filter, String hotWater) {
        System.out.println("필터에 " + hotWater + " 붓기");
        return new Coffee("부드러운 원두커피");
    }
}
  • 의존성 다발: PersonWithoutFacade가 네 개 클래스에 직접 의존
  • 높은 결합도: 서브시스템 구현이 바뀌면 PersonWithoutFacade도 함께 수정해야 함
  • 테스트 어려움: 개별 단계(원두 꺼내기, 분쇄, 여과, 물 추출)를 별도로 모킹하기 힘듦

1.2 Pacade 패턴 적용 후

// 1. 인터페이스 정의 - CoffeeMaker.java 
public interface CoffeeMaker {
    Coffee makeCoffee();
}

// 2. 구현체(Facade) 작성 - CoffeeMakerImpl.java
public class CoffeeMakerImpl implements CoffeeMaker {
    private final Refrigerator refrigerator;
    private final Grinder grinder;
    private final Filter filter;
    private final WaterPurifier waterPurifier;

    public CoffeeMakerImpl() {
        this.refrigerator = new Refrigerator();
        this.grinder       = new Grinder();
        this.filter        = new Filter();
        this.waterPurifier = new WaterPurifier();
    }

    @Override
    public Coffee makeCoffee() {
        CoffeeBean bean     = refrigerator.getCoffeeBean();
        GrindedCoffeeBean g = grinder.grindCoffeeBean(bean);
        filter.put(g);
        String hotWater = waterPurifier.getHotWater();
        return putWaterToFilter(filter, hotWater);
    }

    private Coffee putWaterToFilter(Filter filter, String hotWater) {
        System.out.println("필터에 " + hotWater + " 붓기");
        return new Coffee("부드러운 원두커피");
    }
}

// 3. 클라이언트 분리 - PersonWithFacade.java
public class PersonWithFacade {
    private final CoffeeMaker coffeeMaker;

    public PersonWithFacade() {
        this.coffeeMaker = new CoffeeMakerImpl();
    }

    public Coffee makeCoffee() {
        return coffeeMaker.makeCoffee();
    }
}

해결:
PersonWithFacade는 CoffeeMaker(고수준 Facade) 하나에만 의존하므로, 내부 구현이 바뀌어도 영향 범위가 최소화됩니다.

1.3 요약 정리

  • 의존성 경량화
  • PersonWithFacade는 오직 CoffeeMaker 하나만 알고 있어, 내부 구현 변경 무관
  • 유지보수성 향상
  • 서브시스템 클래스별 수정 범위를 격리
  • 테스트 편의성
  • 인터페이스 기반 설계로 Mockito 등으로 쉽게 Mock 처리 가능
  • 가독성 증가
  • 커피 제조 흐름이 한눈에 들어오는 API 제공
profile
DONE IS BETTER THAN PERFECT.

0개의 댓글