// 유니티로 배우는 게임 디자인 패턴 제 2판 (데이비드 바론, 구진수) 에 대한 공부 노트입니다.
개요
데코레이터 패턴은 객체의 변경 없이 동적으로 기능을 추가할 수 있도록 하는 디자인 패턴이다. 이 패턴을 사용하면, 상속을 하지 않고도 새로운 기능을 객체에 추가하는 것이 가능하다.
데코레이터 패턴의 특징
데코레이터의 특징은 다음과 같다.
- 데코레이터 패턴은 상속이 아닌 Component를 통해서 기존 객체에 새로운 기능을 추가할 수 있다.
- 정적(static)이 아닌 런타임 시점에 동적으로 기능 추가가 가능하다.
- 여러 데코레이터를 중첩하여 사용할 수 있다.
데코레이터 패턴의 장단점
데코레이터 패턴의 장단점에 대해 살펴보자.
장점
- 유연성 : 런타임 도중 동적으로 기능을 추가하고, 데코레이터들을 중첩하여 사용이 가능하다.
- 단일 책임 원칙 : 각 데코레이터가 각 기능을 담당하고 있기 떄문에, 스크립트의 단일 책입 원칙을 지키고 코드의 책임을 분리할 수 있다.
- 서브클래싱의 대안 : 상속은 정적인 프로세스이기 때문에, 상속으로 기능을 추가하는 것의 단점을 극복할 수 있다. 서브클래싱의 동적인 대안이 된다.
단점
- 구현 복잡도, 코드 복잡성 증가 : 여러 데코레이터 클래스를 조합하면 코드가 복잡해진다. 초기화 체인과 데코레이터간의 관계를 추적하는 것이 어려워질 수 있다.
- 디버깅의 어려움 : 중첩된 데코레이터 사이에서 버그가 발견될 경우 디버깅하는 데에 어려움이 생긴다.
구현해보기
데코레이터 패턴을 사용해서 어떠한 기능을 개발하면서 직접 패턴을 사용해보자.
이번에 구현할 내용은 플레이어에게 어떠한 버프를 적용시키는 것이다.
플레이어에게 적용할 버프는 다음과 같다.
- 본래 공격에 화염 속성을 더하기
- 본대 공격에 냉기 속성을 더하기
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// Component interface
public interface ICharacter
{
public void Attack();
}
// Concrete Component
public class Character : MonoBehaviour, ICharacter
{
public float power = 10.0f;
public float speed = 5.0f;
private Rigidbody2D rb;
public void Attack()
{
Debug.Log("공격!");
}
public void Movement()
{
float horizontal = Input.GetAxis("Horizontal");
rb.velocity = new Vector2(horizontal * speed, rb.velocity.y);
}
// Start is called before the first frame update
void Start()
{
rb = GetComponent<Rigidbody2D>();
}
// Update is called once per frame
void Update()
{
Movement();
}
}
// Base Decorator
public class CharacterDecorator : ICharacter
{
protected ICharacter character;
public CharacterDecorator(ICharacter character)
{
this.character = character;
}
public virtual void Attack()
{
character.Attack();
}
}
// Decorator - FireAttack
public class Decorator_CharacterFireAttack : CharacterDecorator
{
public Decorator_CharacterFireAttack(ICharacter character) : base(character)
{}
public override void Attack()
{
base.Attack();
Debug.Log("화염 공격!!");
}
}
// Decorator - IceAttack
public class Decorator_CharacterIceAttack : CharacterDecorator
{
public Decorator_CharacterIceAttack(ICharacter character) : base(character)
{}
public override void Attack()
{
base.Attack();
Debug.Log("냉기 공격!");
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DecoratorManager : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
ICharacter character = new Character();
character.Attack();
ICharacter fireCharacter = new Decorator_CharacterFireAttack(character);
fireCharacter.Attack();
ICharacter iceCharacter = new Decorator_CharacterIceAttack(character);
iceCharacter.Attack();
}
// Update is called once per frame
void Update()
{
}
}
'Studies > 게임 디자인 패턴' 카테고리의 다른 글
[게임 디자인 패턴] 방문자 패턴 (1) | 2024.09.26 |
---|---|
[게임 디자인 패턴] 옵저버 패턴 (0) | 2024.09.24 |
[게임 디자인 패턴] 오브젝트 풀 패턴 (7) | 2024.09.10 |
[게임 디자인 패턴] 커맨드 패턴 (0) | 2024.08.05 |
[게임 디자인 패턴] 이벤트 버스 (1) | 2024.07.16 |
댓글