State Pattern(상태 패턴)?
상태변화를 가지는 주요 객체를 다룰 때 유용하게 적용해 볼 수 있는 패턴이다.
의도
객체의 내부 상태에 따라 스스로 행동을 변경할 수 있게 허가하는 패턴으로 이렇게 하면 개체는 마치 자신의 클래스를 바꾸는 것처럼 보인다.
서브클래스들이 상속 받을 State를 다음과 같이 만든다.
모두 가상 메서드로 이루어지고 각 가상 메서드는 에러처리만 하도록 만든다. 후손개체의 메서드가 사용되지 않고, 조상 개체의 메서드가 사용되면 자동으로 에러가 나도록 만든다.
State.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text;
namespace StatePattern { class State { public virtual bool Attack(Character character) { Console.WriteLine("공격 오류!"); return false; } public virtual bool Move(Character character) { Console.WriteLine("이동 오류 !"); return false; } public virtual bool Lucky(Character character) { Console.WriteLine("행운 오류!"); return false; } public virtual void CountDown(Character character) { } } }
|
싱글톤패턴 적용하여 시스템에 하나의 개체만 존재하도록 하였고, 생성자 캐릭터 개체를 입력 받도록 만들어주어, 나중에 상태개체를 변경해야 할 때 사용한다.
Normal.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text;
namespace StatePattern { class Normal : State { private static Normal this_object; public static Normal get_object { get { if (this_object == null) { this_object = new Normal(); } return this_object; } } public override bool Attack(Character character) { Console.WriteLine("100% 공격력!!"); character.Hp -= 40; if (character.Hp < 30) { character.chageState(Emergency.get_object); } return true; } public override bool Move(Character character) { Console.WriteLine("100% 이동!!"); //character.chageState(Superman.get_object); return true; }
} }
|
Emergency.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text;
namespace StatePattern { class Emergency : State { Random rand = new Random(); private static Emergency this_object; public static Emergency get_object { get { if (this_object == null) { this_object = new Emergency(); } return this_object; } } public override bool Attack(Character character) { int luck=0; Console.WriteLine("공격 75 %!!"); luck = rand.Next(3); if (luck == 2) { character.chageState(Immortal.get_object); Immortal.before_state = this; } return true; } public override bool Move(Character character) { Console.WriteLine("이동 50%!!"); return true; } public override bool Lucky(Character character) { Console.WriteLine("행운 15!"); return true; } } }
|
※ 캐릭터를 담당 하게 될 Character 클래스를 보도록 하자. Character Class 내부에 State 개체를 가지게 되는데, 이 개체는 수시로 각 상태를 담당하는 개체로 형 변환을 하게 된다.
Character.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text;
namespace StatePattern { class Character { int hp; private State state; public Character() { hp = 100; chageState(Normal.get_object); } public int Hp { get { return hp; } set { hp = value; } } public void chageState(State state) { this.state = state; } public void Move() { state.Move(this); } public void Attack() { state.Attack(this); } public void Lucky() { state.Lucky(this); } public void CountDown() { state.CountDown(this); } public void SuperItem() { chageState(Superman.get_object); } } }
|
마지막으로 파일관리 개체를 활용하는 모듈을 작성한다. 이때 모듈은 파일관리 개체의 상태에 전혀 신경을 쓰지 않아도 된다. 그냥 메서드를 호출하여 사용하기만 하면 된다.
using System; using System.Collections.Generic; using System.Linq; using System.Text;
namespace StatePattern { class Program { static void Main(string[] args) { Character c = new Character();
c.Attack(); c.Attack(); c.Attack(); c.Move();
c.Attack(); c.Attack(); c.Attack(); c.Attack(); c.Attack(); c.SuperItem(); c.Attack(); c.Attack(); } } }
|
'Programing > Design Pattern' 카테고리의 다른 글
State Pattern (상태패턴) (0) | 2016.11.30 |
---|---|
템플릿 메서드 (0) | 2016.11.30 |
전략패턴,Strategy patterns (0) | 2016.11.30 |