HaPpY hApPy

Strategy Pattern 스트레트지 패턴 본문

DesignPattern (디자인패턴)/Head First Design Pattern

Strategy Pattern 스트레트지 패턴

juniguya 2013. 7. 26. 10:01

디자인 패턴을 공부하면서 그냥 이해만 하고 넘어가는것보다,


한번쯤 작성해 봐야할꺼 같아서 마침 Head First Design Pattern 책에는 자바로 설명이 나와있어서


간단하게 C#으로 변경했다.


StrategyPattern.zip


Visual Studio 2010 버전으로 작성했다.


간단하게 이해한 내용은


IFlyBehavior인터페이스
interface IFlyBehavior
{
      void Fly();
 }
IQuackBehavior인터페이스
interface IQuackBehavior
{
    void Quack();
}
IFlyBehavior를 상속받는 클래스들
class FlyNoWay : IFlyBehavior
    {
        public void Fly()
        {
            Console.WriteLine("I can't Fly!!! T_T");
        }
    }
 
class FlyWithWings : IFlyBehavior
    {
        public void Fly()
        {
            Console.WriteLine("I can Fly");
        }
    }
IQuackBehavior를 상속받는 클래스들
class MuteQuack : IQuackBehavior
    {
        public void Quack()
        {
            Console.WriteLine("........");
        }
    }

class QuackDuck : IQuackBehavior
    {
        public void Quack()
        {
            Console.WriteLine("Quack!()");
        }
    }
덕 클래스
class Duck
    {
        IFlyBehavior flyBehavior; // A에는 B가 있다 관계 (Duck 에는 IFlyBehavior가 있다)
        IQuackBehavior quackBehavior; // A에는 B가 있다 관계 (Duck 에는 IQuackBehavior가 있다)
        //여기서 A is B 관계가 아니라 Has 관계가 된것은
       //IFlyBehavior 와, IQuackBehavior 행동이 언제든지 변할수 있기 때문이다.

        public void PerformFly()
        {
            flyBehavior.Fly();
        }

        public void PerformQuack()
        {
            quackBehavior.Quack();
        }

        public void WhatKindOfDuckAreYou()
        {
            PerformFly();
            PerformQuack();
        }

        public void setFlyBehavior(IFlyBehavior fb)
        {
            flyBehavior = fb;
        }

        public void setQuackBehavior(IQuackBehavior qb)
        {
            quackBehavior = qb;
        }
    }
마지막으로 메인
    
class Program
    {
        static void Main(string[] args)
        {
            Duck duck = new Duck();  //오리 객체 하나 생성
            duck.setFlyBehavior(new FlyWithWings()); //이 오리는 첨에 건강해서 날수도
            duck.setQuackBehavior(new QuackDuck()); // 소리 지를수도 있다.
            duck.WhatKindOfDuckAreYou(); //오리야 넌 어떤 오린지 보여줘!
            
            Console.WriteLine("날개를 다친후"); //그러다가 날개를 다친다
            
            duck.setFlyBehavior(new FlyNoWay());//날개를 다침
            duck.WhatKindOfDuckAreYou(); //오리야 넌 어떤 오린지 보여줘!

            Console.WriteLine("날개 다치고 하도 투덜 투덜하다가 목소리를 잃은후"); //코딩할때 그만좀 투덜거리자, ㅎ

            duck.setQuackBehavior(new MuteQuack());//.... 투덜되다가 오리가 목소리도 잃음
            duck.WhatKindOfDuckAreYou(); //오리야 넌 어떤 오린지 보여줘!
        }
    }

출력 결과

I can Fly

Quack!()

날개를 다친후

I can't Fly!!! T_T

Quack!()

날개 다치고 하도 투덜 투덜하다가 목소리를 잃은후

I can't Fly!!! T_T

........

Press any key to continue . . .


이 패턴을 이용하면 게임에서 특정 케릭터가 검을 가지고 사냥을 하다가,

Knight handsomeKnight = new Knight();

handsomeKnight.setWeapon(new Gun()); 총을 무기로 사용하다가

총알이 오링나서

handsomeKnight.setWeapon(new Sword()); 검으로 바꾸는 코딩이 아주 편하게 가능하다.


그리고 기사가 배가 고파서 사냥터에서 숫컷 오리를 발견해서 암컷 오리 소리도 흉내내서 사냥할수있다.

handsomeKnight.setQuackBehavior(new QuackDuck()); //이제 이 기사는 오리 소리도 낸다.

handsomeKnight.PerformQuack(); 하면 오리 소리를 내서 숫컷 오리를 유인한다.

잡아 먹고 오리발 내밀고 도망가기 위해서

handsomeKnight.setFlyBehavior(new FlyWithWings()); 하고 나는 기능도 가져서 날아서 도망가버릴수도있다.


물론 이 기사 클래스(그 클래스 말고 class,,,음,,여튼!)



class Knight
{
        IFlyBehavior flyBehavior; // Duck 클래스 처럼 이 두개의 인터페스를 Has 관계로 가져야된다.
        IQuackBehavior quackBehavior; 
        IWeapon weapon;  //무기도 사용하니깐
 }