Beiträge
Die geheime Zutat kodifizieren
16. September 2019 • 5 min Lesezeit
Jede Anwendung hat ihre geheime Zutat, ihren Grund für die Existenz. Die geheime Zutat zu kodifizieren ist entscheidend für das Schreiben wartbarer und erfolgreicher Anwendungen.
Moment. Was bedeutet kodifizieren? Geduld mein Freund, wir werden dort ankommen.
Zunächst lassen Sie uns eine Hypothese aufstellen:
Sie wurden gerade zum Lead Software Engineer befördert (Glückwunsch!). Die erste Aufgabe Ihres CEO ist die Erstellung eines neuen Produkts für das Unternehmen. Es ist eine Buchhaltungsanwendung von Grund auf. Die Führungskräfte sind der Meinung, dass eine benutzerdefinierte Buchhaltungslösung ihnen einen Vorteil gegenüber der Konkurrenz verschafft.
Ein paar Monate sind vergangen, die meisten übergreifenden Belange sind entwickelt (hurra für Sie!). Das Team konzentriert sich nun auf die köstliche Essenz der Anwendung: die Geschäftsdomäne (die geheime Zutat). Hier beginnt die Kodifizierung der geheimen Zutat.
Kodifizieren bedeutet, Struktur um ein wesentliches Konzept in der Geschäftsdomäne zu schaffen.
In der Buchhaltung ist das Kurs-Gewinn-Verhältnis (KGV) eine Messung der Gewinne eines Unternehmens. Ein hohes KGV deutet auf zukünftiges Gewinnwachstum hin. Das KGV wird berechnet, indem der Marktwert pro Aktie (Aktienkurs) durch den Gewinn pro Aktie (Gewinn – Dividenden / Anzahl der ausstehenden Aktien) dividiert wird.
Eine einfache und, wie ich argumentieren würde, naive Implementierung:
public class Metric
{
public string Name { get; set; }
public decimal Value {get; set}
public int Order {get; set;}
}
public class AccountingSummary
{
public Metric[] GetMetrics(decimal price, decimal earnings)
{
var priceEarningsRatio = price/earnings;
var priceEarningsRatioMetric = new Metric
{
Name = "P/E Ratio",
Value = priceEarningsRatio,
Order = 0
}
return new [] {priceEarningsRatioMetric};
}
}
Wenn dies nur an einer Stelle verwendet wird, ist das in Ordnung. Was ist, wenn Sie das KGV an anderen Stellen verwenden?
Wie hier in PriceEarnings.cs
var priceEarningsRatio = price/earnings;
Und hier in AccountSummary.cs
var priceEarningsRatio = price/earnings;
Und hier drüben in StockSummary.cs
var priceEarningsRatio = price/earnings;
Das KGV ist zentral für diese Anwendung, aber die Art und Weise, wie es implementiert ist, hart codiert an verschiedenen Stellen, lässt die Bedeutung des KGV in einem Meer von Code verloren gehen. Es ist nur noch ein Baum im Wald.
Sie setzen sich auch dem Risiko aus, das Verhältnis an einer Stelle zu ändern, aber nicht an der anderen. Dies kann nachgelagerte Berechnungen durcheinander bringen. Diese Arten von Fehlern sind notorisch schwer zu finden.
Oft gehen Tester davon aus, dass wenn es in einem Bereich funktioniert, es in allen Bereichen korrekt ist. Warum würde die Anwendung nicht denselben Code verwenden, um das KGV für die gesamte Anwendung zu generieren? Ist das nicht der Sinn der objektorientierten Programmierung?
Ich kann mir vorstellen, dass ein solcher Fehler in die Produktion gelangt und erst bei einem Besuch Ihres Geschäftsführers entdeckt wird, der wissen möchte, warum die KGV-Berechnungen der SEC sich von dem unterscheiden, was das Unternehmen eingereicht hat. Das ist kein guter Ort, um sich zu befinden.
Lassen Sie uns unsere KGV-Implementierung erneut überprüfen und sehen, wie wir unseren ersten Versuch verbessern können.
In Buchhaltungssystemen sind Formeln eine Sache, lassen Sie uns Struktur um Formeln schaffen, indem wir eine Schnittstelle hinzufügen:
public interface IFormula
{
decimal Calculate<T>(T model);
}
Jede Formel wird nun mit dieser Schnittstelle implementiert, was uns Konsistenz und Vorhersagbarkeit gibt.
Hier ist unser verbessertes KGV nach der Implementierung unserer Schnittstelle:
Wir haben ein PriceEarningsModel hinzugefügt, um die erforderlichen Daten in unsere Calculate-Methode zu übergeben.
public class PriceEarningsModel
{
public decimal Price {get; set;}
public decimal Earnings {get; set;}
}
Mit unserem PriceEarningsModel haben wir eine Implementierung der IFormula-Schnittstelle für das KGV erstellt.
public class PriceEarningsRatioFormula : IFormula
{
public decimal Calculate<PriceEarningsModel>(PriceEarningsModel model)
{
return model.Price / model.Earnings;
}
}
Wir haben das KGV nun kodifiziert. Es ist ein erstklassiges Konzept in unserer Anwendung. Wir können es überall verwenden. Es ist testbar, und eine Änderung wirkt sich auf die gesamte Anwendung aus.
Zur Erinnerung, hier ist die Implementierung, mit der wir begonnen haben:
public class Metric
{
public string Name { get; set; }
public decimal Value {get; set}
public int Order {get; set;}
}
public class AccountingSummary
{
public Metric[] GetMetrics(decimal price, decimal earnings)
{
var priceEarningsRatio = price/earnings;
var priceEarningsRatioMetric = new Metric
{
Name = "P/E Ratio",
Value = priceEarningsRatio,
Order = 0
}
return new [] {priceEarningsRatioMetric};
}
}
Es ist einfach und erledigt die Aufgabe. Das Problem ist, dass das KGV, das ein Kernkonzept in unserer Buchhaltungsanwendung ist, nicht hervorsticht. Ingenieure, die mit der Anwendung oder der Geschäftsdomäne nicht vertraut sind, werden seine Bedeutung nicht verstehen.
Unsere verbesserte Implementierung verwendet unsere neue KGV-Klasse. Wir injizieren die PriceEarningsRatioFormula-Klasse in unsere AccountSummary-Klasse.
Wir ersetzen unser hart codiertes KGV durch unsere neue PriceEarningsRatioFormula-Klasse.
public class AccountingSummary
{
private PriceEarningsRatioFormula _peRatio;
public AccountingSummary(PriceEarningsRatioFormula peRatio)
{
_peRatio = peRatio;
}
public Metric[] GetMetrics(decimal price, decimal earnings)
{
var priceEarningsRatio = _peRatio.Calculate(new PriceEarningsModel
{
Price = price,
Earnings = earnings
});
var priceEarningsRatioMetric = new Metric
{
Name = "P/E Ratio",
Value = priceEarningsRatio,
Order = 0
}
return new [] {priceEarningsRatioMetric};
}
}
Man könnte argumentieren, dass die PriceEarningsRationFormula etwas mehr Aufwand erfordert als die vorherige Implementierung, und ich würde dem zustimmen. Es gibt etwas mehr Zeremonie, aber die Vorteile sind den kleinen Anstieg an Code und Zeremonie wert.
Erstens gewinnen wir die Möglichkeit, das KGV für die gesamte Anwendung zu ändern. Wir haben auch eine einzige Implementierung zum Debuggen, wenn Mängel auftreten.
Schließlich haben wir das Konzept der PriceEarningsRatioFormula in der Anwendung kodifiziert. Wenn ein neuer Ingenieur dem Team beitritt, wird er wissen, dass Formeln für die Anwendung und die Geschäftsdomäne wesentlich sind.
Es gibt andere Methoden zur Kodifizierung (Kapselung) der Domäne, wie z. B. Microservices und Assemblies. Jeder Ansatz hat seine Vor- und Nachteile, Sie und Ihr Team müssen entscheiden, was für Ihre Anwendung am besten ist.
Das Einbetten von Schlüsseldomänenkonzepten in Klassen und Schnittstellen schafft wiederverwendbare Komponenten und konzeptionelle Grenzen. Dies macht eine Anwendung leichter zu verstehen, reduziert Mängel und senkt die Hürden für das Onboarding neuer Ingenieure.
Autor: Chuck Conway ist ein KI-Ingenieur mit fast 30 Jahren Erfahrung in der Softwareentwicklung. Er entwickelt praktische KI-Systeme – Content-Pipelines, Infrastruktur-Agenten und Tools, die echte Probleme lösen – und teilt seine Erkenntnisse unterwegs. Verbinden Sie sich mit ihm in den sozialen Medien: X (@chuckconway) oder besuchen Sie ihn auf YouTube und auf SubStack.