アカウント
関連する会計エントリをまとめて、集計動作を提供する

2005年1月22日
これは、2000年代半ばに執筆していた「Further Enterprise Application Architecture development(エンタープライズアプリケーションアーキテクチャ開発のさらなる発展)」の一部です。残念ながら、それ以来、他の多くのことが私の注意を引いてしまい、それらをさらに進める時間がありませんでしたし、近い将来にも時間が見込めません。そのため、この資料は非常に草稿の状態であり、再び作業する時間を見つけるまで、修正や更新は行いません。
アカウントは長い間存在しています。個人銀行口座、プロジェクト費用口座、企業の勘定科目表など、会計に関連するほとんどの問題で発生します。
アカウントとは何かを考えるには、さまざまな方法があります。良い方法は、それらをエントリのコンテナ(会計エントリ)と考えることです。エントリを作成するたびに、それをアカウントに入れます。ただし、アカウントは単なるコンテナではなく、残高などの概要情報を提供する動作も備えています。
アカウントは、ある値の監査ログ、つまり現在の値だけでなく過去の任意の時点での値を知ることができ、その値に発生した個々の変更を知りたい場合に使用する量と考えることもできます。
アカウントを考える3つ目の方法は、エントリの種類を記述するエントリのすべての要素を結び付ける方法です。これにより、エントリとその記述子の間に間接的なステップが提供されます。これを使用すると、類似した特性を持つすべてのエントリをより簡単にまとめることができます。

図1:アカウントは、エントリとその記述子の間の間接的なレベルとして機能できます
アカウントについて考えるとき、通常は金銭的なアカウントを考えます。しかし、アカウントは金銭以上のものに使用できます。冷蔵庫にブラックビュートのボトルが24本ある場合、それをアカウントと考えることができます。シンディと私がローガンジョシュと一緒に飲むためにボトルを2本取り出すとき、それを2本のボトルの引き出しと考えることができます。私は冷蔵庫に会計システムを使用するつもりはありませんが、倉庫のネットワークがある場合は、そのようなモデルが非常に理にかなっています。
仕組み
アカウントパターンには、エントリのコレクションを保持することと、それらのエントリに関する集計情報を提供することの2つの本質的な性質があります。
通常、大量のエントリを取得するため、残高の計算方法を最適化する必要があることがよくあります。最適化手法は、アカウントからどのような情報が必要かによって異なります。たとえば、現在の残高が必要になることが多い場合は、現在の値をフィールドにキャッシュし、エントリを使用して逆算して過去の残高を取得できます。
エントリは通常、アカウントの開設までさかのぼります。ただし、エントリが多すぎて詳細を知る必要がなくなった場合は、エントリの塊を、値が削除されたエントリの残高である単一の統合エントリに置き換えることができます。これにより、統合後の日付の残高は維持されますが、概要エントリに含まれる情報を取得できなくなります。ただし、このエントリは、詳細エントリのプロキシとして使用できます。
通常、アカウント内のすべてのエントリが同じ通貨であると想定します。そのため、通常、特定の通貨を念頭に置いてアカウントが作成されます。最初のエントリが与えられたときに通貨を動的に選択するアカウントを作成することは可能ですが、空のアカウントの処理方法の面倒な動作は、その労力に見合う価値がないことを意味します。
アカウントで異なる通貨のエントリを保持できるようにする場合は、集計計算にマネーバッグを使用する必要があります。
一般的に見られる集計動作は、特定の日付または期間の残高、引き出し、預金を取得することです。
いつ使うか
私は、いくつかの異なる状況でアカウントを使用したいという衝動を感じることがあります。
1つ目は、現在の値、過去の値、およびその値への変更履歴を保持する必要がある値がある場合です。現在の値のみが必要な場合は、フィールドを使用するだけで済みます。現在と過去の値のみが必要な場合は、時間依存プロパティを使用できます。ただし、アカウントが時間依存プロパティよりも複雑であるとは思いません。
2つ目のケースは、すでに会計エントリ(15)を使用していますが、共通の記述子のセットのすべてのエントリをまとめたい場合です。これにより、同様のエントリを簡単に比較できます。
アカウントを使用するか、会計エントリを単独で使用するか迷うことがよくあります。転記ルールネットワーク(52)や差額調整(59)など、イベントベースのパターンの一部は、アカウントを使用すると、はるかに使いやすくなります。もう1つの要素は、ドメインエキスパートがドメインをどのように見ているかです。アカウントの観点から世界を考えている場合は、アカウントを使用するのが理にかなっています。そうでない場合は使用しないでください。
アカウントとバージョン管理システムのアイデアとの類似性を理解するのは難しくありません。実際、アカウントはバージョン管理のアイデアを金銭に適用していると考えることができます。ただし、アカウントを量的でない状況に使用できるという意味ではないと思います。コードバージョン管理を残高、引き出し、テキストファイルへの預金と考えることはできますが、私にとっては、それは類推を少し広げすぎていると思います。
例:簡単な例(Java)
アカウントの基本的な動作は実際には非常に簡単で、エントリ(会計エントリ)をまとめて集計情報を提供することで構成されます。エントリの収集は非常に簡単です。
class Account ... private Collection entries = new HashSet(); private Currency currency; void addEntry(Money amount, MfDate date){ Assert.equals(currency, amount.currency()); entries.add(new Entry(amount, date)); }
集計情報はそれほど複雑ではありません。
class Account... Money balance(DateRange period) { Money result = new Money (0, currency); Iterator it = entries.iterator(); while (it.hasNext()) { Entry each = (Entry) it.next(); if (period.includes(each.date())) result = result.add(each.amount()); } return result; } Money balance(MfDate date) { return balance(DateRange.upTo(date)); } Money balance() { return balance(MfDate.today()); }
多くの場合、時間の経過とともにアカウントに追加または削除された合計を判断するために、個別の動作を提供すると便利です。