라즈베리파이반

라즈베리파이 등 컴퓨터계열 게시판입니다.

제목디자인 패턴(Design Pattern) : 전략 패턴 / 상태 패턴2022-07-08 22:00
작성자user icon Level 4

88x31.png


1. 전략 패턴(Strategy Pattern)


전략 패턴은 동일 패턴의 알고리즘에 대하여 하나의 접근을 만들어서 상호 교환이 가능하도록 하는 패턴입니다.


지난번 플라이웨이트 패턴에서 이미 구현했던 패턴입니다. 무기라는 인터페이스를 통해 공격이라는 하나의 알고리즘을 통해 서로 다른 무기들의 공격 알고리즘을 실행시킬 수 있었습니다. 이번에는 자동차를 통해 전략 패턴 코드를 작성해보겠습니다.


qq9fdjbqAQCAAC4FCEQAADAhQiBAAAALkQIBAAAcCFCIAAAgAs9VukGPOoOHTokwzAq3Qy41KFDhyrdhA1xfqCSOD+A8g4dOsQQMQAAAG5EdzAAAIALEQIBAABc6P8BsNpRnjp3ss8AAAAASUVORK5CYII=


클래스 다이어그램입니다.


Vehicle.java:

wMLZu7m5latPgAAAABJRU5ErkJggg== 

 Vehicle은 탈것들의 인터페이스 입니다. run이라는 메소드의 접근점을 제공합니다.


Bus.java:

v7UOJiMg9RiMxERExrP8PA0wEXH2rK8MAAAAASUVORK5CYII= 


Taxi.java:

pUdOiYjIANH7xERExLCUThQREcNSEBMREcMK+JhYaGhooKsQEZGblHpiIiJiWIP22KnOzs7BqkpERG4S6hWPFcoAAAB6SURBVImJiIhhKYiJiIhhKYiJiIhhKYiJiIhhKYiJiIhhKYiJiIhhKYiJiIhhKYiJiIhhKYiJiIhhKYiJiIhhKYiJiIhhKYiJiIhhKYiJiIhhKYiJiIhhDdqrWPRyTBERGWjqiYmIiGEFvCeml2GKiEigqCcmIiKG9X8NayYLSHel0AAAAABJRU5ErkJggg== 


Motorcycle.java:

qiYmIiGkFvSeml2GKiEiwqCcmIiKm9f8Bwf1I6PLmUBwAAAAASUVORK5CYII= 


전략 객체 클래스 입니다. Vehicle 이라는 인터페이스를 상속받아 각각 run이라는 메소드를 구현했습니다.


Driver.java:

MK8OeWNERET6KvVwRUREwiDoRzu2t7eHsh0iIiJ92v8DQNXPNyDO9ycAAAAASUVORK5CYII= 


전략 객체들을 관리하는 컨텍스트(Context) 객체 클래스 입니다. 전략 객체 클래스와 집합(Agregation) 관계에 있으며, 여기서는 Vehicle을 상속받았습니다.


Main.java:

T76+KITooeR5lEIIoUGG3kIIoUECpRBCaJBAKYQQGiRQCiGEBgmUQgihQQKlEEJo+P9JXu4O5XvRcQAAAABJRU5ErkJggg== 

탈것없이 운전자 객체를 생성하여 run을 실행하고, 버스객체로 탈것을 전환한 뒤 다시 run을 실행하면 다음과 같이 출력됩니다.


 BRHq7Gm7Ojzr2nclI5+LdAnv6TeLKJsLkmHmpEuzDYeCBs+6LfW0T6QqCO+DV9bsFVrFGUGbMSGnh0j2uiWun3ufYhgb9NUrF9zSRXi+4LLtAbEvrpl59MSfCLR5Tj0s2Zi9gsKT4xibSG9Vw1zl9K25dZP8U1jWR3tHG71Ls+3CD9vNJLPXRZJu2a8cfjkUp9RtABkzCKWRPIpxCgiOcQoIjnEKCI5xCgiOcQoIjnEKCI5xCgiOcQoIjnEKCI5zyD+1cwJipS43DAAAAAElFTkSuQmCC



2. 상태 패턴(State Pattern)


상태 패턴은 객체의 내부 상태에 따라 행위를 변경해주는 패턴입니다. 전략 패턴과 유사해 보이지만 전략 패턴에서 클라이언트가 상태를 설정해주는 것과 달리 상태 패턴은 내부에서 자체적으로 상태를 변경합니다.


컴퓨터 전원 스위치를 예로 들어 코드를 작성해 보겠습니다.


qS0oDZe0UF8AAAAASUVORK5CYII=


클래스 다이어그램입니다. 전략패턴과 유사해보입니다.


State.java:

A5MJLps9NhclAAAAAElFTkSuQmCC 

상태 객체 클래스의 인터페이스 입니다. 토글 메소드를 정의합니다. 컨텍스트(Context) 객체인 Switch를 매개변수로 받습니다.


On.java:

nVF5Kkj13unAYDAMgcK3YAsJiEtxTY2trKVRwAgCxhxQ4AFkNiBwCLIbEDgMX8BzOGwcfRkPRdAAAAAElFTkSuQmCC 


Off.java:

uvPFAGcAAAAAElFTkSuQmCC 


상태 객체 클래스 입니다. on 상태에서는 toggle 메소드가 실행되면 컴퓨터가 꺼지고, off 상태에서는 컴퓨터가 켜집니다. 각각의 상태를 싱글톤으로 작성했습니다.


Switch.java:

AUrSh8KOnpoMAAAAAElFTkSuQmCC 

컨텍스트(Context) 객체 클래스인 스위치 입니다. 초기 상태는 off상태입니다.


Main.java:

8Bw0MReTytgy4AAAAASUVORK5CYII= 


컴퓨터 스위치를 3번 토글한다면 다음과 같은 출력을 얻을 수 있습니다.

onKGRa57QyEVIAW0VxAoKh1hB4RAraOSaJFveyNVV6tsauXgjVzs0cg1nyhu5WqCRyyZX3shFI9cgvJGrFRq5eCOXFTRymcAbuc7QyDUS3shVh0auIXgjVys0cg3AG7namacfZ0ZGLt7I1c48hUOeDI1c84RGLkIKaKsgVlA4xAoKh1hB4RArKBxiBYVDrKBwiBUUDrGCwiFWUDjECgqHWPEfDGTY0rsb9bUAAAAASUVORK5CYII= 


물론 enum을 통해서 다음과 같이 상태를 관리할 수도 있습니다.

SKvxF1EAAAAASUVORK5CYII= 


그러나 이러한 코딩은 상태가 많아질수록 복잡해지며, 컨텍스트 객체 하나에서 모든 책임을 맡고 있습니다. 또한 상태가 추가될 때마다 코드를 수정해야만 합니다. 상태 패턴으로 작성한다면 책임을 각 상태 클래스에 위임할 수 있으며 코드도 간결해집니다. 


최대절전모드를 추가해보겠습니다.


Switch.java:

knRERERkMGrmJiEjYCfjyW93d3UPZDxERkUGjkZuIiIQdBTcREQk7Cm4iIhJ2FNxERCTsKLiJiEjYUXATEZGwo+AmIiJhR8FNRETCjoKbiIiEnf8fXaOTVmCq0zwAAAAASUVORK5CYII= 

longPush 메소드를 추가했습니다. on 상태에서만 동작하며, 강제 형변환을 통해 on 객체의 longPush 메소드를 실행합니다.


On.java:

2wSHXGBrTGsAAAAAElFTkSuQmCC 


longPush 메소드가 실행되면 컴퓨터가 꺼지고, toggle 메소드가 실행되면 최대절전모드가 됩니다.


Hibernate.java:

TIjG3Eag8fwAAAAASUVORK5CYII= 

최대절전모드 상태 클래스 입니다. 토글시 컴퓨터가 켜집니다.


Main.java:

HwDJWtqUhJpkAAAAAElFTkSuQmCC 


다음과 같이 컴퓨터를 켜고, 최대절전모드로 전환하고, 다시 컴퓨터를 켜고, 컴퓨터를 끌 수 있습니다.


Zfu4zNgoTCS0FC4SudmS+Q82ZiEgovwuP1mA4JhVtlXhQ4n1EGCYUX4fGG6SjpXe9XuAwJhZsfkFAYIKHwBEgoTDgJyd4IJyHDJJyEDJNwEjJMwknIMAknIcMknIQMk3ASMkzCSf4HWqy7ot2WDKAAAAAASUVORK5CYII= 

#디자인 패턴# 전략 패턴# 상태 패턴
댓글
자동등록방지
(자동등록방지 숫자를 입력해 주세요)