article thumbnail image
Published 2022. 3. 8. 01:20

#include <iostream>
using namespace std;

class Monster {

public:
	Monster(int ID) : ID{ ID }, type{ Monster::Type::unknown } {}
	virtual void Attack() = 0;
	virtual ~Monster() {}
protected:
	enum class Type { unknown, slime, hog };
	class Ability {
	public:
		int STR, AGI, INT;
		Ability() : STR{ 0 }, AGI{ 0 }, INT{ 0 }{}
		Ability(int STR, int AGI, int INT) :
			STR{ STR }, AGI{ AGI }, INT{ INT }{}
	};
	int ID;
	Type type;
	Ability ability;
};

class Slime : public Monster {
	friend class MonsterFactory;
public:
	Slime() = delete;
	Slime(int ID, Ability ability) : Monster{ ID }, ability{ ability }{}
	Slime(int ID, int STR, int AGI, int INT)
		: Monster{ ID }, ability(STR, AGI, INT){}
	void Attack() override {
		cout << "ID : " << ID << " : slime attack" << endl;
	}
	~Slime() {}
private:
	Type type = Type::slime;
	Ability ability;

};

class Hog : public Monster {
	friend class MonsterFactory;
public:
	Hog() = delete;
	Hog(int ID) : Monster{ ID } {}
	Hog(int ID, Ability ability) : Monster{ ID }, ability{ ability }{}
	Hog(int ID, int STR, int AGI, int INT)
		: Monster{ ID }, ability(STR, AGI, INT){}
	void Attack() override {
		cout << "ID : " << ID << " : hog attack" << endl;
	}
	~Hog() {}
private:
	Type type = Type::hog;
	Ability ability;
};

class MonsterFactory {
public:
	static Slime proto_slime;
	static Hog proto_hog;
public:
	static std::unique_ptr<Slime> Create_Slime(int ID, Slime& proto) {
		return Create_Monster(ID, proto);
	}

	static std::unique_ptr<Hog> Create_Hog(int ID, Hog& proto) {
		return Create_Monster(ID, proto);
	}

private:
	template<typename T>
	static std::unique_ptr<T> Create_Monster(int ID, T& proto) {
		std::unique_ptr<T> res;

		if (proto.type == Monster::Type::slime) {
			res = std::make_unique<T>(ID, proto.ability);
		}
		else if (proto.type == Monster::Type::hog) {
			res = std::make_unique<T>(ID, proto.ability);
		}

		return res;
	}
};

Slime MonsterFactory::proto_slime = Slime{ 1,10,32,10 };
Hog MonsterFactory::proto_hog = Hog{ 1,10,32,10 };

int main(void) {
	auto s1 = MonsterFactory::Create_Slime(112, MonsterFactory::proto_slime);
	s1->Attack();
	auto s2 = MonsterFactory::Create_Slime(4540, MonsterFactory::proto_slime);
	s2->Attack();
	s1->Attack();
	s2->Attack();
}

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

Singleton 싱글턴  (0) 2022.10.25
Builder  (0) 2020.11.30
SOLID Design Principles  (0) 2020.11.24
복사했습니다!