Абстрактный шаблон разработки фабрики

По умолчанию изображение отображается inline, как буква.

Он сидит в той же строке, на которой сидят a, b, c и d.

Существует пространство ниже этой строки для descenders, которые вы найдете на таких буквах, как f, j, p и q.

Вы можете отрегулировать vertical-align изображения, чтобы разместить его в другом месте (например, middle) или изменить display, чтобы он не был встроен.

21
задан FlySwat 16 September 2008 в 14:37
поделиться

10 ответов

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

удостоверяются, что у Вас есть "Система использования. Отражение", помещают следующий код в Ваш метод инстанцирования.

public Task CreateTask(XmlElement elem)
{
    if (elem != null)
    { 
        try
        {
          Assembly a = typeof(Task).Assembly
          string type = string.Format("{0}.{1}Task",typeof(Task).Namespace,elem.Name);

          //this is only here, so that if that type doesn't exist, this method
          //throws an exception
          Type t = a.GetType(type, true, true);

          return a.CreateInstance(type, true) as Task;
        }
        catch(System.Exception)
        {
          throw new ArgumentException("Invalid Task");
        }
    }
}

Другое наблюдение, то, что можно сделать этот метод, помехи и подвесить его прочь класса Задачи, так, чтобы у Вас не было к новому TaskFactory, и также Вы добираетесь для сохранения себя движущаяся часть для поддержания.

12
ответ дан 29 November 2019 в 21:21
поделиться

Создайте "Прототип" instanace каждого класса и поместите их в хеш-таблицу в фабрике со строкой, которую Вы ожидаете в XML как ключ.

, таким образом, CreateTask просто находит, что правильный Объект прототипа, получают () луг от хеш-таблицы.

тогда вызов LoadFromXML на нем.

необходимо предварительно загрузить классы в хеш-таблицу,

, Если Вы хотите ее более автоматический...

можно сделать классы "саморегистрирующийся" путем вызова статического метода регистра на фабрике.

Помещенные вызовы для регистрации (в конструкторах) в статических блоках на подклассах Задачи. Тогда все, что необходимо сделать, "упомянуть" классы для обстрела статических блоков.

А статический массив подклассов Задачи был бы тогда достаточен для "упоминания" их. Или используйте отражение для упоминания классов.

6
ответ дан 29 November 2019 в 21:21
поделиться

Что Вы думаете о Внедрении зависимости? Я использую Ninject, и контекстная обязательная поддержка в нем идеально подошла бы для этой ситуации. Посмотрите на этот сообщение в блоге о том, как можно использовать контекстную привязку с созданием контроллеров с IControllerFactory, когда их требуют. Это должно быть хорошим ресурсом о том, как использовать его для Вашей ситуации.

4
ответ дан 29 November 2019 в 21:21
поделиться

@jholland

я не думаю перечисление Типа, необходим, потому что я могу всегда делать что-то вроде этого:

Перечисление?

я признаю, что это чувствует hacky. Отражение чувствует себя грязным сначала, но как только Вы приручаете зверя, Вы будете наслаждаться тем, что это позволяет Вам делать. (Помните рекурсию, это чувствует себя грязным, но ее польза)

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

BTW: оператор, отражение также.

http://en.wikipedia.org/wiki/Reflection_ (computer_science) #Uses

2
ответ дан 29 November 2019 в 21:21
поделиться

@Tim, я закончил тем, что использовал упрощенную версию Вашего подхода и ChanChans, Вот код:

public class TaskFactory
    {
        private Dictionary<String, Type> _taskTypes = new Dictionary<String, Type>();

        public TaskFactory()
        {
            // Preload the Task Types into a dictionary so we can look them up later
            foreach (Type type in typeof(TaskFactory).Assembly.GetTypes())
            {
                if (type.IsSubclassOf(typeof(CCTask)))
                {
                    _taskTypes[type.Name.ToLower()] = type;
                }
            }
        }

        public CCTask CreateTask(XmlElement task)
        {
            if (task != null)
            {
                string taskName = task.Name;
                taskName =  taskName.ToLower() + "task";

                // If the Type information is in our Dictionary, instantiate a new instance of that task
                Type taskType;
                if (_taskTypes.TryGetValue(taskName, out taskType))
                {
                    return (CCTask)Activator.CreateInstance(taskType, task);
                }
                else
                {
                    throw new ArgumentException("Unrecognized Task:" + task.Name);
                }                               
            }
            else
            {
                return null;
            }
        }
    }
2
ответ дан 29 November 2019 в 21:21
поделиться

@ChanChan

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

Вы действительно получали меня взгляды, я не думаю, что перечисление Типа необходимо, потому что я могу всегда делать что-то вроде этого:

if (CurrentTask is MergeTask)
{
    // Do Something Specific to MergeTask
}

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

1
ответ дан 29 November 2019 в 21:21
поделиться

Перечисление?

я обращался к свойству Type и перечислению в моем абстрактном классе.

Отражение это тогда! Я отмечу Вас ответ, как принято приблизительно через 30 минут, только для предоставления времени для кого-либо еще для взвешиваний. Это - забавная тема.

1
ответ дан 29 November 2019 в 21:21
поделиться

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

1
ответ дан 29 November 2019 в 21:21
поделиться

@Dale

я не осмотрел nInject тесно, но от моего понимания высокого уровня внедрения зависимости, я полагаю, что это выполнило бы то же самое как предложение ChanChans, только с большим количеством слоев хлама (er абстракция).

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

, Но возможно я не понимаю, что преимущество nInject дало бы мне здесь.

1
ответ дан 29 November 2019 в 21:21
поделиться

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

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

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

1
ответ дан 29 November 2019 в 21:21
поделиться
Другие вопросы по тегам:

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