Um eine bedingte Verzweigung (if) zu schreiben, können wir verschiedene Techniken für die frühe Rückkehr sehen, die die Verschachtelung nicht vertiefen. Persönlich denke ich nicht, dass alles mit vorzeitiger Rückgabe geschrieben und je nach Situation verwendet werden sollte. Darüber hinaus hat mich dieser Artikel dazu inspiriert, einen Artikel zu schreiben. Insbesondere der Kommentarbereich war eine Lernerfahrung.
Ich habe die Richtlinie, dass vorzeitige Rückgaben nur zur Fehlerbehandlung verwendet werden sollten und die Geschäftslogik unter bestimmten Bedingungen sicher geschrieben werden sollte. Dieser Punkt wird im folgenden Beispielcode erläutert.
Betrachten Sie als einfaches Beispiel die Berechnungslogik des Zahlungspreises unter Berücksichtigung der Verbrauchssteuer und des Abzinsungssatzes. Die Verbrauchsteuer ist der Preis ohne Verbrauchssteuer, wenn bestimmte Bedingungen erfüllt sind. Wenn der Abzinsungssatz auch bestimmte Bedingungen erfüllt, wird er nach Berücksichtigung der Verbrauchsteuer um 1 vom Preis abgezinst. Der Einfachheit halber werden wir nicht näher auf das Vorhandensein oder Nichtvorhandensein von Verbrauchssteuern und die Bedingungen für die Anwendung von Rabatten eingehen, sondern diese mit einem Flag versehen, das angibt, ob sie angewendet werden können oder nicht.
//Berechnen Sie den vom Kunden gezahlten Betrag
public decimal CalculatePaymentPrice(decimal price, bool canRemoveTax, bool canDiscount)
{
if (price < 0)
{
throw new ArgumentOutOfRangeException("Bitte geben Sie einen Wert von 0 oder mehr für den Produktpreis ein.");
}
else if (canRemoveTax)
{
//Rabatt ohne Verbrauchssteuer
if (canDiscount)
{
return price * 0.9m;
}
else
{
return price;
}
}
else
{
//Rabatt mit Verbrauchsteuer angewendet
if (canDiscount)
{
return price * 1.08m * 0.9m;
}
else
{
return price * 1.08m;
}
}
}
//Berechnen Sie den vom Kunden gezahlten Betrag
public BigDecimal CalculatePaymentPrice(BigDecimal price, boolean canRemoveTax, boolean canDiscount) {
if (price.compareTo(BigDecimal.ZERO) < 0) {
throw new IllegalArgumentException("Bitte geben Sie einen Wert von 0 oder mehr für den Produktpreis ein.");
} else if (canRemoveTax) {
//Rabatt ohne Verbrauchssteuer
if (canDiscount) {
return price.multiply(new BigDecimal("0.9"));
} else {
return price;
}
} else {
//Rabatt mit Verbrauchsteuer angewendet
if (canDiscount) {
return price.multiply(new BigDecimal("1.08")).multiply(new BigDecimal("0.9"));
} else {
return price.multiply(new BigDecimal("1.08"));
}
}
}
2018/05/01 Nachtrag Wie Sie im Kommentarbereich sehen können, wird eine Ausnahme ausgelöst, obwohl es sich um einen Geschäftsfehler handelt. Normalerweise sollten Sie keine Ausnahme für Geschäftsfehler auslösen. Dies ist aufgrund der Vereinfachung des Beispielcodes ein schädlicher Effekt und unterliegt keinem Refactoring. Was ich in diesem Beispiel sagen wollte, ist, dass ich keine Geschäftsfehler in die Logik einfügen möchte, daher ist es in Ordnung, sie frühzeitig zu beseitigen.
In der Realität besteht ein Refactoring-Plan darin, den Preisprüfungsprozess im Voraus durchzuführen und nach dem Bestehen der Prüfung die CalculatePaymentPrice-Methode aufzurufen.
public decimal CalculatePaymentPriceAfterRefactoring(decimal price, bool canRemoveTax, bool canDiscount)
{
//Fehlervermeidung
if (price < 0)
{
throw new ArgumentOutOfRangeException("Bitte geben Sie einen Wert von 0 oder mehr für den Produktpreis ein.");
}
//Verbrauchsteuersatz festgelegt
decimal taxRate;
if (canRemoveTax)
{
taxRate = 0m;
}
else
{
taxRate = 0.08m;
}
//Diskontsatz bestätigt
decimal discountRate;
if (canDiscount)
{
discountRate = 0.9m;
}
else
{
discountRate = 1.0m;
}
//Zahlungspreis berechnen
return price * (1m + taxRate) * discountRate;
}
public BigDecimal CalculatePaymentPriceAfterRefactoring(BigDecimal price, boolean canRemoveTax,
boolean canDiscount) {
//Fehlervermeidung
if (price.compareTo(BigDecimal.ZERO) < 0) {
throw new IllegalArgumentException("Bitte geben Sie einen Wert von 0 oder mehr für den Produktpreis ein.");
}
//Erwerb des Verbrauchsteuersatzes
BigDecimal taxRate;
if (canRemoveTax) {
taxRate = BigDecimal.ZERO;
} else {
taxRate = new BigDecimal("0.08");
}
//Rabatt erhalten
BigDecimal discountRate;
if (canDiscount) {
discountRate = new BigDecimal("0.9");
} else {
discountRate = BigDecimal.ONE;
}
//Zahlungspreis berechnen
return price.multiply(taxRate.add(BigDecimal.ONE)).multiply(discountRate);
}
Durch Ändern des Verarbeitungsablaufs des Zahlungspreisberechnungsteils kann jede Verarbeitung getrennt werden. Wenn Sie sich Sorgen über die temporären Variablen taxRate und discountRate machen, können Sie den Teil der Festlegung des Verbrauchsteuersatzes und des festen Abzinsungssatzes zu einer Methode machen. Gibt es in Bezug auf die Fehlerbehandlung kein Problem als Implementierungsrichtlinie, wenn Sie eine frühzeitige Rückgabe anwenden und die andere Geschäftslogik sicher unter umfassenden Bedingungen schreiben? Schließlich wagte ich es, mit einer vorzeitigen Rückgabe über die endgültige Verbrauchsteuer zu schreiben.
Dieser Code ist prägnant, aber wenn Sie ihn in if-else schreiben, können Sie die Zustandsabdeckung überprüfen und sich wohl fühlen. Auf der anderen Seite sagen viele Leute, dass der Code zu kurz ist und einer von beiden in Ordnung ist. .. ..
private decimal GetTaxRate(bool canRemoveTax)
{
if (canRemoveTax)
{
return 0m;
}
return 0.08m;
}