Что Ваш порог должен использовать фабрику вместо конструктора для создания объекта?

Вы можете определить поле в вашем компоненте и установить его в true при отправке.

<button class="btn btn-primary" (click)="processAdd()" [disabled]="addfrm.invalid || submitted">add</button>

внутри компонента

export class MyComponent {
    submitted = false;
    ...

    processAdd() {
        this.submitted = true; 
        this.someService.post(this.addForm).subscribe(result => {
            this.submitted = false; // reset it on response from server
        });
    }

}
11
задан StackUnderflow 28 January 2009 в 22:51
поделиться

9 ответов

Я использую фабрику, если у меня есть абстрактный базовый класс (или интерфейс), и несколько конкретных производных классов, и существует некоторая логика, согласно которой создается один из реальных классов. Я реализую ту логику на фабрике.

13
ответ дан 3 December 2019 в 04:14
поделиться

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

5
ответ дан 3 December 2019 в 04:14
поделиться

Я не абсолютно уверенный, как Вы выбрали свои пороги...

Фабрики являются соответствующими, если Вы не хотите абстрагировать потребителя объекта от конструкции. Экземпляры, где это может быть подходящим:

  • Можно хотеть к sub реализацию во времени выполнения. Часто это объединено с использованием интерфейсов, а не реальных классов. Пример в Java был бы то, как Вы получаете Объект документа от DocumentBuilder в Java.
  • Можно хотеть ограничить # экземпляров объекта. Думайте о построении Пула с ограниченным количеством объектов потока вместо того, чтобы просто создать новый все время

Проверьте Книгу Четыре (Гамма и. al.) шаблоны заказывают и смотрят на шаблон "фабрика" подробно для получения дополнительной информации о том, когда использовать этот шаблон.

2
ответ дан 3 December 2019 в 04:14
поделиться

Что-то интересное о C#, который касается этой темы, то, что новое () ограничение на универсальные типы, которые указаны в определении класса, вызывает типы, которые обрабатываются универсальным контейнерным типом для реализации конструктора без параметров. Новое () ограничение только необходимо, когда каждый намеревается создать экземпляр типа T, как в GenericType<T>, в классе. Мне кажется, что это явно в поддержку фабрик классов, особенно фабрики, которые производят универсальные типы.

Для переворачивания этого требования с ног на голову Windows Communication Foundation (WCF) имеет класс ChannelFactory, который определяет следующий статический метод фабрики:

public static TChannel CreateChannel(Binding binding, EndpointAddress endpointAddress, Uri via)
{
    ChannelFactory<TChannel> factory = new ChannelFactory<TChannel>(binding);
    if (factory.HasDuplexOperations())
    {
        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString("SFxInvalidStaticOverloadCalledForDuplexChannelFactory1", new object[] { factory.channelType.Name })));
    }
    TChannel channel = factory.CreateChannel(endpointAddress, via);
    ChannelFactory<TChannel>.SetFactoryToAutoClose(channel);
    return channel;
}

Если Вы смотрите в Отражателе на дизассемблирование класса (Система. Блок ServiceModel и Система. ServiceModel. Пространство имен каналов), Вы заметите, что "новый ()" не используется в качестве ограничения.

Поэтому метод CreateChannel использует typeof (TChannel) для делегирования создания объекта далее вниз цепочка...

public virtual TChannel CreateChannel(EndpointAddress address, Uri via)
{
    TChannel local;
    bool traceOpenAndClose = base.TraceOpenAndClose;
    try
    {
        using (ServiceModelActivity activity = (DiagnosticUtility.ShouldUseActivity && base.TraceOpenAndClose) ? ServiceModelActivity.CreateBoundedActivity() : null)
        {
            if (DiagnosticUtility.ShouldUseActivity)
            {
                ServiceModelActivity.Start(activity, this.OpenActivityName, this.OpenActivityType);
                base.TraceOpenAndClose = false;
            }
            if (address == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("address");
            }
            if (base.HasDuplexOperations())
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString("SFxCreateNonDuplexChannel1", new object[] { base.Endpoint.Contract.Name })));
            }
            base.EnsureOpened();
            local = (TChannel) this.ServiceChannelFactory.CreateChannel(typeof(TChannel), address, via);
        }
    }
    finally
    {
        base.TraceOpenAndClose = traceOpenAndClose;
    }
    return local;
}

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

RemotingServices.CreateTransparentProxy(this, classToProxy, stub, stubData);

Это является чрезвычайно замысловатым, но это - самая сложная фабрика, которую я когда-либо видел. Интересно достаточно все махинации заканчиваются с WCF создание класса RealProxy от Системы. Время выполнения. Дистанционная работа. Пространство имен прокси.

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

3
ответ дан 3 December 2019 в 04:14
поделиться

Вот радикальная мысль (я действительно не защищаю ее, но я не думаю, что она вредила бы):

Всегда используйте методы фабрики!

Методы фабрики более гибки, например, они могут кэшировать результаты или возвратить дочерние классы.

Так, вместо:

class SomeClass {
  public SomeClass(/*parameters*/) { /*...*/ }
} 

Всегда использование:

class SomeClass {
  protected SomeClass(/*parameters*/) { /*...*/ }
  public static SomeClass New(/*parameters*/) {
    return new SomeClass(/*parameters*/);
  }
} 

Код вызывающей стороны изменяется от:

SomeClass sc = new SomeClass();

Кому:

SomeClass sc = SomeClass.New();

Можно теперь изменить логику "конструктора" для возврата подклассов или кэшируемых экземпляров, и все вызывающие стороны не затронуты. Вы теперь управляете возвращаемым значением своих "конструкторов".

1
ответ дан 3 December 2019 в 04:14
поделиться

Мне нравится сохранять число конструкторов к разумному низкому уровню; больше чем два или три, и я подвергаю сомнению, как хорошо конструкция объекта разработана.

В случаях, где дополнительные конструкторы представляются для поддержки устанавливающих различных дополнительных атрибутов, мне нравится использовать Разработчика, как описано в Эффективном Java (Joshua Bloch, 2-й редактор)

1
ответ дан 3 December 2019 в 04:14
поделиться

Используйте фабрику когда, решением которого реальный класс инстанцировать не до клиента. например, где существует несколько 'семейств' объектов и выбором которого семейство использовать сделано в другом месте.

0
ответ дан 3 December 2019 в 04:14
поделиться

Я пытаюсь иметь размеры между теми. Я думаю, что необходимо использовать фабрики когда:

  1. Высокое количество параметрического усилителя.
  2. Дополнительный параметрический усилитель. (Оба использования внутреннего класса шаблон Разработчика)
  3. Необходимо будет изменить порядок параметров для выполнения другого действия, из-за тех же типов параметра, но различных данных.
  4. Вам нужен singleton-класс (лучше сделанный с перечислением)

С фабриками, в этом случае, можно дать имя собственное объектному возвращаемому состоянию.

0
ответ дан 3 December 2019 в 04:14
поделиться

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

0
ответ дан 3 December 2019 в 04:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: