Factory Method

2022. 2. 23. 00:00CSharp/Advance

반응형

객체를 생성하기 위한 인터페이스를 정의하는데, 어떤 클래스의 인스턴스를 만들지는 서브클래스에서 결정

 

문제

물류 관리 응용 프로그램을 만들고 있다고 상상해 보자.

앱의 첫 번째 버전은 트럭 운송만 처리할 수 있으므로 대부분의 코드는 Truck클래스 내에 있다.

나중에 앱 의 기능이 늘어서 배를 추가 하게 되면 Ships class 를 위해 전체 코드를 수정해야 할 수 있다.

다른 교통 수단을 또 추가 하기로 하였다면 전체 코드를 다시 수정해야 한다. 

 

 

해결책

팩토리 메소드 패턴은 직접적인 객체 생성 호출을 특별한 팩토리 메소드에 대한 호출로 변경한다. 

 

참조 : https://refactoring.guru/design-patterns/factory-method

 

모든 Product (Truk, Ship) 은 동일한 인터페이스를 따라야 한다. 

참조 : https://refactoring.guru/design-patterns/factory-method

 

팩토리 메서드에 의해 반환된 객체는 Product 이라고 하고 팩토리 메서드를 가지고 있는 객체를 Creator 라고 한다면 아래와 같은 diagram 으로 표현 할 수 있다. 

 

참조: https://refactoring.guru/design-patterns/factory-method

 

 

이제 아래의 전사,도적,암살자 예제를 통해 팩토리 메서드를 사용해 보자

 

Factory Method 를 가지고 있는 Creator

public interface ICreator
{
    public IUnitProduct CreateUnit();
}

public class WarriorCreator : ICreator
{
    public IUnitProduct CreateUnit() => new Warrior();
}

public class RogueCreator : ICreator
{
    public IUnitProduct CreateUnit() => new Rogue();
}

public class AssassinCreator : ICreator
{
    public IUnitProduct CreateUnit() => new Assassin();
}

Creator 에 의해 생성되는 각 Product (여기서는 Unit)

public interface IUnitProduct
{
    void Attack();
    void Defence();
}

public class Warrior : IUnitProduct
{
    public  void Attack() => Console.WriteLine("대검으로 공격");
    public  void Defence() => Console.WriteLine("방패로 방어");
}

public class Rogue : IUnitProduct
{
    public void Attack() => Console.WriteLine("독묻은 단검으로 공격");
    public void Defence() => Console.WriteLine("상대의 공격을 회피하여 방어");
}

public class Assassin : IUnitProduct
{
    public void Attack() => Console.WriteLine("쌍검으로 공격");
    public void Defence() => Console.WriteLine("쌍검을 교차하여 방어");
}

사용방법

public class Sample
{
    private readonly ICreator _creator;
    public Sample(ICreator creator)=> _creator = creator;
    public void Attack()=> _creator.CreateUnit().Attack();
    public void Defence()=> _creator.CreateUnit().Defence();
}

public class Test : ITest
{
    public void Run()
    {
        var sample = new Sample(new WarriorCreator());
        sample.Attack();
        sample = new Sample(new RogueCreator());
        sample.Attack();
        sample = new Sample(new AssassinCreator());
        sample.Defence();
    }
}
// output
대검으로 공격
독묻은 단검으로 공격
쌍검을 교차하여 방어

 

관련영상

https://youtu.be/-S5-jenvfvs

 

 

 

반응형

'CSharp > Advance' 카테고리의 다른 글

Singleton  (0) 2022.02.25
Prototype  (0) 2022.02.24
Builder  (0) 2022.02.22
Abstract Factory  (0) 2022.02.21
Parallel Programming (PLINQ Optimizing and Parallel Class)  (0) 2022.02.18