Một chút kiến thức về miền
Tôi đang viết phần mềm POS (Điểm bán hàng) cho phép thanh toán hàng hóa hoặc hoàn tiền cho họ. Khi thanh toán hoặc hoàn trả, người ta cần chỉ định sử dụng chuyển tiền nào : tiền mặt, EFT (~ = thẻ tín dụng), thẻ khách hàng thân thiết, chứng từ, v.v.
Các phương tiện chuyển tiền này là một tập hợp các giá trị hữu hạn và đã biết (một loại enum).
Phần khó khăn là tôi cần có khả năng lưu trữ một tập hợp con tùy chỉnh của các phương tiện này cho cả thanh toán và hoàn tiền (hai bộ có thể khác nhau) trên thiết bị đầu cuối POS.
Ví dụ:
- Có sẵn phương tiện thanh toán: Tiền mặt, EFT, Thẻ khách hàng thân thiết, Phiếu mua hàng
- Hoàn trả có nghĩa là: Tiền mặt, Phiếu quà tặng
Hiện trạng thực hiện
Tôi chọn thực hiện khái niệm chuyển tiền có nghĩa như sau:
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...
}
Lý do nó không phải là "enum đơn giản" là có tồn tại một số hành vi bên trong các lớp này. Tôi cũng đã phải khai báo các lớp bên trong công khai (thay vì riêng tư) để tham chiếu chúng trong ánh xạ FluentNHibernate (xem bên dưới).
Nó được sử dụng như thế nào
Cả phương tiện thanh toán và hoàn trả luôn được lưu trữ hoặc truy xuất trong / từ DB dưới dạng tập hợp. Chúng thực sự là hai bộ riêng biệt mặc dù một số giá trị bên trong cả hai bộ có thể giống nhau.
Trường hợp sử dụng 1: xác định một nhóm phương tiện thanh toán / hoàn trả mới
- Xóa tất cả các phương tiện thanh toán / hoàn trả hiện có
- Chèn cái mới
Trường hợp sử dụng 2: lấy tất cả các phương tiện thanh toán / hoàn trả
- Nhận một bộ sưu tập của tất cả các phương tiện thanh toán / hoàn trả được lưu trữ
Vấn đề
Tôi bị mắc kẹt với thiết kế hiện tại của tôi trên khía cạnh kiên trì. Tôi đang sử dụng NHibernate (với FluentNHibernate để khai báo các bản đồ lớp) và tôi không thể tìm cách ánh xạ nó tới một lược đồ DB hợp lệ.
Tôi thấy rằng có thể ánh xạ một lớp nhiều lần bằng tên thực thể tuy nhiên tôi không chắc chắn rằng nó có thể với các lớp con.
Điều tôi chưa sẵn sàng làm là thay đổi API công khai MoneyTransferMean để có thể duy trì nó (ví dụ: thêm một bool isRefund
để phân biệt giữa hai). Tuy nhiên, thêm một số lĩnh vực phân biệt đối xử tư nhân hoặc như vậy là ok.
Bản đồ hiện tại của tôi:
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...
Ánh xạ này biên dịch tuy nhiên nó chỉ tạo ra 1 bảng và tôi không thể phân biệt giữa thanh toán / hoàn tiền khi truy vấn bảng này.
Tôi đã cố gắng khai báo hai ánh xạ tham chiếu cả hai MoneyTransferMean
với tên bảng và tên thực thể khác nhau tuy nhiên điều này dẫn tôi đến một ngoại lệ Duplicate class/entity mapping MoneyTransferMean+CashMoneyTransferMean
.
Tôi cũng đã cố gắng sao chép ánh xạ lớp con nhưng tôi không thể chỉ định "ánh xạ cha" dẫn tôi đến ngoại lệ giống như trên.
Câu hỏi
Có một giải pháp tồn tại để duy trì các thực thể miền hiện tại của tôi?
Nếu không, công cụ tái cấu trúc nhỏ nhất tôi cần thực hiện trên các thực thể của mình để làm cho chúng bền bỉ với NHibnernate là gì?
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).
: Tại sao không? Đó là thay đổi đơn giản và ngọt ngào sẽ giải quyết vấn đề của bạn. Bạn có thể tạo nên với ba giá trị có thể (mặc dù hai cũng sẽ làm gì với hồ sơ trùng lặp hoặcFlag
loại):Payment
,Refund
,Both
. Nếu hai giá trị làm cho bạn,bool
tài sản là tuyệt vời.