C#에서 팩토리 패턴을 피하는 방법

도메인 모델 클래스



객체 지향은 클래스가 실제 도메인 모델 객체를 나타낼 때 훌륭합니다. 예를 들어 동물 소리를 모델링하는 경우 DogCat 클래스가 적합합니다.

interface IAnimal
{
    string Speak();
}

class Dog : IAnimal
{
    public string Speak() => "Woof";
}

class Cat : IAnimal
{
    public string Speak() => "Meow";
}


공장 패턴



이제 임의의 동물을 만들고 말을 하도록 요청하는 함수를 작성해야 한다고 가정해 보겠습니다. 불행히도 IAnimal 인터페이스에 생성자를 추가할 방법이 없습니다. 이 제한을 해결하는 한 가지 방법은 Factory design pattern 입니다. 이는 각 도메인 모델 클래스에 대해 별도의 "팩토리"클래스를 생성합니다.

interface IAnimalFactory
{
    IAnimal CreateAnimal();
}

class DogFactory : IAnimalFactory
{
    public IAnimal CreateAnimal() => new Dog();
}

class CatFactory : IAnimalFactory
{
    public IAnimal CreateAnimal() => new Cat();
}



새로운IAnimalFactory 인터페이스를 사용하여 개와 고양이를 만들고 말하게 할 수 있습니다.

class Program
{
    static void Main(string[] args)
    {
        Run(1, new DogFactory());
        Run(2, new CatFactory());
    }

    static void Run(int n, IAnimalFactory factory)
    {
        var animal = factory.CreateAnimal();
        Console.WriteLine($"Animal #{n} says '{animal.Speak()}'");
    }
}

// output:
// Animal #1 says 'Woof'
// Animal #2 says 'Meow'



이것은 잘 작동하지만 모든 도메인 모델 클래스가 이제 별도의 팩토리 클래스도 필요로 하기 때문에 상당한 양의 새로운 코드와 개념적 오버헤드를 추가합니다. 간접 참조의 추가 수준은 빠르게 혼란스러워질 수 있습니다. 더 좋은 방법이 있습니까?

공장 기능



함수형 프로그래밍을 사용하면 팩토리 클래스를 완전히 제거할 수 있습니다. IAnimalFactoryRun 에 전달하는 대신 Func<IAnimal> 유형의 "팩토리 함수"를 전달할 수 있습니다. 이것은 이전 구현에서 팩토리 객체가 수행한 역할을 대신합니다.

static void Run(int n, Func<IAnimal> createAnimal)
{
    var animal = createAnimal();
    Console.WriteLine($"Animal #{n} says '{animal.Speak()}'");
}


람다를 사용하여 약간의 의식 없이 팩토리 함수를 생성할 수 있습니다.

static void Main(string[] args)
{
    Run(1, () => new Dog());
    Run(2, () => new Cat());
}



출력은 정확히 동일합니다. 함수를 일급 객체로 사용하여 전체 클래스 범주를 제거하고 코드 기반을 크게 단순화했습니다! 미래에 팩토리 객체를 만들고 싶은 생각이 든다면, 대신 팩토리 함수를 사용하는 것을 고려하십시오.

좋은 웹페이지 즐겨찾기