Шаблон фабричного метода, чтобы избежать создания объектов на основе условной логики - PullRequest
0 голосов
/ 23 июля 2010

В сценарии, подобном приведенному ниже, когда объект должен быть реализован на основе некоторой условной логики, может ли шаблон метода фабрики помочь избежать загромождения клиентского кода из-за количества условий if / elseif ( также будет кошмаром для техобслуживания, если все больше и больше продуктов нужно создавать из-за различных вариантов логики).

Или есть какой-то другой шаблон проектирования, который может прийти на помощь?

public interface IProduct
{
    void Method1();
}

public class ProductA : IProduct
{
    void Method1()
    {
    }
}

public class ProductB : IProduct
{
    void Method1()
    {
    }
}

public class ProductC : IProduct
{
    void Method1()
    {
    }
}

public class Client
{
    public void Test()
    {
        int count = 5;

        IProduct product;

        if (count < 10)
        {
            product = new ProductA();
        }
        else if (count == 10)
        {
            product = new ProductB();
        }
        else if (count > 10)
        {
            product = new ProductC();
        }

        product.Method1();


    }
}

Ответы [ 2 ]

5 голосов
/ 23 июля 2010

Похоже, заводской шаблон именно то, что вы хотите:


public class ProductFactory
{
    public IProduct GetProduct(int count)
    {
        if (count < 10)
        {
            return new ProductA();
        }
        else if (count == 10)
        {
            return new ProductB();
        }
        else if (count > 10)
        {
            return new ProductC();
        }
    }
}

Тогда, когда ваш клиентский код нуждается в экземпляре, он может просто идти


public class Client
{
    public void Test()
    {
        ProductFactory factory = new ProductFactory();

        IProduct product = factory.GetProduct(5);

        product.Method1();
    }
}

2 голосов
/ 23 октября 2010

Я не верю, что решение мистера Карвера строго следует структуре фабричного образца, описанного в книге GOF Design Pattern.Тем не менее, это очень распространенная идиома программирования (простая фабрика) и, вероятно, хороший подход для этого дизайна.

Фабричный образец требует, чтобы Конкретный Создатель был получен от Создателя.Как правило, Создатель делегирует создание продукта Конкретному Создателю.Это полезно, когда новая фабрика может быть добавлена ​​в будущем.Например, представьте, что вы создали новую фабрику, которая могла бы производить определенные продукты с меньшими ресурсами (счетчик используется в качестве прокси для «ресурса»).

    public interface IProduct
    {
      void PerformService();
    }

    public class ProductA : IProduct
    {
      public void PerformService()
      {
        Console.WriteLine("Product A's service.");
      }
    }

    public class ProductB : IProduct
    {
      public void PerformService()
      {
        Console.WriteLine("Product B's service.");
      }
    }

    public class ProductC : IProduct
    {
      public void PerformService()
      {
        Console.WriteLine("Product C's service.");
      }
    }

    abstract class ProductFactory
    {
      public abstract IProduct CreateProduct(int count);
    }

    class OriginalFactory : ProductFactory
    {
      public override IProduct CreateProduct(int count)
      {
        if (count < 10)
        {
          return new ProductA();
        }
        else if (count == 10)
        {
          return new ProductB();
        }
        else if (count > 10)
        {
          return new ProductC();
        }
        else
        {
          return null;
        }
      }
    }

    class NewFactory : ProductFactory
    {
      public override IProduct CreateProduct(int count)
      {
        if (count < 20)
        {
          return new ProductA();
        }
        else if (count == 20)
        {
          return new ProductB();
        }
        else if (count > 20)
        {
          return new ProductC();
        }
        else
        {
          return null;
        }
      }
    }

    public class FactoryTest
    {
      public void TestNew()
      {
        ProductFactory factory = new NewFactory();
        IProduct product = factory.CreateProduct(10); // Product B
        product.PerformService();
      }
      public void TestOld()
      {
        ProductFactory factory = new OriginalFactory();
        IProduct product = factory.CreateProduct(10); // Product A
        product.PerformService();
      }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...