Frage
In einigen aktuellen Projekten, dass ich teilnahm ich fast auf die folgenden Codierungsmuster süchtig war: (ich bin sicher nicht, wenn es ein richtiger Namen für diese, aber trotzdem ...)
Lassen Sie uns sagen, ein Objekt in irgendeiner bestimmten Zustand ist und wir wan't diesen Zustand von außen zu ändern. Diese Veränderungen könnten jedes Verhalten bedeuten könnte alle Algorithmen aufrufen, aber die Tatsache ist, dass sie sich auf das Ändern des Zustandes (Mitgliedstaat, Datenzustand, etc ...) von einem Gegenstand.
Und Nennen wir eine diskrete Art und Weise diejenigen Objekt eine Mutator
ändern. Mutators
angewandt werden, wenn (in der Regel) und sie haben einige internen Verfahren wie apply(Target& target, ...)
, die sofort den Zustand des Objekts provoziert zu ändern (in der Tat, sie sind eine Art funktioneller Objekte).
Sie könnten auch leicht in assimiliert werden Ketten und angewandte one-by-one (Mutator m1, m2, ...
); sie auch von einigen grundlegenden BasicMutator
mit virtual void apply(...)
Methode ableiten könnten.
Ich habe Klassen genannt InnerMutator
und ExplicitMutator
eingeführt, die in Bezug auf den Zugang unterscheiden - erste von ihnen auch die ändern können interne Zustand des Objekts und sollte als Freund (friend InnerMutator::access;
) deklariert werden.
In diesen Projekten meine Logik drehte die folgende Art und Weise zu arbeiten:
- verfügbar Mutatoren Bereiten Sie fest, welche anzuwenden
- Erstellen und die
object
bis zu einem gewissen bestimmten Zustand gesetzt -
foreach (mutator) mutator.apply(object);
Nun ist die Frage.
Dieses Schema turnes gut funktionieren und (für mich) scheint als eine Probe von einigen Nicht-Standard, aber nützliche Design Muster.
Was macht mich unwohl fühlen, ist, dass
InnerMutator
Zeug. Ich glaube nicht, denken erklärt Mutator ein Freund jeder Gegenstand, welcher Staat könnte verändert hat, ist eine gute Idee, und ich wan't zu findet die passende Alternative.Könnte diese Situation in Bezug auf
Mutators
gelöst werden oder könnten Sie einige alternative Muster Beratung mit das gleiche Ergebnis?
Danke.
Lösung
Ich hoffe, dies ist nicht offensiv genommen, aber ich kann nicht helfen, aber denke, dass dieses Design ist eine allzu ausgefallene Lösung für ein eher einfaches Problem.
Warum brauchen Sie Aggregat Mutatoren, zum Beispiel? Man kann nur schreiben:
template <class T>
void mutate(T& t)
{
t.mutate1(...);
t.mutate2(...);
t.mutate3(...);
}
Es ist Ihr Aggregat Mutator, nur ist es eine einfache Funktion Vorlage auf statischen Polymorphismus verlassen, anstatt eine kombinierte Liste von Mutatoren einen super-Mutator zu machen.
Ich habe einmal etwas, das ziemlich ähnlich gewesen sein könnte. Ich habe Funktionsobjekte, die durch Operator && in Superfunktionsobjekten kombiniert werden könnten, die beiden Operanden angewandt, so (in der Reihenfolge von links nach rechts), dass man Code schreiben könnte wie:
foreach(v.begin(), v.end(), attack && burn && drain);
Es war wirklich ordentlich und schien wirklich klug mir zu der Zeit und es war ziemlich effizient, weil es neue Funktionsobjekte on the fly generiert (keine Laufzeitmechanismen beteiligt sind), aber wenn meine Mitarbeiter sahen, dachten sie, ich war wahnsinnig. Im Nachhinein habe ich versucht zu stopfen alles in funktionalen Stil Programmierung, die ihren Nutzen hat, aber wahrscheinlich sollte nicht über verlassen in C ++. Es wäre leicht genug, um zu schreiben hat:
BOOST_FOR_EACH(Something& something, v)
{
attack(something);
burn(something);
drain(something);
}
Zugegeben ist es mehr Zeilen Code, aber es hat den Vorteil, zentralisierte und einfach zu debuggen und führt keine Fremdwörter zu anderen Menschen mit meinem Code arbeiten. Ich habe es viel günstiger, statt gefunden eher auf enge Logik zu konzentrieren, als zu versuchen Codezeilen mit Gewalt zu reduzieren.
Ich empfehle Ihnen, denken tief über diese und wirklich überlegen, ob es lohnt sich mit diesem Mutator-basierten Design fortzusetzen, egal wie klug und fest ist. Wenn andere Leute es nicht schnell verstehen können, es sei denn, Sie die Autorität der Boost-Autoren haben, es wird schwer sein, die Menschen wie sie zu überzeugen.
Wie bei InnerMutator, ich glaube, Sie es wie die Pest meiden sollte. Mit externen Mutator-Klassen, die eine Klasse Interna als direkt ändern können, wie sie können hier viele Zwecke der besiegt Einbauten überhaupt hat.
Andere Tipps
Wäre es besser, nicht zu einfach diejenigen Mutator
s Methoden der Klassen machen sie zu ändern? Wenn es gemeinsame Funktionen, die Sie mehrere Klassen wollen, dann haben, warum sie nicht von der gleichen Basisklasse erben machen? Dadurch wird mit allen inneren Mutator Beschwerden befassen könnte ich mir vorstellen.
Wenn Sie die Warteschlange Änderungen wollen, um sie als Sätze von Funktionsaufrufen an die Methoden innerhalb der Klassen speichern können.