Frage

Ich habe einige Event-Handler auf einer Grenz Klasse, die einen Persistenzmechanismus für eine bestimmte generische Transaktion verwaltet:

void MyBoundaryClass::MyEventHandler(...)
{
  //retrieve stuff from the UI
  //...
  //declare and initialize trasaction to persist
  SimpleTransaction myTransaction(.../*pass down stuff*/);
  //do some other checks
  //...
  //declare transaction persistor
  TransactionPersistor myPersistor(myTransaction, .../*pass down connection to DB and other stuff*/);
  //persist transaction
  try
  {
    myPersistor.Persist();
  }
  catch(...)
  {
    //handle errors
  }
}

Wäre es besser, eine Art von Transaction hat SimpleTransaction und TransactionPErsistor Objekte zu wickeln?

Gibt es eine nützliche Daumenregel zu verstehen, wenn ich eine weitere Ebene der Verkapselung müssen?

Im Moment ist die Faustregel gilt: I folgen wird „wenn das Verfahren zu groß wird - etwas dagegen tun“. Es ist manchmal schwierig, die richtige Balance zwischen prozeduralen und objektorientiert zu finden, wenn sie mit Rande Event-Handler zu tun.

Jede Meinung?

Prost

War es hilfreich?

Lösung

In Anbetracht, dass:

  • Konzept der Kapselung geht es um einen Behälter zu definieren, und
  • objektorientiertes Design auf dem Konzept der Nachricht basiert vorbei (Aufruf von Methoden)

Ich würde argumentieren, dass die API ist ein guter Indikator über die Stichhaltigkeit einer neuen High-Level-Verkapselung (das ist die Definition eines neuen Objekts)

Wenn die Dienste (das heißt die API) von diesem neuen Objekt angeboten kohärent sind, und sind besser für den Rest des Programms ausgesetzt, wenn sie in einem speziellen Objekt neu gruppiert, dann mit allen Mitteln, um ein neues Objekt zu verwenden.

Ansonsten ist es wahrscheinlich zuviel des Guten.

Da Sie belichten eine öffentlich API durch Erstellen eines neuen Objekts, den Begriff der Test kann einfacher sein, in diesem neuen Objekt zu tun ( und ein paar andere Mock Objekte), anstatt viele ältere Objekte zu erstellen, um die gleichen Operationen zu testen.

In Ihrem Fall, wenn Sie die Transaktion testen möchten, müssen Sie tatsächlich testen MyEventHandler von MyBoundaryClass, um Daten von der Benutzeroberfläche abgerufen werden.

Aber wenn Sie definieren einen Transactionmanager, die Ihnen die Möglichkeit auf Unter Kopplung verschiedener Architekturebenen (GUI vs. Daten) in MyBoundaryClass und exportieren Datenmanagement in eine eigene Klasse gibt. < br> Dann können Sie Datenpersistenz in unabhängigen Testszenarios testen, wobei der Schwerpunkt insbesondere auf Grenzwerte und Datenbankfehler und nicht-Nennbedingungen, und so weiter.

Testing Szenario kann Ihnen helfen, die Zusammenhalt (großer Punkt erwähnt von Daok ) Ihre verschiedenen Objekte. Wenn die Tests einfach und kohärent sind, stehen die Chancen, dass Ihre Objekte haben eine Dienstgrenze gut definieren.

Da es kann argumentiert werden, dass Kopplung und Kohäsion sind zwei Eckpfeiler der OO-Programmierung , der Zusammenhalt einer neuen Klasse wie Transaction kann in der Bezeichnung des Satzes von Aktionen ausgewertet wird, durchführen wird.

  

Cohesive bedeutet, dass eine bestimmte Klasse eine Reihe von eng verwandten Aktionen ausführt. Ein Mangel an Zusammenhalt, auf der anderen Seite bedeutet, dass eine Klasse mehr unabhängigen Aufgaben ausführt. [...] die Anwendungssoftware wird schließlich unkontrollierbar geworden, da immer mehr Verhaltensweisen zerstreuten werden und in falschen Stellen enden.

Wenn Sie Verhalten anders umgesetzt in mehreren verschiedenen Orten in Ihre Transaction umgruppieren, sollte es in Ordnung sein, vorausgesetzt, dass seine öffentliche API repräsentiert klare Schritte von dem, was eine Transaktion umfasst und nicht „Sachen über Transaktion“ wie verschiedene Utility-Funktionen. Ein Name an sich ist nicht genug, um den Zusammenhalt einer Klasse zu beurteilen. Die Kombination des Namens und seiner öffentlichen API benötigt.

Zum Beispiel eines interessanter Aspekt einer Transaction wäre völlig den Begriff der Transaktion zu verkapseln, das würde:

  • wird praktisch unkown vom Rest f dem System und würde Kopplung zwischen den anderen Klassen und ‚Transaktion‘
  • senken
  • verstärkt die Kohäsivität von Transaction durch seine API rund Schritte Transaktionszentrieren (wie initTransaction (), persistTransaction (), ...), jedes Getter oder Setter für jede Transaktionsinstanz zu vermeiden.

Andere Tipps

Ausarbeiten auf VonC Vorschlag, sollten Sie die folgenden Richtlinien:

  • Wenn Sie die gleichen Funktionen an anderer Stelle berufen erwarten, auf die gleiche Art und Weise, ist es sinnvoll, sie in einem neuen Objekt zu kapseln.

  • Wenn eine Funktion (oder ein Objekt) eine Reihe von Einrichtungen bereitstellt, die nützlich individuell sind, ist es sinnvoll sie in kleinere Komponenten Refactoring.

VonC der Punkt über die API ist ein ausgezeichneter Lackmus-Test:. Schaffen effektives Schnittstellen und die Objekte oft deutlich wurde

Die Höhe der Verkapselung sollte direkt an die Kohäsion verknüpft Ihr Objekt. Ihr Objekt muss eine einzelne Aufgabe tun oder muß in mehrere Klasse und kapselt alle seine Verhaltensweisen und Eigenschaften unterteilt werden.

Eine Daumenregel ist, wenn es Zeit, Ihr Objekt zu testen ist. Wenn Sie Unit Testing tun, und Sie erkennen, dass Sie mehrere andere Sache (nicht in der gleichen Gegend Aktion), als Sie könnten versuchen, testen sie aufzuteilen.

Für Sie Fall , würde ich mit Ihrer Idee von "Transaction" einkapseln. Auf diese Weise der „Transactionmanager“ wird handhaben, wie Transaktion arbeitet und nicht „MyBoundaryClass“.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top