[스터디] 디자인 패턴

Jun_k·2026년 5월 1일

CS

목록 보기
8/16

이터레이터 패턴

  • 컬렉션(List, Set, Map 등)은 데이터를 저장하는 방식이 모두 다르다.
    이터레이터 패턴은 데이터를 어떻게 저장하는지 몰라도(캡슐화),
    그 안의 요소들을 하나씩 꺼내는 방법만 표준화하는 패턴이다.

  • 사용하는 이유는 자료구조가 변경되어도(예: ArrayList -> LinkedList)
    순회 로직 자체를 수정할 필요가 없다.

  • 컬렉션 내부의 복잡한 구현(트리 구조, 해시 테이블 등)을
    외부에 노출하지 않고도 안전하게 요소를 전달할 수 있다.

Java 17 예시

  • 자바에서는 이미 java.util.Iterator 인터페이스를 통해
    이 패턴을 내장하고 있다.
import java.util.Iterator;
import java.util.List;

public class IteratorExample {
    public static void main(String[] args) {
        // ArrayList 형태로 저장된다.
        List<String> fruits = List.of("Apple", "Banana", "Orange");

        // 표준 이터레이터 사용 (자료구조를 몰라도 순회 가능)
        Iterator<String> iterator = fruits.iterator();
        
        while (iterator.hasNext()) {
            String fruit = iterator.next();
            System.out.println("과일: " + fruit);
        }

        for (String fruit : fruits) {
            System.out.println("과일은: " + fruit);
        }
    }
}

옵저버 패턴

  • 어떤 객체의 상태가 변할 때
    그와 연관된 다른 객체들에게 자동으로 알림을 보내는
    1:N 관계의 디자인 패턴이다.

  • 사용하는 이유는 주체(Subject)와 관찰자(Observer)가
    서로를 구체적으로 알 필요가 없다(느슨한 결합).

  • 상태 변화를 실시간으로 반영해야 하는
    이벤트 기반 시스템(예: 주식 차트, 푸시 알림)에 적합하다.

Java 17 예시

  • 자바의 Observable는 Deprecated(권장되지 않음) 되었기에
    직접 인터페이스를 정의하거나
    Spring의 ApplicationEvent 등을 사용하는 것이 현대적이다.
import java.util.ArrayList;
import java.util.List;

// 옵저버 인터페이스
interface Observer {
    void update(String message);
}

// 주체 (Subject)
class NewsChannel {
    private final List<Observer> observers = new ArrayList<>();

    public void addObserver(Observer o) { observers.add(o); }
    
    public void notifyObservers(String news) {
        for (Observer o : observers) {
            o.update(news);
        }
    }
}

// 실행 예시
public class ObserverExample {
    public static void main(String[] args) {
        NewsChannel channel = new NewsChannel();

        // 익명 클래스 또는 람다를 사용한 옵저버 등록
        channel.addObserver(msg -> System.out.println("구독자 A 수신: " + msg));
        channel.addObserver(msg -> System.out.println("구독자 B 수신: " + msg));

        channel.notifyObservers("새로운 기능 출시");
    }
}

노출 모듈 패턴

  • 이 패턴의 본질은 "우리 집 주방(내부 로직)은 보여주기 싫고,
    음식(결과물)만 창구로 내보내겠다"는 선언이다.
  • 자바스크립트의 태생적 한계: 예전 자바스크립트는 모든 코드가
    전역(Global)에 노출 되었기에 내가 만든 count 변수가
    남이 만든 count 변수와 충돌해서 값이 멋대로 바뀌는 대참사가 빈번했다.

  • 해결책: 함수 안에 변수를 가두고(클로저)
    밖에서 쓰고 싶은 것만 객체에 담아 노출 시키기로 약속한 것이다.

  • 자바에서는 이 철학이 클래스의 접근 제어자로 이미 녹아들어 있다.

    • 비공개(Private): "내부 부품".
      외부에서 건드리면 고장 날 수 있는 로직이나 데이터이다.

    • 공개(Public/Interface): "리모컨 버튼". 사용자가 눌러야 할 최소한의 기능이다.

public class VendingMachine {
    // 숨겨진 것 (Private)
    private int moneyInside = 0;
    
    // 내부 로직은 건드릴 수 없게 private으로 막아 놓음.
    private void verifyCoin(int coin) {
        System.out.println(coin + "원이 유효한지 검사 중...");
    }

    // 노출된 것 (Public): 사용자가 볼 수 있는 '버튼'만 공개
    public void insertCoin(int coin) {
        verifyCoin(coin); // 내부 로직 호출
        this.moneyInside += coin;
        System.out.println("코인이 투입되었습니다.");
    }

    public String pushButton() {
        if (moneyInside >= 500) {
            return "콜라";
        }
        return "잔액 부족";
    }
}

MVVM 패턴

  • Model (데이터와 비즈니스 로직)

    • 애플리케이션에서 사용하는 실제 데이터와 그 데이터를 처리하는 로직이다. (DB, API 응답, Service 레이어 등)

    • UI가 어떻게 생겼는지 전혀 모른다.
      오직 "데이터는 무엇인가?"에만 집중한다.

  • View (사용자 인터페이스)

    • 사용자에게 보여지는 화면(UI) 그 자체이다.

    • 비즈니스 로직을 포함하지 않는다.
      오직 "어떻게 보여줄 것인가?"와
      "사용자의 입력(클릭 등)을 어떻게 받을 것인가?"만 담당한다.

  • ViewModel (상태 관리와 중재자)

    • View를 위한 Model이다.
      View에 표시될 데이터를 가공하고, View의 상태를 유지한다.

    • 가장 중요한 점은 ViewModel은 View를 참조하지 않는다.
      즉, "내 데이터를 누가 가져가는지" 몰라도 된다.
      대신 View가 ViewModel의 데이터를 관찰(Observe)하고 있다가
      값이 변하면 스스로 화면을 갱신한다.

왜 MVVM을 사용하는가?

  • 기존 MVC 패턴에서는 컨트롤러가
    View와 Model 사이를 일일이 간섭해야 했다.
    하지만 MVVM에서는 View가 ViewModel의 데이터에
    딱 붙어(Data Binding) 있어서
    ViewModel의 데이터만 바뀌면 화면은 알아서 바뀐다.
    덕분에 UI 코드가 매우 단순해진다.

  • "UI 없이도 로직을 테스트하기 위해서" (테스트 용이성)
    ViewModel은 View(화면)에 대한 코드가 한 줄도 없다.
    따라서 화면을 직접 띄우지 않고도
    "데이터가 제대로 가공되는지", "상태가 잘 변하는지"를
    JUnit 같은 도구로 완벽하게 테스트할 수 있다.

profile
개발을 즐겨보자.

0개의 댓글