статические методы фабрики против фабрики - PullRequest
2 голосов
/ 03 мая 2011

У меня есть классы, которые должны иметь свойства с частными установщиками (или с ними связаны частные поля и свойства Readonly).Это нормально, если у меня есть статические фабричные методы в этих классах для создания экземпляров.Однако многие разработчики пишут, что «Статические фабричные методы - это архитектурная черная дыра», так как невозможно наследовать статические методы.

C # не имеет дружественных классов, поэтому я не могу сделать это с помощью Factories.

Что вы думаете об использовании статических фабричных методов?

Ответы [ 6 ]

2 голосов
/ 04 мая 2011

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

Если у вас есть сложные правила создания экземпляров, которые зависят от параметров и, возможно, других факторов, вы можете использовать фабрику, может быть, свободную фабрику, которая собирает все необходимые параметры и выполняет необходимую логику, а затем использует открытый конструктор класса для создания предмет.

2 голосов
/ 03 мая 2011

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

Пример:

class Foo : IFoo
{
    private readonly IBar bar;
    private readonly IBaz baz;

    public Foo(IBar bar, IBaz baz)
    {
        this.bar = bar;
        this.baz = baz;
    }

    // Readonly properties for bar and baz, if needed.
} 
1 голос
/ 03 мая 2011

Я полагаю, что когда люди говорят, что статические фабричные методы «... [это] архитектурная черная дыра» », они имеют в виду проблему, заключающуюся в том, что расширение фабричных методов бесполезно. Смысл в том, насколько сложны созданные классы. Если они тяжелые, то, вероятно, статические фабричные методы в конечном итоге приведут к беспорядку.

В C # действительно есть модификатор «internal», который не заменяет друга, поскольку другие работают над вашими классами, но когда важна ваша способность расширять фабрики в будущем, а не другие, вы может упаковать фабрики и созданные классы как отдельную сборку и, таким образом, использовать «внутренний», например, «друг».

И, да, это проблема при работе с C #. Противоречивые требования, которые отбросили поддержку старого дружественного фабричного класса, и это болезненно. Если вы не можете использовать «internal», и ваши фабрики производят тяжеловесные классы, на самом деле нет никакой альтернативы добавлению метода типа «InitInstance ()» к классам, чтобы можно было расширить «производственный процесс».

1 голос
/ 03 мая 2011

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

Итак, ответ таков: useстатические методы пожалуйста!:)

1 голос
/ 03 мая 2011

Не думаю, что утверждение:

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

Это действительно правда.

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

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

0 голосов
/ 03 мая 2011

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

internal interface IMyClassFactorable
{
    string MyProperty{ set; }
}

public class MyClass : IMyClassFactorable
{
     private string _myProperty;
     public string MyPrperty { get { return _myProperty; } }
     string IFactoryable.MyProperty { set { _myProperty = value; } }
}

илис внутренними установщиками, если фабрика и цели находятся в одной сборке

public class MyClass 
{
     public string MyPrperty { get; internal set; }
}
...