C/C++ 디자인 패턴 (3) — 팩토리 메서드(Factory Method)
내보내기 기능을 만든다고 하자. "헤더를 쓰고, 행을 하나씩 쓰고, 마무리한다"는 절차는 CSV든 JSON이든 같은데, 어떤 Writer 객체를 쓸지만 다르다. 이 절차를 가진 부모 클래스가 new CsvWriter를 직접 부르면 JSON을 지원할…
내보내기 기능을 만든다고 하자. "헤더를 쓰고, 행을 하나씩 쓰고, 마무리한다"는 절차는 CSV든 JSON이든 같은데, 어떤 Writer 객체를 쓸지만 다르다. 이 절차를 가진 부모 클래스가 new CsvWriter를 직접 부르면 JSON을 지원할…
HTTP 요청 객체 하나에 URL, 메서드, 타임아웃, 재시도 횟수, 헤더가 붙기 시작하면 생성자 인자 목록이 길어지고, 같은 타입 인자의 순서를 바꿔 써도 컴파일러는 알아채지 못한다. 빌더(Builder)는 복잡한 객체의 생성 과정을…
다크 모드를 지원하는 앱에서 버튼은 다크 테마로, 체크박스는 라이트 테마로 그려지는 버그는 흔하다. 화면 곳곳에서 new DarkButton, new LightCheckbox처럼 구체 클래스를 직접 만들면 "같은 패밀리끼리만 섞여야 한다"는 규칙을 지킬 곳이…
8편에서 만든 메뉴 시스템은 항목을 선택하면 command()가 불리는 데서 끝났다. 실제 프로그램에서는 "Save를 선택하면 문서를 저장한다"처럼 메뉴 항목과 애플리케이션의 동작을 연결해야 한다. 그런데 메뉴는 라이브러리 쪽 코드이고 문서는 애플리케이션 쪽…
스택이나 리스트 같은 컨테이너는 원소 타입과 무관하게 같은 알고리즘을 쓴다. 문제는 "아무 타입이나 담는다"를 어떻게 표현하느냐다. C는 void*, Java는 모든 클래스의 공통 기반 Object, C++은 템플릿을 쓴다. 방식마다 타입 안전성,…
10편의 컨테이너들은 원소를 담는 방식이 저마다 다르다. 연결 리스트는 노드 포인터를 따라가고 배열은 인덱스를 늘려 가므로, 내부 구조를 그대로 공개하면 컨테이너를 바꿀 때마다 순회 코드도 고쳐야 한다. 반복자(Iterator) 패턴은 내부…
5편의 자기 등록 팩토리는 새 도형 파일을 추가해도 기존 코드를 고치지 않았지만, 프로그램은 다시 빌드해야 했다. 플러그인(Plug-in)은 여기서 한 걸음 더 나아가 이미 배포된 호스트 프로그램에 공유 라이브러리(.so)를 실행 중에…
작은 도구를 여러 개 만들다 보면 main마다 설정 읽기, 로그 초기화, 종료 정리 같은 코드가 똑같이 반복된다. 애플리케이션 프레임워크(Application Framework)는 이 뼈대와 main을 프레임워크 쪽이 가져가고, 사용자는 클래스 하나를 상속해…
9편의 리스너와 핸들러는 메뉴 항목처럼 이벤트를 보내는 객체에 직접 등록해야 했다. 배터리 부족이나 테마 변경처럼 발신자가 하나로 정해지지 않거나, 수신자가 발신자 객체에 접근할 수 없는 이벤트에는 맞지 않는다. iOS·macOS의 NSNotificationCenter는…
메뉴는 실행할 수 있는 항목(Open, Save)과 다른 메뉴를 담는 팝업 메뉴(File, Recent)로 이루어지고, 팝업 안에 팝업이 다시 들어가는 트리 구조다. 두 종류를 따로 다루면 "이 항목이 팝업인가?"를 묻는 분기가 곳곳에…