안녕하세요. 도미닉입니다.
오늘은 스트래티지 패턴에 대해서 알아보겠습니다.
스트래티지 패턴이란?
자주 변경되는 부분을 인터페이스화하는 것입니다.
스트래티지 패턴이 필요한 이유?
예를 들어 Duck 이라는 클래스가 있습니다.
러버덕과 실제 오리가 Duck 클래스를 상속받습니다.
Duck 에 fly 라는 메서드를 추가하면 어떻게 될까요?
러버덕도 날 수 있습니다!!
현실은 러버덕은 날지 못합니다.
fly 라는 메서드를 오버라이드해서 아무 동작하지 않도록 수정해줘야 할 것입니다.
그렇다면 프로토콜로 채택해주면 어떨까요?
Duck 이라는 프로토콜이 있습니다.
러버덕 인형과 실제 오리는 모두 Duck 을 채택합니다.
이럴 때 러버덕 인형과 실제 오리 모두 각 fly 와 quack(오리 울음소리) 메서드를 구현해주어야 할 것입니다.
소스의 중복이 발생합니다.
또한 똑같은 동작을 하는 메서드들이 동일한 소스인지 확인해줘야 할 것입니다.
이럴 때 사용할 수 있는 것이 스트래티지 패턴입니다.
스트래티지 패턴 적용 방법
그렇다면 스트래티지 패턴은 어떻게 적용할 수 있을까요?
아래 예제를 먼저 보시겠습니다.
FlyBehavior 프로토콜과 QuackBehavior 프로토콜이 작성되었습니다.
이러한 프로토콜은 각 기능 fly 와 quack 메서드만이 선언되어 있습니다.
FlyWithWings 구조체와 FlyNoWay 구조체는 FlyBehavior 프로토콜을 채택했고 fly 라는 메서드가 각자의 동작대로 작성되어있습니다.
Quack 구조체와 Squeak 구조체와 MuteQuack 구조체는 QuackBehavior 프로토콜을 채택했고 quack 이라는 메서드가 각자의 동작대로 작성되어있습니다.
Duck 이라는 프로토콜은 오리가 가져야할 특성들을 정의합니다.
스트래티지 패턴 적용 전의 예제소스는 날 수 있고 울을 수 있기 때문에 fly 와 quack 이라는 메서드만 있었습니다.
이제 flyBehavior 와 quackBehavior 이라는 프로토콜 변수를 프로퍼티로 가집니다.
flyBehavior 에는 FlyBehavior 을 채택한 FlyWithWings 와 FlyNoWay 가 상황에 따라 들어갈 수 있을 것입니다.
quackBehavior 의 경우도 마찬가지입니다.
이렇게 구현함으로써 fly 와 quack 은 원하는 대로 동작을 작성해서 넣어줄 수 있을 것입니다.
하지만 이게 끝이 아닙니다.
이렇게 동적으로 작성해놓고 flyBehavior 와 quackBehavior 을 바꿀 수 없다면 의미가 없을 것입니다.
아래 예제 소스를 보시죠.
이제 setFlyBehavior 와 setQuackBehavior 메서드를 통해 MallarDuck 객체를 다시 선언하지 않고도 fly 와 quack 동작을 바꿀 수 있게 되었습니다.
이런 식으로 자주 변동되는 부분들을 프로토콜 변수로 선언하여 변경할 수 있도록 하는 것이 스트래티지 패턴입니다.
정리
오늘은 스트래티지 패턴에 대해서 알아봤습니다.
자주 변동되는 소스가 있다면 스트래티지 패턴을 통해 소스 수정을 줄일 수 있을 것입니다.
글 읽어주셔서 감사합니다.