Могу ли я использовать шаблон «Фабрика», если типы, которые я хочу создать, имеют разные входные параметры? - PullRequest
2 голосов
/ 25 января 2012

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

В родительской форме у меня есть методы, которые выглядят так:

public SubControl1 CreateSubControl1(Guid ID, Info userInfo, bool populate)
public SubControl1 CreateSubControl1(Guid ID, Info userInfo, bool populate, StateType1 state)

public SubControl2 CreateSubControl2(Guid ID, Info userInfo, bool populate, String dataFile, String dataFile2, )
public SubControl2 CreateSubControl2(Guid ID, Info userInfo, bool populate, String dataFile, String dataFile2,  StateType2 state)

private SubControl3 CreateSubControl3(Guid ID, Info userInfo, bool populate, String dateFile)
private SubControl3 CreateSubControl3(Guid ID, Info userInfo, bool populate, String dateFile,  StateType3 state)

private SubControl4 CreateSubControl4(Guid ID, Info userInfo, bool populate, WorkingFolder wf)
private SubControl4 CreateSubControl4(Guid ID, Info userInfo, bool populate, WorkingFolder wf, StateType4 state)

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

Однако, поскольку каждый из моих производных типов имеет немного разные входные параметры, мне интересно, как это сделать? Должен ли я создать «простую» фабрику, которая имеет общий метод Create, который принимает все возможные типы параметров и тип (чтобы отличить, какой SubControl 1 - 4 создать). Затем я мог бы использовать ноль для любых параметров, которые я не хочу устанавливать. Это кажется мне плохой идеей.

например. ControlFactory.Create(ID, userInfo, false, null, null, null, SubControlType1)

BaseControl - это базовый класс для всех типов элементов управления, например, SubControl1 до SubControl4.

Может кто-нибудь предложить какую-нибудь помощь?

Ответы [ 4 ]

4 голосов
/ 25 января 2012

Что бы вы ни делали, не создавайте один мега-метод с безлимитными параметрами.Это делает код нечитаемым и усложняет жизнь людям, которым придется писать код для вызова этого метода (включая вас).

Я имею в виду на самом деле.Посмотрите на этот вызов метода и скажите мне, что он делает:

 ControlFactory.Create(ID, userInfo, false, null, null, null, SubControlType1)

Вы не можете.С тремя пустыми аргументами и true / false, это нечитаемый, не поддерживаемый код.

Создайте несколько перегруженных или похожих именованных методов, которые настолько специфичны, насколько вы можете их создать.Для часто используемых методов я хотел бы рассмотреть вопрос об исключении одного из логических аргументов путем создания двух методов: одного жестко закодированного в случае True и одного жестко закодированного в False.Они вызывают общую внутреннюю функцию, которая принимает логический аргумент для совместного использования кода, но не ожидается, что она будет использоваться внешними потребителями.Вы всегда хотите, чтобы наиболее часто выполняемые действия требовали завершения укороченного пути - с точки зрения выполнения кода и с помощью нажатий клавиш, необходимых для его получения.

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

1 голос
/ 25 января 2012

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

BaseClass Create( ParameterObject parameterObject )
0 голосов
/ 25 января 2012

Если вы используете .Net 4, вы можете иметь именованные аргументы, которые очень хороши:)

public CreateSubControl(Guid ID, Info userInfo, bool populate, String dateFile = null, String dataFile2 = null, StateType1 statetype1 = null, StateType2 statetype2 = null)
{
    // Do stuff with those variables here

}

И назвать это (только некоторые примеры):

CreateSubControl(id, userinfo, populate, dateFile = "blah", statetype2 = somethinghere)
CreateSubControl(id, userinfo, populate, dateFile = "blah", dateFile2 = "blah2", statetype3 = somethingelsehere)

НоЯ согласен, что трудно прочитать этот код или сказать, что вы должны делать и почему существует так много похожих типов.Может быть, вам нужен интерфейс?

0 голосов
/ 25 января 2012

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

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

...