ドメインに関する知識
商品の支払いや払い戻しを可能にするPOS(Point Of Sales)ソフトウェアを書いています。支払いまたは払い戻しの際、使用する送金方法を指定する必要があります:現金、銀行口座振込(〜=クレジットカード)、ポイントカード、バウチャーなど。
これらの送金手段は、有限で既知の値のセット(列挙型の一種)です。
トリッキーな部分は、支払いと払い戻しの両方(2つのセットは異なる場合があります)のためにこれらの手段のカスタムサブセットをPOS端末に保存できる必要があることです。
例えば:
- 利用可能な支払い手段:現金、EFT、ポイントカード、バウチャー
- 利用可能な払い戻し手段:現金、バウチャー
実施の現状
私は次のように送金手段の概念を実装することを選択します:
public abstract class MoneyTransferMean : AggregateRoot
{
public static readonly MoneyTransferMean Cash = new CashMoneyTransferMean();
public static readonly MoneyTransferMean EFT = new EFTMoneyTransferMean();
// and so on...
//abstract method
public class CashMoneyTransferMean : MoneyTransferMean
{
//impl of abstract method
}
public class EFTMoneyTransferMean : MoneyTransferMean
{
//impl of abstract method
}
//and so on...
}
「プレーン列挙」ではない理由は、これらのクラスの内部にいくつかの動作が存在するためです。また、FluentNHibernateマッピングで参照するために、内部クラスを(privateではなく)publicと宣言する必要がありました(下記参照)。
使い方
支払い手段と払い戻し手段の両方は、常にセットとしてDBに格納またはDBから取得されます。両方のセット内の一部の値が同じである場合でも、実際には2つの異なるセットです。
ユースケース1:支払い/払い戻し手段の新しいセットを定義する
- 既存の支払い/払い戻し手段をすべて削除します
- 新しいものを挿入する
ユースケース2:すべての支払い/払い戻し手段を取得する
- 保存されているすべての支払い/払い戻し手段のコレクションを取得します
問題
永続性の面で現在のデザインにこだわっています。NHibernate(クラスマップを宣言するためにFluentNHibernateを使用)を使用していますが、それを有効なDBスキーマにマップする方法が見つかりません。
entity-nameを使用してクラスを複数回マッピングすることが可能であることがわかりましたが、サブクラスでそれが可能かどうかはわかりません。
私がする準備ができていないのは、それを永続化できるようにMoneyTransferMeanパブリックAPIを変更することです(たとえばbool isRefund
、2つを区別するためにを追加します)。ただし、プライベート識別フィールドを追加してもかまいません。
私の現在のマッピング:
public sealed class MoneyTransferMeanMap : ClassMap<MoneyTransferMean>
{
public MoneyTransferMeanMap()
{
Id(Entity.Expressions<MoneyTransferMean>.Id);
DiscriminateSubClassesOnColumn("Type")
.Not.Nullable();
}
}
public sealed class CashMoneyTransferMeanMap : SubclassMap<MoneyTransferMean.CashMoneyTransferMean>
{
public CashMoneyTransferMeanMap()
{
DiscriminatorValue("Cash");
}
}
public sealed class EFTMoneyTransferMeanMap : SubclassMap<MoneyTransferMean.EFTMoneyTransferMean>
{
public EFTMoneyTransferMeanMap()
{
DiscriminatorValue("EFT");
}
}
//and so on...
このマッピングはコンパイルされますが、生成されるテーブルは1つだけであり、このテーブルを照会するときに支払いと払い戻しを区別できません。
MoneyTransferMean
異なるテーブルとエンティティ名の両方を参照する2つのマッピングを宣言しようとしましたが、これにより例外が発生しましたDuplicate class/entity mapping MoneyTransferMean+CashMoneyTransferMean
。
また、サブクラスマッピングを複製しようとしましたが、上記と同じ例外につながる「親マッピング」を指定できません。
質問
現在のドメインエンティティを永続化するソリューションはありますか
そうでない場合、NHibnernateで永続化できるようにエンティティで実行する必要がある最小のリファクタリングは何ですか?
What I'm not ready to do is to alter the MoneyTransferMean public API to be able to persist it (for example adding a bool isRefund to differentiate between the two).
: 何故なの?それはあなたの問題を解決するはずのシンプルで甘い変更です。(2はまた、重複するレコードまたはを行いますが、あなたが可能な3つの値で構成することができますFlag
タイプ): 、Payment
、。Refund
Both
2つの値が適切であれば、bool
プロパティは優れています。