
各アプリケーションには秘伝のソース、つまり存在理由があります。秘伝のソースをコード化することは、保守可能で成功するアプリケーションを書く上で重要です。
待ってください。コード化とは何でしょうか?我慢してください、そこに辿り着きます。
まず仮説を立ててみましょう:
あなたは主任ソフトウェアエンジニアに昇進したばかりです(おめでとうございます!)。CEOの最初の任務は、会社の新製品を作ることです。それは一から作る会計アプリケーションです。経営陣は、カスタム会計ソリューションを持つことで競合他社に対して優位に立てると感じています。
数ヶ月が経過し、横断的関心事のほとんどが開発されました(やったね!)。チームは今、アプリケーションの美味しい部分、つまりビジネスドメイン(秘伝のソース)に焦点を当てています。ここで秘伝のソースのコード化が始まります。
コード化とは、ビジネスドメインの本質的な概念に構造を与えることです。
会計において、株価収益率(P/E比)は企業の収益の測定値です。高いP/E比は将来の高い収益成長を示唆します。P/E比は、1株当たりの市場価値(株価)を1株当たりの収益(利益 - 配当 / 発行済株式数)で割って計算されます。
シンプルで、私が言うには素朴な実装:
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};
}
}
これが一箇所でのみ使用される場合、これで問題ありません。P/E比を他の領域で使用する場合はどうでしょうか?
PriceEarnings.csのここのように
var priceEarningsRatio = price/earnings;
そしてAccountSummary.csのここで
var priceEarningsRatio = price/earnings;
そしてこちらのStockSummary.csで
var priceEarningsRatio = price/earnings;
P/E比はこのアプリケーションの中核ですが、その実装方法、つまり様々な場所にハードコードされていることで、P/E比の重要性がコードの海の中で失われてしまいます。それは森の中のただの木になってしまいます。
また、一箇所で比率を変更しても他の箇所で変更しないリスクも生じます。これは下流の計算を狂わせる可能性があります。この種のエラーは見つけるのが非常に困難です。
多くの場合、テスターは一つの領域で動作すれば、すべての領域で正しいと仮定します。なぜアプリケーション全体でP/E比を生成するのに同じコードを使わないのでしょうか?これがオブジェクト指向プログラミングの要点ではないのでしょうか?
このようなエラーが本番環境に入り込み、SECのP/E比計算が会社が提出したものと異なる理由を知りたがる経営陣の訪問まで発見されないことを想像できます。それは良い状況ではありません。
P/E比の実装を見直して、最初の試みをどのように改善できるかを見てみましょう。
会計システムでは数式が重要なので、インターフェースを追加して数式に構造を与えましょう:
public interface IFormula
{
decimal Calculate<T>(T model);
}
各数式は今、このインターフェースで実装され、一貫性と予測可能性を提供します。
インターフェースを実装した後の改善されたP/E比は次のとおりです:
Calculateメソッドに必要なデータを渡すためにPriceEarningsModelを追加しました。
public class PriceEarningsModel
{
public decimal Price {get; set;}
public decimal Earnings {get; set;}
}
PriceEarningsModelを使用して、P/E比用のIFormulaインターフェースの実装を作成しました。
public class PriceEarningsRatioFormula : IFormula
{
public decimal Calculate<PriceEarningsModel>(PriceEarningsModel model)
{
return model.Price / model.Earnings;
}
}
これでP/E比をコード化しました。それはアプリケーションの第一級の概念です。どこでも使用でき、テスト可能で、変更はアプリケーション全体に影響します。
念のため、最初に始めた実装を思い出してください:
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};
}
}
これはシンプルで仕事を成し遂げます。問題は、会計アプリケーションの中核概念であるP/E比が目立たないことです。アプリケーションやビジネスドメインに馴染みのないエンジニアは、その重要性を理解できません。
改善された実装では、新しいP/E比クラスを使用します。PriceEarningsRatioFormulaクラスをAccountSummaryクラスに注入します。
ハードコードされたP/E比を新しいPriceEarningsRatioFormula
クラスに置き換えます。
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};
}
}
PriceEarningsRationFormulaは以前の実装よりも少し手間がかかると主張する人もいるでしょうし、私も同意します。少し儀式的ですが、利点はコードと儀式のわずかな増加に十分見合います。
まず、アプリケーション全体のP/E比を変更する能力を得ます。また、欠陥が発生した場合にデバッグする単一の実装があります。
最後に、アプリケーションでPriceEarningsRatioFormulaの概念をコード化しました。新しいエンジニアがチームに参加したとき、数式がアプリケーションとビジネスドメインにとって不可欠であることを知るでしょう。
マイクロサービスやアセンブリなど、ドメインをコード化(カプセル化)する他の方法があります。各アプローチには長所と短所があり、あなたとあなたのチームがアプリケーションにとって最適なものを決定する必要があります。
主要なドメイン概念をクラスとインターフェースに包含することで、再利用可能なコンポーネントと概念的境界を作成します。これにより、アプリケーションの推論が容易になり、欠陥が減り、新しいエンジニアのオンボーディングの障壁が低くなります。
著者:Chuck Conwayはソフトウェアエンジニアリングと生成AIを専門としています。ソーシャルメディアで彼とつながりましょう:X (@chuckconway) または YouTube をご覧ください。