디자인패턴 기말고사 필기
포스트
취소

디자인패턴 기말고사 필기

패턴 내 클래스의 역할

mediator

  • 중재자 클래스: 컴포넌트 간 통신을 조정하기 위한 인터페이스
  • 구체 중재자 클래스: 중재자 인터페이스를 구현, 실제 통신 조정을 수행
  • 동료 클래스: 중재자와 통신할 인터페이스
  • 구체 동료 클래스: 동료 인터페이스 구현

observer

  • 관찰 대상: 관찰 대상을 관리하는 인터페이스
  • 구체 관찰 대상: 상태가 변하면 관찰자에게 통보.
  • 관찰자: 관찰 대상으로부터 상태 변화를 통보받음.
  • 구체 관찰자: 관찰 대상으로부터 상태 변화를 통보받으면 관찰 대상의 현재 상태를 확인하고 적절한 동작을 수행함.

state

  • 상태: 상태를 나타냄. 각 상태에 따른 행동을 하는 통일된 인터페이스를 정함.
  • 구체 상태: 구체적인 각각의 상태를 표현. 상태 인터페이스 구현.
  • 상황/문맥: 현재 상태를 나타내는 구체 상태 클래스를 갖고 있음(집합 관계).

flyweight

  • 플라이: 평소대로 취급하면 프로그램이 무거워져 공유하는게 훨씬 좋은 역할
  • 플라이 공장: 플라이 역할을 만드는 공장의 역할. 일단 만들면 인스턴스를 공유한다.
  • 클라이언트: 플라이 공장으로 플라이를 만들어서 사용함.

command

  • 커맨드: 실행될 기능에 대한 인터페이스. 실행될 기능을 execute 메서드로 선언함. 구체 커맨드가 반드시 구현해야 하는 계약서 역할.
  • 구체 커맨드: 실제로 실행되는 기능을 구현.
  • 인보커/호출자: 기능의 실행을 요청하는 호출자 클래스. 커맨드의 레퍼런스를 갖고 있음.
  • 리시버: 구체 커맨드에서 execute 메서드를 구현할 때 필요한 클래스, 구체 커맨드의 기능을 실행하기 위해 사용하는 수신자 클래스

decorator

  • 컴포넌트: 기능을 추가할 때 핵심이 되는 역할. 장식의 밑바탕이 됨.
  • 구체 컴포넌트: 컴포넌트 클래스 구현
  • 장식자: 컴포넌트와 동일한 인터페이스를 가짐. 장식자이면서 장식 대상이 됨.
  • 구체 장식자: 구체적인 장식자.

chain of responsibility

  • 핸들러/처리자: 요구를 처리하는 클래스들의 인터페이스(API)를 정하는 역할
  • 구체 핸들러: 요구를 처리하는 구체적인 역할
  • 클라이언트: 구체 핸들러에게 요구하는 역할

proxy

  • 주체: 프록시와 구체 주체를 동일시하기 위한 인터페이스(API)를 정한다.
  • 구체 주체: 주체를 상속 구현함. 생성이 오래 걸리거나 접근 권한을 제한해야 하는 클래스.
  • 프록시: 주체를 상속 구현하며 클라이언트의 요구를 최대한 직접 처리함. 혼자 처리할 수 없을 때 그제서야 구체 주체 생성하여 위임.
  • 클라이언트: 사용자

facade

  • 파사드/정면: 시스템을 구성하고 있는 그 밖의 많은 역할에 대한 ‘단순한 창구’. 높은 레벨에서 단순한 인터페이스(API)를 시스템 외부에 제공. 복잡한 서브 클래스들에 대한 인스턴스 포함
  • 시스템을 구성하는 다수의 클래스: 각각의 임무를 실행하지만 Facade 역할에 대해서는 신경쓰지 않음. 파사드 클래스에서 호출되는 임무를 실행하지만, 다른 클래스가 파사드 클래스를 호출하는 일은 없다.
  • 클라이언트: 파사드 사용자

패턴을 적용했을 때의 장단점

mediator

  1. 중재자가 복잡하게 얽혀 있는 객체들 간의 상호 통신을 중재시키고, 객체들 간의 상호 작용 로직을 Mediator 에 집중시킴으로써 처리를 원할하게 한다. GUI에 효과적.
  2. 중재자의 재사용이 어려움. 동료 클래스는 재사용 가능.

state

  1. 새로운 상태를 추가하는 것은 간단
  2. 상태 머신에 몇 가지 상태만 있거나 머신이 거의 변경되지 않을 때상태 패턴을 적용하는 것은 추천되지 않음

command

  1. 시스템이 확장성이 있으면서 유연성을 가짐. 인보커와 리시버, 커맨드가 각각 캡슐화 되어서 결합도가 낮아진다.
  2. 리시버 객체의 동작이 늘어날 때마다 커맨드 클래스가 늘어나기 때문에 클래스가 많아진다.

decorator

  1. 내용물을 변경하지 않고, 기능을 추가할 수 있다. 단순한 장식으로도 다양한 기능을 추가할 수 있다.
  2. 작은 클래스가 증가함. 유사한 작은 클래스들이 많아진다.

chain of responsibility

  1. 요구하는 사람과 요구를 처리하는 사람을 느슨하게 연결. 이 패턴을 사용하지 않으면, “이 요구는 이 처리자가 처리해야 한다”라는 지식을 누군가 중앙 집중적으로 가지고 있어야 한다. 동적으로 연쇄의 형태를 바꿀 수 있다. 자신의 일에 집중할 수 있다.
  2. 유연성은 높지만, 처리 속도는 느리다. 요구와 처리자의 관계가 고정적이고, 처리의 속도가 중요한 경우에는 이 패턴을 사용하지 않는 편이 유효할 수도 있다.

proxy

  1. 초기화에 시간이 많이 걸리는 대규모 시스템에서 유용하다. 사이즈가 큰 객체가 로딩되기 전에도 프록시를 통해 참조 가능. 실제 객체의 public, protected 메소드를 숨기고 인터페이스를 통해 노출 가능. 로컬에 있지 않고 떨어져있는 객체를 사용 가능. 원래 객체에 접근에 대한 사전처리 가능
  2. 객체를 생성할 때 한 단계를 거치게 되므로, 빈번한 객체 생성이 필요한 경우 성능 저하 가능. 프록시 내부에서 객체 생성을 위해 스레드가 생성, 동기화가 구현되어야 하는 경우 성능 저하 가능. 로직이 난해해져 가독성이 떨어질 수 있음.

facade

  1. 복잡한 하위 시스템에서 코드를 별도로 분리할 수 있다.
  2. 파사드는 앱의 모든 클래스에 결합된 전지전능한 객체가 될수 있다.

패턴을 적용할만한 상황, 패턴을 사용하면 좋은 경우

mediator

  • 복잡하고 다양한 양식 컨트롤로 구성된 대화 상자. 요소 중 일부는 다른 요소와 상호작용 (관계 형성), 코드 재사용 어려움 (얽힌 상호작용에 따라 클래스 종속성 발생)

observer

  • 특정 사건에 대해 알림을 받고 싶은 고객과 모든 사건에 대해 알림을 보내고 싶은 쇼핑몰의 이해관계 충돌 문제
  • MVC 모델

state

  • 상태 머신의 경우 보통 많은 조건문으로 구현되는 문제점이 발생
  • 스마트폰 버튼의 상태에 따른 행동 변화

flyweight

  • 총을 쏘는 간단한 게임을 개발할 때의 문제. 사격 및 폭발로 인한 총알, 미사일, 파편을 객체로 구현, 몇 분이 지나지 않아 게임은 crash가 나서 종료됨. 많은 데이터를 포함하는 별도의 객체가 문제
  • RAM의 사용을 줄이는 최적화 아이디어. 인스턴스를 가능한 한 공유시켜서, 쓸데없이 new를 하지 않도록 함. 인스턴스가 필요할 때 마다 new를 하는 것이 아니라, 이미 만들어져 있는 인스턴스를 이용할 수 있으면 공유
  • 텍스트 에디터 프로그램: 각 문자의 위치, 폰트, 크기, 색상 등을 지정할 수 있음. 메모리 용량 사용 최적화를 위해 Flyweight 패턴을 적용함.

command

  • 객체 A에서 객체 B의 메소드를 실행하려면 객체 B를 참조하고 있어야 하는 의존성이 발생
  • 텍스트 편집기의 도구 모음(툴바)을 만들기. 일반 버튼에 사용할 Button 클래스, 다양한 버튼은 다 다른 기능을 수행해야 함. 자식 클래스를 만들어 버튼 클릭 시 실행되어야 하는 코드 포함시킴. 엄청난 수의 자식 클래스 생성으로 인한 Button 클래스 의존성 증가, 일부 작업의 경우 여러 위치에서 호출될 가능성도 있음. 중복된 코드 사용, 버튼에 의존하는 메뉴 등 문제 발생.
  • 레스토랑 주문: 고객은 주문만 하면 되지 음식이 어떻게 만들어지는지는 관심 없음.
  • 버튼 하나로 음악플레이어의 음악 재생과 전원을 처리하기
  • 작업들로 객체를 매개변수화하려는 경우 사용, 특정 메서드 호출을 독립실행형 객체로 전환 가능
  • 되돌릴 수 있는 작업을 구현하려고 할 때 사용, 두 가지 단점: 첫째, 앱 일부가 비공개일 수 있으므로 앱의 상태를 저장하는 것이 쉽지 않음. 둘째, 상태 백업들은 상당히 많은 RAM을 소모할 수 있음.

decorator

  • 간단한 이메일 알림 시스템을 만드는 과정, Notifier 클래스 기반(단일 send 메소드). 이메일 이외의 알림을 추가하고 싶어 추가 자식 클래스를 생성. 복합적으로 알림을 구현하고 싶을 경우 너무 많은 자식 클래스 조합 발생.
  • 도로 표시 방법 조합하기: 내비게이션 SW에서 도로를 표시하는 기능
  • java.io 패키지와 Decorator 패턴

chain of responsibility

  • 온라인 주문 시스템. 일련의 인증 과정을 거쳐 검증된 사용자만 기능에 접근할 수 있도록 해야 함. 인증 과정은 순서대로 진행되어야 함. 이 상황에서 새 기능을 추가할 때마다 코드는 길고 복잡해진다. -> 특정 행동들을 핸들러라는 독립 실행형 객체들로 변환, 핸들러들을 체인으로 연결하도록 제안. 하나의 핸들러가 주문 처리를 수행한 다음 요청을 체인 아래로 더전달할지를 결정.

proxy

  • HTTP 프록시: HTTP 서버(웹 서버)와 HTTP 클라이언트(웹 브라우저) 사이에 들어가, 웹 페이지의 캐싱 등을 실행하는 소프트웨어. 웹 브라우저가 웹 페이지를 표시할 때, 일일이 원격지에 있는 웹서버로부터 페이지를 얻어오는 것이 아니다. 대신에, HTTP 프록시가 캐쉬한 페이지를 얻어온다. 최신 정보가 필요하게 되었거나, 페이지의 유효기간이 다 되었을 때에 비로소 웹 서버로 웹 페이지를 가지러 간다.

facade

  • 많은 저레벨 객체를 모두 제어해야 하는 상황. 많은 객체에 의존성을 갖게 되기 때문에 문제 발생. -> 저수준 객체를 깔끔하게 감싼 고수준 객체를 만들면 된다
  • 전화로 주문하기 위해 매장에 전화를 걸었을 때 전화를 받는 교환원. 주문 시스템, 지불 게이트웨이 및 다양한 배송 서비스에 대한 간단한 음성 인터페이스 제공
  • 영화를 볼 때, 복잡한 서브 클래스 없이 해결하기
  • 복잡한 하위 시스템에 대한 제한적이지만 간단한 인터페이스가 필요할 때 사용한다.
  • 하위 시스템을 계층들로 구성하려는 경우 사용한다. (mediator pattern)

추가 참고 사항

mediator

  • 로직이 중재자에게 집중됨.

observer

  • 관찰하는 게 아니라 통지를 받음.

state

  • 머신 클래스가 상태 클래스의 객체를 현재 상태로써 갖고, 현 상태에 따른 적절한 동작은 상태 클래스에 위임함.
  • divide and conquer. 개개의 구체적인 상태를 각각 클래스로 나누어서 표현함으로써 문제를 분할함.
  • STD(State Transition Diagram): 시스템의 상태 변화를 표현하기 위해 많이 사용되는 다이어그램

flyweight

  • Flyweight 패턴의 핵심은, 인스턴스를 ‘공유’하는 것이다. 반드시 공유해야 할 정보만 공유해야 한다.
  • instrinsic한 정보: 공유되어야 하는 정보, 상태에 의존하지 않는 정보
  • extrinsic한 정보: 공유시키지 말아야 할 정보, 상태에 따라 바뀌는 정보를 의미함
  • 관리되고 있는 인스턴스는 쓰레기수집(Garbage collection)이 되지 않는다.

command

  • 객체의 행위(메소드)를 클래스로 만들어 캡슐화
  • 관심사 분리의 원칙 기반 프로그래밍. 그래픽 인터페이스 레이어와 비즈니스 로직용 레이어의 분리. 그래픽 사용자 인터페이스 객체는 어떤 비즈니스 논리 객체가 요청을 받을지, 요청이 어떻게 처리될지 알 필요가 없어짐

decorator

  • 래퍼의 참조 필드가 해당 인터페이스를 따르는 모든 객체를 받도록 처리, 여러 래퍼로 객체를 포장해서 모든 래퍼들의 합성된 행동들을 객체에 추가 가능
  • 중심이 되는 객체에, 장식과 같은 부가적인 기능을 하나씩 입혀서좀 더 목적에 어울리는 객체를 만드는 패턴
  • 재귀적인 구조: 장식을 하는 주체와 장식되는 대상이 같을 수 있다.

chain of responsibility

  • 특정 문제 케이스에 대해 문제 해결 과정 시퀀스 다이어그램 그리기 문제 있음. 각 클래스 별 해결 가능한 문제를 정해주고, 클래스마다 문제를 몇 개나 해결할 수 있는지 / 몇 개나 처리하지 못했는지 개수를 세는 문제 있음(뒤에 있는 해결자는 앞에서 해결한 문제는 제외하고 세어야 한다) + 마지막까지 남은 문제를 모두 해결할 수 있는 논리 구조 작성하기 문제 낼 수 있음.

proxy

  • 실제 서비스와 같은 이름의 메서드 구현(인터페이스 사용), 실제 서비스에 대한 참조 변수를 가짐, 실제 서비스의 같은 이름을 가진 메서드를 호출하고 그 값을 클라이언트에게 반환, 실제 서비스의 메서드 호출 전후에도 별도의 로직을 수행 가능.
  • 세 가지 프록시 타입은 시험에 나온다. 예시 코드를 바꿔서 낼 것이니, 코드의 어느 부분에서 시간이 걸리는지 확인하고 어떤 유형의 프록시인지 파악하기.
    • 가상 프록시: 꼭 필요한 시점까지 객체 생성 연기. 작은 단위 작업은 프록시가 처리하고, 리소스가 많이 필요한 작업이 요구될 때에만 주체 클래스를 사용하게 함. 속도 향상 타입. 초기화하는데 시간이 많이 걸리는 대규모의 시스템에서 유용하다.
    • 원격 프록시: 원격 객체에 대한 접근을 제어(로컬 환경에 존재하며, 원격 객체에 대한 대변자 역할을 함). 구글 클라우드 서비스와 비슷함. 구글 독스처럼 서로 다른 주소 공간에 있는 객체에 대해 마치 같은 주소 공간에 있는 것처럼 동작하게 함. 멀리 떨어져 있어도 지금 같이 있는 것처럼
    • 보호 프록시: 주체 클래스에 대한 접근을 제어. 객체에 대한 접근 권한을 제어하거나 객체마다 접근 권한을 다르게 할 수 있음. 프록시가 클라이언트의 주체 클래스에 대한 접근을 허용할지 말지 결정. 귀한 곳에 누추하신 분이 오면 입장권 확인
이 기사는 저작권자의 CC BY-NC-ND 4.0 라이센스를 따릅니다.

[python] GUI 프로그램 exe 만들고 배포하기, 소멸자와 로깅

[python] 백준 8979 올림픽