[Design Pattern] 2. μƒνƒœ νŒ¨ν„΄(state)

μ—…λ°μ΄νŠΈ:

μΉ΄ν…Œκ³ λ¦¬:

νƒœκ·Έ: ,




μƒνƒœ νŒ¨ν„΄(state)

μƒνƒœ(state)νŒ¨ν„΄






μƒνƒœνŒ¨ν„΄ (state)

image

  • 객체의 μƒνƒœμ— 따라 객체의 행동을 λ³€κ²½ ν•΄μ£ΌλŠ” λ””μžμΈ νŒ¨ν„΄
  • 캐릭터 μƒνƒœκ°€ λŠμž„μ—†μ΄ μ „ν™˜ 객체가 λ‚΄λΆ€ μƒνƒœλ₯Ό 기반으둜 μ›€μ§μ΄λŠ” μ‹œμŠ€ν…œ
  • 쑰건문으둜 λ‚˜λˆ„λŠ” 것이 μ•„λ‹ˆλΌ 객체의 μƒνƒœλ₯Ό λ³„λ„μ˜ 클래슀둜 μΊ‘μŠν™”
  • κ²Œμž„ μΊλ¦­ν„°μ˜ μƒνƒœ(λŒ€κΈ°, 이동, 곡격)에 따라 행동이 λ‹¬λΌμ§€κ²Œ κ΅¬ν˜„
state μ½”λ“œλ³΄κΈ°
// μƒνƒœ μΈν„°νŽ˜μ΄μŠ€
public interface IState
{
    void HandleInput(Player player, string input);
    void Update(Player player);
}

// μƒνƒœμ— λ”°λ₯Έ ν΄λž˜μŠ€λ“€, λŒ€κΈ° μƒνƒœ 클래슀
public class StandingState : IState
{
    public void HandleInput(Player player, string input)
    {
        if (input == "SPACE") 
        {
            player.SetState(new JumpingState());
        }
    }

    public void Update(Player player)
    {
        // λŒ€κΈ° μƒνƒœμ—μ„œ ν•  행동
    }
}

// 점프 μƒνƒœ 클래슀
public class JumpingState : IState
{
    public void HandleInput(Player player, string input)
    {
        // 점프 μƒνƒœμ—μ„œμ˜ μž…λ ₯ 처리
    }

    public void Update(Player player)
    {
        // 점프 μƒνƒœμ—μ„œ ν•  행동
    }
}

// ν”Œλ ˆμ΄μ–΄ 클래슀
public class Player
{
    private IState currentState;

    public Player()
    {
        currentState = new StandingState();
    }

    public void SetState(IState newState)
    {
        currentState = newState;
    }

    public void HandleInput(string input)
    {
        currentState.HandleInput(this, input);
    }

    public void Update()
    {
        currentState.Update(this);
    }
}

// μƒνƒœ νŒ¨ν„΄ μ‚¬μš© μ˜ˆμ‹œ
Player player = new Player();
player.HandleInput("SPACE"); // 점프 μƒνƒœλ‘œ λ³€κ²½
player.Update(); // ν˜„μž¬ μƒνƒœ(점프)에 λ§žλŠ” 행동 μ‹€ν–‰

μΆ”κ°€

image

  • μƒνƒœλ₯Ό λΆˆλŸ¬λ‚΄λŠ” 호좜자 -> μΈν„°νŽ˜μ΄μŠ€ -> μƒνƒœABC
  • Context ν΄λž˜μŠ€λŠ” 객체의 λ‚΄λΆ€ μƒνƒœλ₯Ό λ³€κ²½ν•˜λ„λ‘ μš”μ²­ν•˜λŠ” 클래슀
  • IState μΈν„°νŽ˜μ΄μŠ€λŠ” ꡬ체적인 μƒνƒœ 클래슀둜 μ—°κ²°ν•  수 μžˆλ„λ‘ 섀정함
  • Context μ˜€λΈŒμ νŠΈκ°€ Istate μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•œ ν΄λž˜μŠ€λ“€μ„ ν˜ΈμΆœν•¨

μž₯점
Β Β 1. μΊ‘μŠν™”
Β Β 2. κΈ΄ 쑰건문, λ°©λŒ€ν•œ 클래슀 κ΅¬ν˜„ν•˜λŠ” 것을 λ§‰μŒ

단점
Β Β 1. λ§Œμ•½ μƒνƒœκ°€ μ „ν™˜λ˜λŠ” μ‚¬μ΄μ—μ„œ λ°œμƒν•˜λŠ”κ±΄ λ”°λ‘œ κ΅¬ν˜„μ„ 해야함.

μ½”λ“œ
CharaccterStateContext, ICharacterState, CharacterController, CharacterStartState

state μ˜ˆμ‹œ
CharaccterStateContext  
public class CharaccterStateContext
    {
        public ICharacterState CurrentState
        {
            get; set;
        }
        
        private readonly CharacterController _characterController;

        public CharacterStateContext(CharacterController characterController)
        {
            _characterController = characterController;
        }

        public void Transition()
        {
            CurrentState.Handle(_characterController);
        }
        
        public void Transition(ICharacterState state)
        {
            CurrentState = state;
            CurrentState.Handle(_characterController);
        }
    }

ICharacterState
public interface ICharacterState
{
    void Handle(CharacterController controller);
}

using UnityEngine;

CharacterController
public class CharacterController : MonoBehaviour {
            
    private ICharacterState 
        _startState, _stopState, _turnState;
    
    private CharacterStateContext _characterStateContext;

    private void Start() {
        _chracterStateContext = 
            new CharacterStateContext(this);
        
        _startState = 
            gameObject.AddComponent<CharacterStartState>();
        _stopState = 
            gameObject.AddComponent<CharacterStopState>();
        _turnState = 
            gameObject.AddComponent<CharacterTurnState>();
        
        _characterStateContext.Transition(_stopState);
    }

    public void StartCharacter() {
        _characterStateContext.Transition(_startState);
    }

    public void StopCharacter() {
        _chracterStateContext.Transition(_stopState);
    }
}

CharacterStartState
 public class CharacterStartState : MonoBehaviour, ICharacterState
{
    private CharacterController _characterController; 
    
    public void Handle(CharacterController characterController)
    {
        if (!_characterController)
            _characterController = characterController;
        
        _characterController.CurrentSpeed = 10.0f;
    }
}







μž‘λ‹΄, 정리

  • λ””μžμΈ νŒ¨ν„΄μ€ μ• μ΄ˆμ— νŠΉμ • 문제λ₯Ό ν•΄κ²°ν•˜κΈ° μœ„ν•΄ 고렀된 것.(μ„±λŠ₯, λ©”λͺ¨λ¦¬ μ‚¬μš© κ³ λ €)




[C#] λ””μžμΈ νŒ¨ν„΄ (Design Pattern)
TOP


πŸ“”

λŒ“κΈ€λ‚¨κΈ°κΈ°