Nano Hash - криптовалюты, майнинг, программирование

Параметризованная абстрактная фабрика/фабричный метод/другие шаблоны создания

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

Как подготовить эту архитектуру в соответствии с шаблонами проектирования?

Текущий подход ниже

public abstract class Product {}

public class MyProduct : Product
{
    public bool Abc { get; set; }
}

public class YourProduct : Product {}

public abstract class ProductFactory
{
    //in some cases parameter not in use
    public abstract Product Create(HelpData additionalData);
}

public class MyProductFactory : ProductFactory
{
    public override Product Create(HelpData additionalData)
    {
        return new MyProduct {Abc = additionalData.SomethingImportantForMyProduct};
    }
}

public class YourProductFactory : ProductFactory
{
    //unused parameter
    public override Product Create(HelpData additionalData)
    {
        return new YourProduct();
    }
}

public class HelpData
{
    public bool SomethingImportantForMyProduct { get; set; }
}

ИЗМЕНИТЬ

Я вижу, что это не ясно, поэтому повторю.

Обычно я не использую шаблоны только потому, что использую их. Но эта проблема, похоже, не пограничный случай. Выглядит довольно часто. Идя дальше, я считаю, что для этого есть подходящий шаблон проектирования, но я не уверен, какой именно. На данный момент похоже, что абстрактная фабрика не является правильным выбором.


  • Я полагаю, вам нужны два разных фабричных метода, один с параметром в пределах MyProductFactory, а другой без параметра в пределах YourProductFactory. Это означает, что фабрика вообще не будет производной от ProductFactory. 12.04.2017
  • @HimBromBeere, тогда это не заводской шаблон проектирования. Я не говорю, что это должно быть именно так, но я твердо верю, что этого можно добиться в соответствии с любым шаблоном проектирования :) 12.04.2017
  • @Святой, что заставляет тебя думать, что это неправильно? 12.04.2017
  • Звучит как дырявая абстракция. Предоставленные вами параметры должны быть обязательными для обоих типов, создаваемых фабриками. Если вам нужно настроить другие аспекты этих типов, рассмотрите возможность предоставления этих отдельных значений (или поставщиков этих значений) конструкторам фабрик. Дайте мне знать, если вы хотите увидеть пример. 12.04.2017
  • @AndriiLitvinov Если вы можете привести пример. Но еще одно: фабрики также внедряются в c-tors своего клиентского класса. 12.04.2017
  • @HeyJude минусует тебя? Во всяком случае, я имею в виду то, что упомянул Андрей Литвинов - все производные классы должны знать, что делать с переданным аргументом. В данном случае он вообще не используется. Это не мнение, так как оно основано на общих передовых методах. Если вы сделаете: string one = 1.ToString(), это тоже будет неправильно, и опять же, это не основано на мнении. Однако я не хочу обсуждать здесь неправильное и правильное, а не другое решение для этого. 12.04.2017

Ответы:


1

Не используйте шаблоны дизайна, потому что вы используете шаблоны дизайна. Всегда имейте в виду, когда его использовать, а когда нет. В ваших условиях, по крайней мере, абстрактный фабричный шаблон неверен, поскольку он предполагает, что все фабрики работают с одинаковыми параметрами. Поэтому, если у вас разные параметры, вам наверняка нужны разные фабрики. Однако у абстрактной фабрики нет возможности угадать, как получить экземпляр HelpData в одном случае, но не в другом, поэтому либо передайте его каждой абстрактной фабрике, либо полностью опустите эту дальнейшую абстракцию. и остаться с двумя независимыми фабриками:

public abstract class Product {}

public class MyProduct : Product
{
    public bool Abc { get; set; }
}

public class YourProduct : Product {}

public class MyProductFactory
{
    public Product Create(HelpData additionalData)
    {
        return new MyProduct {Abc = additionalData.SomethingImportantForMyProduct};
    }
}

public class YourProductFactory
{
    //unused parameter
    public Product Create()
    {
        return new YourProduct();
    }
}

public class HelpData
{
    public bool SomethingImportantForMyProduct { get; set; }
}

Предоставлять параметр, используемый только в одной фабрике, для всех фабрик — не лучшая идея.

Помимо этого просто представьте, что у вас не фабрики, а любые другие классы, у которых есть Create-метод, где одному нужен параметр, а другому нет. Почему эти два класса должны быть производными от одного и того же базового класса (в вашем случае абстрактной фабрики), когда у них нет общих членов? По-видимому, для этого нет никакой причины, поэтому не усложняйте вещи только ради использования шаблона, который не подходит.

13.04.2017
  • Да, я не использую шаблоны только потому, что использую их. Я подумываю избавиться от абстракции, так как этот пример не соответствует правилу. Мне было интересно, не пропустил ли я что-то о шаблонах, связанных с фабрикой. 13.04.2017
  • Спасибо за Ваш ответ. Пожалуйста, смотрите мое обновление в вопросе 13.04.2017

  • 2

    В зависимости от того, где и как вы получаете дополнительные данные, вы можете ввести эти данные в фабрику, которая будет использовать их для создания объекта:

    public abstract class ProductFactory
    {
        public abstract Product Create();
    }
    
    public class MyProductFactory : ProductFactory
    {
        private HelpData additionalData;
    
        public MyProductFactory(HelpData additionalData)
        {
             this.additionalData = additionalData;
        }
    
        public override Product Create()
        {
            return new MyProduct {Abc = additionalData.SomethingImportantForMyProduct};
        }
    }
    
    public class YourProductFactory : ProductFactory
    {
        public override Product Create()
        {
            return new YourProduct();
        }
    }
    

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

    Я также немного погуглил и нашел хороший ответ, который объясняет, почему не https://stackoverflow.com/a/6241219/2138959. Передача словаря или типа, который имеет свойство типа словаря, также является опцией, но в таких подходах клиент слишком много знает о типе, который он хочет создать, чтобы использовать абстрактную фабрику.

    12.04.2017
  • На самом деле это не очень хороший подход в данном случае. Продукт будет отличаться для каждого вызова метода Create. Для этого упрощенного примера иногда будет верно, иногда ложно. Дополнительный сервис также не знает о деталях, поскольку он поступает непосредственно из пользовательского интерфейса. Мне интересно, можно ли вообще использовать здесь абстрактную фабрику. 13.04.2017
  • Это возможно, но опять же, потребитель фабрики будет слишком много знать о конкретных требованиях фабрики, что является дырявой абстракцией. Поэтому я бы не предлагал абстрактный заводской подход. Что касается того, что логический параметр будет меняться для каждого запроса, вы можете создать новую фабрику для каждого запроса с новым параметром. Но вам, вероятно, следует также обратить внимание на шаблон стратегии. 13.04.2017
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..