본문 바로가기
프로그래밍/디자인패턴

Factory Mathod Pattern

by 리뷰하는 (게임)프로그래머_리프TV 2017. 4. 12.

Factory Method Pattern 에 대해서 알아보도록 하겠습니다.

 

개인적으로 이 패턴에 대해서 이해를 하는 과정이 있어서, 가장 좋은 방법은

사용, 결과를 확인 하였을 때 가장 이해가 빠르지 않나 싶습니다.

 

namespace Pattern
{
    public class FactoryMathodClass : MonoBehaviour
    {
        void Start()
        {
//            FrameWork.Factory factory = new UnitCreate.UnitFactory(); 이렇게 해도 됩니다.
            UnitCreate.UnitFactory factory = new UnitCreate.UnitFactory();
            FrameWork.Unit unit1 = factory.create(FrameWork.UnitType.fly);
            FrameWork.Unit unit2 = factory.create(FrameWork.UnitType.fly);
            FrameWork.Unit unit3 = factory.create(FrameWork.UnitType.fly);
            FrameWork.Unit unit4 = factory.create(FrameWork.UnitType.walk);

            unit1.use();
            unit2.use();
            unit3.use();
            unit4.use();
        }
    }
}​

결과를 보면 텍스트 뿐이지만, 실제로 생성되는 클래스는 각각 다른 클래스 입니다.

 

public class FlyUnit : FrameWork.Unit
{
	public FlyUnit()
	{
		Debug.Log("날으는 유닛 생성");
	}

	public override void use()
	{	
		Debug.Log("날으는 유닛을 사용");
	}
}

public class WalkUnit : FrameWork.Unit
{
	public WalkUnit()
	{
		Debug.Log("걸어다니는 유닛 생성");
	}

	public override void use()
	{
		Debug.Log("걸어다니는 유닛을 사용");
	}
}
​

다음은 UnitFactory Class 를 확인해 봅시다.

 

    public class UnitFactory : FrameWork.Factory
    {
        private List<FrameWork.Unit> unitList = new List<FrameWork.Unit>();

        protected override FrameWork.Unit createUnit(FrameWork.UnitType type)
        {
            if (type == FrameWork.UnitType.fly)
                return new FlyUnit();
            else
                return new WalkUnit();
        }

        protected override void registerUnit(FrameWork.Unit unit)
        {
            unitList.Add(unit);
        }

        public List<FrameWork.Unit> getUnitList()
        {
            return unitList;
        }
    }​

Factory 라는 가상 클래스에서 상속받아, 생성 타입에 따라 Fly, Walk 등을 만들어 낸다고 보시면됩니다.

사실 상황에 따라 다르게 쓰일 수 있는데, 

이번 예제 같은 경우엔 UnitFactory 하나를 만들어 2가지 유닛을 생성하는 용도로 사용하였지만,

- FlayUnitFactory

- WlakUnitFactory 

이렇게 2개로 나누어 작성할 수도 있을 것 같습니다.

 

그럼 마지막으로 Factory Class를 살펴 보겠습니다.

 

namespace FrameWork
{
    public enum UnitType
    {
        fly,
        walk,
    }
    public abstract class Factory
    {
        public Unit create(UnitType type)
        {
            Unit u = createUnit(type);
            registerUnit(u);

            return u;
        }

        protected abstract Unit createUnit(UnitType type);
        protected abstract void registerUnit(Unit unit);
    }

    public abstract class Unit
    {
        public abstract void use();
    }
}
​

쉽게 말해, 무언가를 찍어내고 싶을때 많이 사용하는 패턴입니다. 만들고 관리하는 과정에 있어서 편리함을 주기 위함이라고 보시면 될 것 같습니다. 

 

어떤것을 만들던지 쉽게 만들 수 있고( 정해진 패턴내에서 )

이미 만든것들을 관리하기 편하게 한다던가,

원한다면 제거 하는 과정에서도 쉽게 컨트롤 할 수 있습니다. 

 

테스트를 위한 전체 코드를 첨부하고 마치도록하겠습니다.

 

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

namespace FrameWork
{
    public enum UnitType
    {
        fly,
        walk,
    }
    public abstract class Factory
    {
        public Unit create(UnitType type)
        {
            Unit u = createUnit(type);
            registerUnit(u);

            return u;
        }

        protected abstract Unit createUnit(UnitType type);
        protected abstract void registerUnit(Unit unit);
    }

    public abstract class Unit
    {
        public abstract void use();
    }
}

namespace UnitCreate
{
    public class FlyUnit : FrameWork.Unit
    {
        public FlyUnit()
        {
            Debug.Log("날으는 유닛 생성");
        }

        public override void use()
        {
            Debug.Log("날으는 유닛을 사용");
        }
    }

    public class WalkUnit : FrameWork.Unit
    {
        public WalkUnit()
        {
            Debug.Log("걸어다니는 유닛 생성");
        }

        public override void use()
        {
            Debug.Log("걸어다니는 유닛을 사용");
        }
    }

    public class UnitFactory : FrameWork.Factory
    {
        private List<FrameWork.Unit> unitList = new List<FrameWork.Unit>();

        protected override FrameWork.Unit createUnit(FrameWork.UnitType type)
        {
            if (type == FrameWork.UnitType.fly)
                return new FlyUnit();
            else
                return new WalkUnit();
        }

        protected override void registerUnit(FrameWork.Unit unit)
        {
            unitList.Add(unit);
        }

        public List<FrameWork.Unit> getUnitList()
        {
            return unitList;
        }
    }
}

namespace Pattern
{
    public class FactoryMathodClass : MonoBehaviour
    {
        void Start()
        {
//            FrameWork.Factory factory = new UnitCreate.UnitFactory(); 이렇게 해도 됩니다.
            UnitCreate.UnitFactory factory = new UnitCreate.UnitFactory();
            FrameWork.Unit unit1 = factory.create(FrameWork.UnitType.fly);
            FrameWork.Unit unit2 = factory.create(FrameWork.UnitType.fly);
            FrameWork.Unit unit3 = factory.create(FrameWork.UnitType.fly);
            FrameWork.Unit unit4 = factory.create(FrameWork.UnitType.walk);

            unit1.use();
            unit2.use();
            unit3.use();
            unit4.use();
        }
    }
}​