2009-08-27 4 views
7

Also gibt es die Regel "Do One Thing" in dem Buch "Clean Code". Aber wie weit müssen wir das wirklich nehmen?Do One Thing - Wie weit soll man diese Regel nehmen?

Zum Beispiel die folgenden Aussagen:

Settings.Default.BaudRate = baudRate; 
Settings.Default.COMPort = port; 
Settings.Default.DataBits = dataBits; 
Settings.Default.Handshake = handshake; 
Settings.Default.Parity = parity; 
Settings.Default.ReadTimeout = readTimeout; 
Settings.Default.WriteTimeout = writeTimeout; 
Settings.Default.CommunicationTimeout = communicationTimeout; 
Settings.Default.Save(); 

Ok, sicher, dass es hier mehr als eine Anweisung ist, aber es mir nicht glauben, wie sie gerade sind, eine Sache zu tun. Speichern der Einstellungen.

Ich habe dies in einer einzigen Funktion. Würdest du dieses Appart wirklich nehmen und eine einzelne Methode für jede Einstellung haben?

Wann halten Sie sich an diese Regel und wann nicht?

+1

Wenn diese Eigenschaften, dann im Wesentlichen eine andere Methode für jeden von denen haben, nicht wahr? Ich bin kein C# Typ, aber diese sehen wie Requisiten aus. –

+0

Vielen Dank für Ihre Antworten :-) – TimothyP

Antwort

18

Sieht perfekt für mich. Der naheliegende Methodenname für diesen Code ist SaveSettings, was anzeigt, dass die Methode genau eine Sache macht. Nichts, über das man sich sorgen sollte.

+0

oder saveSettings abhängig vom Codierungsstil. Diese Antwort ist perfekt. – wlashell

+0

Ja, es macht *** eine Sache: Speichern Sie die Einstellungen. Keine Sorge ... – awe

6

Ich würde sie alle in einer einzigen SaveSettings() Funktion halten - wenn Sie sie jeweils in ihre eigene Funktion einfügen, müssten Sie alle diese Funktionen noch von einer anderen Funktion aufrufen.

4

Ich gehe davon aus, dass diese Regel verweist, wenn eine Funktion in mehrere Unterfunktionen aufgeteilt werden soll.

Sie haben die richtige Idee - Speichern von Einstellungen ist "eine Sache" und könnte in einer eigenen Funktion sein. Jede Einstellung in ihre eigene Funktion zu bringen, wäre übertrieben. Ein weiterer Leitfaden, den ich gehört habe, könnte Ihnen beim Verständnis des "One Thing" -Konzepts helfen: Wenn die Funktion länger als ein oder zwei Seiten ist, kann sie wahrscheinlich besser geschrieben werden, indem ihr Inhalt in mehrere Unterfunktionen unterteilt wird.

18

Der nächste Abschnitt des Buches, Eine Ebene der Abstraktion pro Funktion, geht einen langen Weg zur Beantwortung dieser Frage. Alle diese Anweisungen sind auf der gleichen Abstraktionsebene, also macht diese Funktion bereits eine Sache und speichert die Einstellungen.

+0

Noch müssen Sie zu diesem Teil: p – TimothyP

6

Ja, sollte jede Methode eine Sache nur tun. Aber was ist das eine Sache?

Dies ist abhängig von der Abstraktionsebene Ihre Methode ist in. Eine Methode (Eigenschaft) zum Speichern einer einzelnen Einstellung ist eine eher geringe Abstraktion. Die nächsthöhere Abstraktion wäre dann die vorgeschlagene SaveSettings Methode.

Ganz oben haben Sie eine einzelne Methode/Funktion main, die auch nur eine Sache tut: das ganze Programm ...

2

Auf unserem Team versuchen wir, die einen Zweck für jede Funktion Leitlinie zu folgen. Um Entwicklern zu helfen, fügten wir unseren Standards einen Vorschlag hinzu, den sie in Betracht ziehen, wenn eine Funktion 25 Zeilen überschreitet. Wenn Sie also über 100 Zeilen Codeeigenschaften verfügen, können Sie diese nach Kategorien wie SaveUserSettings, SaveNetworkSettings usw. aufteilen.

Das Endziel ist, den Code lesbarer zu machen. Wenn Sie Ihre Methode nehmen und sie in 20 Aufrufe aufteilen, die jeweils eine Eigenschaft festlegen, würde ich denken, dass es zeitaufwendiger wäre, sie zu befolgen und zu unterstützen.

4

Wenn Sie Ihren Code isoliert betrachten, ist es schwer zu sagen.Sie könnten argumentieren, dass Ihre Funktion zwei Dinge tut - Aktualisieren der Einstellungen und Speichern der Änderungen. Wie bevölkern Sie die Werte, werden sie als Argumente an Ihre Funktion übergeben (bevorzugt) oder erhält Ihre Funktion die Werte selbst (macht etwas anderes)?

würde ich die Single Responsibility Principle folgen, die zusammengefasst als:

Es soll nie mehr als ein Grund für eine Klasse

und kann ebenso auf Verfahren angewandt werden, ändern. In Ihrem Beispiel würde es immer einen Grund geben, die Einstellungen zu aktualisieren, aber nicht zu speichern?

+0

Nicht wirklich. Ich würde sie nie aktualisieren, es sei denn, ich muss sie speichern – TimothyP

1

Der Beispielcode würde besser mit der Frage umgehen, wann Eigenschaften verwendet werden sollen und wann Parameter in einem Konstruktor oder einer Methode zum Festlegen des Objektstatus verwendet werden sollen. Ich weiß, dass es einen Abschnitt dazu in der .NET framework guidelines gibt, wo es das Komponentenbasismuster (viele Eigenschaften und der innere Zustand der Komponenten kann zwischen der ersten und letzten Zuweisung ungültig sein) gegen das andere Muster (viele Konstruktorparameter und Methodenparameter) diskutiert und die Objekte interne Zustand gilt nach jeder Zeile Code ausführt.

+0

Ich werde das untersuchen – TimothyP

4

ich habe nicht, dass bestimmtes Buch lesen, aber wie das Konzept ...

„Eins“ bedeutet nicht „eine Zeile Code "." Eine Sache "bedeutet, dass alles in der Funktion logisch in Verbindung gebracht werden sollte.

Ich würde mit einigen der vorhergehenden Plakate sagen, dass" saveSetti ngs "ist" eine Sache ". Vielleicht ist es nur eine Nachlässigkeit mit Worten, aber ich werde die Gelegenheit nutzen, um auf die potenzielle Falle hinzuweisen. In Ihrem Fall ist es eher "saveCommunicationSettings", was meiner Meinung nach leicht zur "one thing" Definition passt. Wenn Sie "Settings.Default.customerLoyaltyDiscount = ..." zu dieser Liste hinzugefügt haben, würde ich sagen, dass Sie sich wahrscheinlich auf einer gefährlichen Basis befinden, da Sie jetzt Kommunikationseinstellungen mit Preisberechnungseinstellungen mischen.

Im wirklichen Leben ist die Entscheidung, was vernünftiger Zusammenhalt ist, keine Formel, sondern ein Urteilsspruch, der die Ausübung von Intelligenz erfordert. Sollte eine Funktion, die den Gesamtbetrag eines Auftrags berechnet, eine Umsatzsteuerberechnung enthalten? Das sind zwei Dinge: der Gesamtpreis aller Artikel auf Bestellung UND die Mehrwertsteuer berechnen. Man könnte aber auch argumentieren, dass es nur eines ist: Finde den Gesamtpreis des Auftrags, was auch immer das beinhaltet. In der Praxis treffe ich die Entscheidung oft aufgrund der Komplexität der Logik. Wenn alles, was erforderlich ist, um eine Auftragssumme zu berechnen, eine einfache Schleife durch alle Elemente ist, die ihre Preise addieren und dann eine Umsatzsteuersatz aus einer Tabelle holen und multiplizieren, würde ich wahrscheinlich alles in einer Funktion tun. Wenn es mehr als das gibt - wie das System, an dem ich gerade arbeite, beinhaltet die Preisberechnung die Bestellung von Lagerbeständen im Vergleich zu Sonderbestellungen, die Suche nach möglichen Rabatten, das Hinzufügen von Garantien usw. - wir müssen es wirklich brechen oben.

0

Wenn Sie Ihre Methode aufteilen wollten, würde ich das Abbilden von Werten aus dem tatsächlichen Speichern des Objekts abbrechen. Man könnte sagen, dass das Mapping von Werten eine separate Abstraktionsebene ist. So würden Sie haben:

public void save(){ 
    mapSettings(); 
    Settings.Default.Save(); 
} 

private void mapSettings(){ 
    Settings.Default.BaudRate = baudRate; 
    Settings.Default.COMPort = port; 
    Settings.Default.DataBits = dataBits; 
    Settings.Default.Handshake = handshake; 
    Settings.Default.Parity = parity; 
    Settings.Default.ReadTimeout = readTimeout; 
    Settings.Default.WriteTimeout = writeTimeout; 
    Settings.Default.CommunicationTimeout = communicationTimeout; 
} 

Es scheint, wie die Abbildung woanders wiederverwendet bekommen könnte oder Sie könnten wollen. Wenn die Zahleneinstellungen größer wurden, konnten sie auch weiter nach Kategorie aufgeschlüsselt werden.

In Fällen wie diesem würde ich nicht behaupten, dass es das wert ist, und ob ich es tat, würde von meiner Stimmung oder der Menge der Wolken am Himmel abhängen. Aber ja, technisch gesehen gibt es hier zwei Ebenen, die man aufteilen könnte.

0

Wie kann man wissen, ob eine Funktion eine Sache oder mehr macht? es hängt vom Grad der Abstraktionen ab. Ich versuche, im Schlepptau Beispielen (clean Codebuch, Kapitel 3) Abstraktionsebene zu beschreiben, diesen Code sehe

public function buildPage() { 
    $page = header(); 
    $page .= body(); 
    $page .= footer(); 
    return $page; 
} 

diese Funktion nur, dass eine Sache, und alle Unterfunktionen Teil der buildPage Phrase sind

public function sendMail() { 
    $user = $this->getUser(); 
    $this->mailer->content("send this message!") 
     ->to($user->email)->send(); 
} 

Diese Funktion benötigt eine Benutzer-E-Mail, daher kann sendMail mit Hilfe der getUser-Funktion den Benutzer per E-Mail erreichen. aber $ user = getUser() nicht in sendmail Phrase best practice für diese Funktion beschrieben ist

public function sendMail($email,$message) { 
    $this->mailer->content($message)->to($email)->send(); 
} 
Verwandte Themen