Вопрос

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

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

И давайте назовем один дискретный способ изменения этих объектов Mutator. Mutators применяются один раз (в общем) и у них есть внутренний метод, как apply(Target& target, ...), что мгновенно провоцирует изменение состояния объекта (На самом деле, они какие-то функциональные объекты).

Они также могут быть легко ассимилированы в цепочки и применил один за другим (Mutator m1, m2, ...); Они также могут получить из некоторых основных BasicMutator с участием virtual void apply(...) метод.

Я ввел классы под названием InnerMutator а также ExplicitMutator которые отличаются с точки зрения доступа - первая из них также может изменить внутреннее состояние объекта и должен быть объявлен как друг (friend InnerMutator::access;).


В этих проектах моя логика повернулась на работу следующим образом:

  1. Подготовьте доступные мутаторы, выберите, что для применения
  2. Создать и установить object к определенному определенному состоянию
  3. foreach (mutator) mutator.apply(object);

Теперь вопрос.

Эта схема становится хорошо работать и (мне) Кажется, как образец некоторых нестандартных, но полезных конструкторов.

Что заставляет меня чувствовать себя некомфортно, это то, что InnerMutator вещи. Я не думаю, что объявление мутатора друга каждому объекту, которое может быть изменено, - это хорошая идея, и я не хочу найти соответствующую альтернативу.

Может ли эта ситуация была решена с точки зрения Mutators Или вы могли бы совет какой-то альтернативный шаблон с тем же результатом?

Спасибо.

Это было полезно?

Решение

Я надеюсь, что это не будет предприниматься в недонзен, но я не могу не думать, что этот дизайн является чрезмерно необычным решением для довольно простой проблемы.

Почему нужно, например, для агрегирования мутаторов? Можно просто написать:

template <class T>
void mutate(T& t)
{
    t.mutate1(...);
    t.mutate2(...);
    t.mutate3(...);
}

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

Я когда-то сделал то, что могло бы быть довольно похожим. Я сделал функциональные объекты, которые могут быть объединены оператором && в супер функциональные объекты, которые применяли обе операнды (в порядке слева направо), чтобы можно было написать код как:

foreach(v.begin(), v.end(), attack && burn && drain);

Это было действительно аккуратно и казалось, очень умным для меня в то время, и это было довольно эффективно, потому что оно сгенерировало новые функции объекты на лету (никаких вовлеченных механизмов времени выполнения), но когда мои сотрудники увидели это, они думали, что я безумной. При ретроспективе я пытался все покрасить в программирование функционального стиля, которое имеет его полезность, но, вероятно, не должно быть переложена на C ++. Было бы легко было бы легко написать:

BOOST_FOR_EACH(Something& something, v)
{
    attack(something);
    burn(something);
    drain(something);
}

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

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

Что касается Innermutator, я думаю, что вы должны избежать этого, как чума. Наличие классов внешних мутаторов, которые могут изменить внутренние органы класса, так как можно напрямую, так как они могут, поражены многими целями наличия внутренних органов.

Другие советы

Было бы лучше просто сделать тех MutatorS Методы классов, которые они меняются? Если есть общая функциональность, вы хотите, чтобы несколько классов имели, тогда почему бы не заставить их наследовать из того же базового класса? Делая это будет иметь дело со всем внутренним мутатором, которым я мог себе представить.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top