4 분 소요

1. 디자인 패턴의 이해

디자인 패턴

GoF의 디자인 패턴

  • 소프트웨어 설계를 위한 지식이나 노하우를 공유할 방법 중 하나
  • 설계 중에서 재사용할 경우에 유용한 것을 디자인 패턴으로 정립
  • 소프트웨어 설계에 대한 지식이나 노하우가 문제 유형별로 잘 구체화되어 있음
  • 동일한 유형의 문제를 해결하는 방법에 대한 지식이나 노하우가 패턴 형태로 충분히 일반화
  • 쉽게 재사용할 수 있도록 객체지향 개념에 따른 설계만을 패턴으로 지정

2. 행위 패턴

행위 패턴

행위 패턴의 개요

  • 반복적으로 사용되는 객체의 상호작용을 패턴화한 것
  • 클래스나 객체가 상호작용하는 방법과 책임을 분산하는 방법을 정의
  • 메시지 교환과 관련된 것으로 객체 간의 행위나 알고리즘 등과 관련된 패턴

행위 패턴의 종류

  • strategy 패턴
  • template method 패턴
  • iterator 패턴
  • visitor 패턴
  • mediator 패턴
  • chain of responsibility 패턴
  • state 패턴
  • interpreter 패턴
  • observer 패턴
  • command 패턴
  • memento 패턴

strategy 패턴

자주 바뀌는 것이 기능이라면?

메서드를 클래스로 바꾸고 <<interface>> 타입의 상속 구조를 만들어라

예제 프로젝트 이해(포켓몬 예시)

  • 이 프로젝트의 특성은 포켓몬의 종류가 자주 추가되고 삭제된다는 점
  • 기술이 발전함에 따라 성능 개선을 위해 기능(공격, 패시브)이 수정되기도 하고 새로운 공격 기술이 추가

sw_8_1

일반적인 클래스 설계
  • 모든 포켓몬이 공통으로 가지는 공격/패시브 기술은 상위 클래스의 attack()과 passive() 메서드로 놓고 하위 클래스에서 상속

sw_8_2

sw_8_3

문제: 기능 변화

문제점
  • 기술이 발전함에 따라 공격과 패시브 기술이 계속 교체되지만 이에 대한 해결책이 없음
  • 클래스 설계 원칙 중 OCP(개방 폐쇄 원칙)를 위반하는 것일 뿐 아니라 프로그램을 복잡하게 만듬
해결책
  • 자주 바뀌는 것이 무엇인지 찾아 그들을 별도의 상속 구조로 만들어 사용
  • 자주 바뀌는 것이 attack(), passive()이기 때문에 이들을 클래스로 만들고 상속 구조로 설계
  • 추가되는 공격 기술을 하위 클래스에 계속 추가할 수 있음

strategy 패턴을 적용한 클래스 설계

sw_8_4

  • 포켓몬의 종류를 계속 추가/삭제할 수 있도록 Pokemon 클래스를 상위 클래스, 포켓몬 종류를 하위 클래스로 배치한 상속 구조로 설계
  • Pokemon 클래스에서 메서드로 구현한 패시브Passive를 별도의 상속 구조로 만들어 사용

sw_8_5

state 패턴

State 패턴: 객체의 상태에 따라 객체의 행동을 변경할 수 있는 패턴으로, 상태를 객 체화하여 관리합니다. 상태 전환 과정과 실제 적용 사례를 공부해야 합니다.

자주 바뀌는 것이 상태라면?
상태를 클래스로 바꾸고 <<interface>> 타입의 상속 구조를 만들어라

예제 프로젝트 이해

  • 처음의 선풍기는 정지와 송풍 기능만 있는 것
  • 정지 상태에서 ON 버튼을 누르면 송풍 상태로 변하고 송풍 상태에서 OFF 버튼을 누르면 정지 상태로 변한
  • 선풍기의 바람 상태에 Sleep, 약풍, 중간풍, 강풍이 계속 추가될 것

sw_8_6

문제: 상태 변화

문제점

  • ElecFan 클래스에서는 조건문(if ~ else if)을 사용했는데 이 코드만으로는 상태의 변화를 쉽게 읽을 수 없음
  • 상태(추가, 삭제)가 바뀌면 on_button(), off_button() 메서드에 이를 반영해야 하므로 계속해서 코드 수정이 필요
  • 클래스 설계 원칙 중 OCP(개방 폐쇄 원칙)를 위반하는 것일 뿐 아니라 프로그램을 복잡하게 만들어 유지보수를 어렵게 함

-> 클래스를 상속구조로 만든다. 필요할 때 마다 호출하게 끔 한다.

해결책

  • 자주 바뀌는 것이 상태(송풍, 정지, 수면, 약풍, 중간풍, 강풍 등)이므로 조건문으로 처리하던 상태를 클래스로 변경
  • 클래스를 상속 구조(인터페이스 포함) 형태로 만들어 하위 클래스에서 상태를 추가 및 삭제할 수 있도록 만듬

sw_8_7

state 패턴 정리

  • state 패턴은 자주 바뀌는 상태를 클래스로 만들고 이를 <<interface>> 타입의 상속 구조로 만듬
  • 상태의 변경이 그 안에서만 이루어지게 하여 주 클래스에 미치는 영향을 최소화하도록 설계한 패턴\

sw_8_8

3. 구조 패턴

구조 패턴

구조 패턴의 개요

  • 프로그램 내의 데이터나 인터페이스의 구조를 설계하는 데 많이 활용할 수 있음
  • 클래스나 객체의 구성(합성)으로 더 큰 구조를 만들어야 할 때 유용한 디자인 패턴

구조 패턴의 종류

  • decorator 패턴
  • adapter 패턴
  • composite 패턴
  • bridge 패턴
  • facade 패턴
  • flyweight 패턴
  • proxy 패턴

decorator 패턴

기본 클래스를 조합해서 많은 클래스를 만들어야 한다면?
많은 클래스를 조용히 처리하라!

decorator 패턴의 개요

  • 너무 많아질 수 있는 장식을 ‘조용히(?) 어떻게 처리하는가’를 설명하는 디자인 패턴
  • decorator 패턴은 장식이 주인공으로 여기서의 주인공은 꼭 있어야만 하는 존재가 아니고 장식처럼 없어도 되는 존재

예제 프로젝트 이해

  • 토스트를 판매할 때 칼로리를 계산해 알려주는 토스트 가게가 있음
  • 현재 판매하는 메뉴는 치즈 토스트, 야채 토스트, 햄 토스트로 3종류
  • 앞으로 재료도 늘어날 것이고 재료를 혼합한 토스트 종류도 늘어날 예정
  • 기본 재료를 조합해 만드는 토스트의 종류를 하위 클래스로 계속 추가할 수 있는 상속 구조로 만든다면 기본 재료가 추가될 때마다 그것을 조합해 만들어지는 토스트의 종류 (클래스)는 수십 가지로 늘어날 것

decorator 패턴의 적용

  • Decorator 패턴을 적용하면 식빵은 상속 구조를 사용
  • 빵의 종류가 늘어나는 것에 대해서는 Toast라는 상위 클래스를 만들고 하위 클래스에 식빵의 종류를 둠
  • decorator 패턴은 재료를 기본 재료(햄, 치즈, 달걀, 야채)와 복합 재료로 나누는 것부터 시작
  • 핵심은 혼합 재료의 숫자만큼 클래스를 만들지 않고 기본 재료만 가지고 해결하는 것
  • 기본 재료는 하위 클래스에 놓고 상위 클래스에 ToppiongDecorator 라는 이름의 클래스를 만듬
  • 혼합 재료는 기본 재료를 계속 늘려 나가는 방식으로 프로그래밍
Tost toast1 = new NormalBread();  
tost1.addToping(new Chesse());    ➋ 
tost1.addToping(new Ham());       
tost1.serve();                    

➊   Toast 타입의 일반식빵인 toast1 객체를 생성 ➋   ‘치즈’를 인자로 갖는 addTopping()을 호출 ➌   ‘햄’을 인자로 갖는 addTopping()을 호출 ➍   server()를 호출해 지금까지 name에 들어간 이름과 누적된 칼로리를 출력

sw_8_9

sw_8_10

sw_8_11

decorator 패턴 정리

  • 객체지향 방법에서는 객체를 안정적으로 추가/삭제할 수 있는 방법으로 상속을 많이 활용
  • 상속 구조는 상위 클래스와 하위 클래스 간에 강한 결합으로 묶이게 되고 객체를 동적으로 확장할 때는 구현하기 쉽지 않음
  • 구성(합성)은 객체를 실행하는 도중에 동적으로 확장한다는 장점

adapter 패턴

구매한 컴포넌트가 맞지 않아 바로 사용할 수 없다면?
apdapter를 만들어 사용하라!

adapter 패턴의 개요

  • adapter의 의미: ‘접속 소켓’, ‘확장 카드’, ‘(물건을 다른 것에) 맞추어 붙이다’, ‘맞추다’
  • 호환되지 않는 두 인터페이스를 작동시킬 수 있도록 만든 인터페이스
  • adapter 패턴은 다음 두 가지 형태로 사용
    • 클래스 adapter 패턴: 상속을 이용한 어댑터 패턴
    • 인스턴스 adapter 패턴: 위임을 이용한 어댑터 패턴

예제 프로젝트의 이해

  • 삼성 휴대전화에 무선 이어폰 Buds 대신 애플의 무선 이어폰 (Airpods)을 사용할 수 있도록 하는 것
  • 두 이어폰의 기능은 재생과 멈춤으로 한정
  • Buds는 재생 기능에 play(), 멈춤 기능에 stop() 메서드를 사용
  • Airpods은 재생 기능에 playing(), 멈춤 기능에 stopping() 메서드를 사용

adapter 패턴의 적용

  • <<<interface>> 타입의 AirPodsInterface 클래스를 정의하고 그 메서드는 Buds에서 사용하는 play(), stop() 메서드와 같게 함
  • 어댑터로 AirPodsAdapter 클래스를 만듬
  • AirPods 클래스로부터 상속을 받지만 AirPodsInterface 클래스로 인터페이스 구현으로 이루어졌기 때문에 자바에서 가능

sw_8_12

sw_8_13

댓글남기기