Stategy pattern

Yongs12 ㅣ 2024. 2. 7. 09:04

 

전략 패턴 인터페이스 정의 (IWeapon)

 

#pragma once

/*=================================
	   WeaponStategy Pattern
=================================*/

/*
전략 패턴은 특정 알고리즘이나 행동을 정의하고 이를 클라이언트에서 동적으로 교체할 수 있게 해주는 디자인 패턴이다.
이 패턴은 알고리즘을 개별적인 클래스로 캡슐화하여 서로 간의 교환이 가능하도록 한다.

장점
ㄴ 코드 재사용 : 여러 객체가 동일한 알고리즘을 공유하여 코드의 재사용성이 높다. 또한 같은 인터페이스로 구현한 여러 전략을 교체하기 쉽다.
ㄴ 확장성 : 기존 코드를 수정하지 않고도 새로운 전략을 추가하기 용이하다. (OCP)
ㄴ 단일 책임 : 별도의 클래스로 각각 분리되어 역할이 명확해지고 유지보수가 용이해진다. (SRP)

단점
ㄴ 복잡성 : 별도의 클래스로 만들기 때문에 코드의 복잡성을 증가시키고 관리하기 어려울 수 있다.

*/


class IWeapon 
{
public:
    virtual void attack() = 0;
    virtual ~IWeapon() {}

protected:
    IWeapon() {}
};

 

 

전략 패턴을 상속

#pragma once

#include "WeaponStategy.h"


class Sword : public IWeapon
{
public:
	Sword() 
	{
		cout << "검으로 장착\n";
	}
	~Sword() {}

public:
	void attack() override
	{
		cout << "검 공격\n";
	}

};

class Bow : public IWeapon
{
public:
	Bow()
	{
		cout << "활로 장착\n";
	}
	~Bow() {}

public:
	void attack() override
	{
		cout << "활 공격\n";
	}
};

 

 

Character 클래스 재사용

https://mygameprogramming.tistory.com/338

 

Prototype Pattern

Prototype 예시 (Character)#pragma once/*================================= Prototype Pattern=================================*//*프로토 타입 패턴은 객체 생성 방식 중 하나로 기존의 객체를 복제하여 새로운 객체를 만드는

mygameprogramming.tistory.com

 

Header file

/* 추가 사항
Observer Pattern을 위한 IObserver 상속 추가
State Pattern을 위한 ICharacterState 멤버 변수 추가
Stategy Pattern을 위한 IWeapon 멤버 변수 추가
무기가 없을 경우 기본 공격을 위한 Fist.h 추가
*/
#include "Observer.h"
#include "CharacterState.h"
#include "IdleState.h"
#include "WeaponStategy.h"
#include "Fist.h"

... 기존과 동일
public: 
    void update(EEventType event) override;
    void setState(unique_ptr<ICharacterState> newState);
    void stateUpdate(char input);
    void setWeapon(unique_ptr<IWeapon> weapon);
// 공격 형태 추가
    void performAttack();
    
private:
    string _name;
    int _hp = 0;    
    int _mp = 0;    
    int _speed = 0; 
    Vector3D _position;
// 기본 공격
    Fist _fist;

    unique_ptr<ICharacterState> _currentState = make_unique<IdleState>();
// 무기 공격을 위한 멤버 변수 추가
    unique_ptr<IWeapon> _weapon;
};

 

cpp file

void Character::performAttack()
{
    if (_weapon)
    {
        _weapon->attack();
    }
    else
    {
        _fist.attack();
    }
}

 

 

상태 패턴 부분 일부 수정 ( 차후 키 입력 처리 부분 수정 예정 )

MovingState 키입력 처리 부분

void MovingState::handleInput(Character* character, char direction)
{
    Vector3D position = character->getPosition();
    const int speed = character->getSpeed();

    switch (direction)
    {
    case 'w':
        position.y += speed;
        break;
    case 's':
        position.y -= speed;
        break;
    case 'a':
        position.x -= speed;
        break;
    case 'd':
        position.x += speed;
        break;
    case 'f':
// 특정 키 입력에 따른 무기 공격 추가
        character->performAttack();
        return;
    default:
        character->setState(make_unique<IdleState>());
        return;
    }

    move(character, position);
}

 

 

사용 예시

int main()
{
	Mage prototypeMage(100, 100, 80, "메이지");

	unique_ptr<Character> copyMage = prototypeMage.clone();

	bool run = true;

	while (run)
	{
		if (_kbhit())
		{
			char key = _getch();

			// 무기 장착
			if (key == '1')
			{
				copyMage->setWeapon(make_unique<Sword>());
			}
			else if (key == '2')
			{
				copyMage->setWeapon(make_unique<Bow>());
			}

			copyMage->stateUpdate(key);
		}
	}

	return 0;
}

 

실행 화면

 

'Design Pattern' 카테고리의 다른 글

State Pattern  (0) 2024.02.06
Observer Pattern  (0) 2024.02.05
Prototype Pattern  (0) 2024.02.04
Builder Pattern  (0) 2024.02.03
Factory Pattern  (0) 2024.02.02