2011-02-01 3 views
3

У меня есть набор классов, которые работают вместе (я кодирую в javascript).Есть ли шаблон дизайна для инъекций методов в класс?

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

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

Основной класс динамически создает методы, и клиенты могут вызывать методы, как они были там все время.

Мои вопросы:

  1. это разумная вещь, чтобы сделать?
  2. Каков будет шаблон дизайна для того, что я делаю?
+0

Работа с классами в Javascript была сложной 4 года назад. – nbro

ответ

3

strategy pattern предназначен для ситуаций, когда вы получаете свою стратегию во время работы. могут быть применимы здесь. Стратегия в этом случае - это класс, который соответствует поведению, то есть имеет метод «выполнить» или что-то еще.

decorator pattern также могут применяться. Это также шаблон времени выполнения, но увеличивает класс, который он украшает на уровне метода.

Итак, шаблон стратегии хорош, если вы выбираете класс динамически, а Decorator хорош, если вы только меняете реализацию метода во время выполнения.

(я взял декоратор часть этого ответа с разрешением ircmaxell)

+0

Ну, стратегия - это компостирование объектов во время выполнения (соединение объектов вместе). Decorator - это методы компостирования во время выполнения (добавление методов/возможностей к объекту). Та же концепция, но разный уровень. Хотя стратегия может работать в этом случае (и может быть лучше, чем то, что делается), стратегия работает на уровне класса, а описание, описанное выше, работает на уровне метода (и, следовательно, будет Decorator) ... – ircmaxell

+0

@ircmaxell , я никогда этого не знал, но ведь ты прав! Могу ли я добавить это к моему ответу? – hvgotcodes

+0

Абсолютно! Вы можете ссылаться на мой ответ, чтобы отредактировать его, а также, если хотите (я собираюсь удалить мой, так как ваши покрытия лучше все равно) ... – ircmaxell

0

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

У вас нет: я могу только догадываться, что вы не с использованием прототипов. Прототипы будут «правильным» шаблоном проектирования для «объектно-ориентированного» JavaScript.

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

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

+0

Я использую прототипы. Я не добавляю эти методы, специфичные для клиента, в прототип, потому что существует большое количество клиентов, каждый из которых имеет свой собственный метод или два, которые необходимо добавить и не нужно видеть другим клиентам. Кроме того, я хочу разрешить неизвестным клиентам (т. Е. Людям, использующим мою библиотеку) вводить свои собственные функции. –

2

Должен признать, что шаблоны не являются моей «вещью», но вы можете делать именно то, что хотите в javascript. Именно так все структуры выполняют такие вещи, «расширяя» дочерние «классы» (в javascript нет классов).

Если вы в чистом яваскрипта мире, вы хотите использовать:

foo.prototype.bar = function() {}; 

Таким образом, вы можете позвонить bar на любой foo и bar существует только в памяти один раз - это та же функция ссылается память через каждый foo объект.Поэтому будьте осторожны с любыми переменными, на которые вы можете ссылаться вне этой области.

Каждая библиотека имеет свою собственную архитектуру плагинов для выполнения примерно той же цели (и они заботятся о некоторых из беспорядочности/опасности в прототипе)

0

Как hvgotcodes говорит, вы описываете стратегии паттерна, вы бы сделали это для своего конкретного случая, не использовать прототипы (тем самым затрагивая все объекты вашего класса.)

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

например.

function MyClass() { 
    this.myFunction = defaultFunction; 

    this.defaultFunction = function() { 
     // do something by default. 
     alert("using default"); 
    } 

    this.doFunction = function() { 
     // something that calls myFunction. 
     this.myFunction(); 
    } 
} 

---8< snip -------- 

// later on... 

t = new MyClass(); 
t.doFunction(); // output 'using default' 
t.myFunction = function(){ 
    // do something specific with this instance, when myFunction is called. 
    alert("customized for this instance."); 
} 
t.doFunction(); // output 'customized for this instance.' 
Смежные вопросы