ความรู้เกี่ยวกับโดเมน
ฉันกำลังเขียนซอฟต์แวร์ POS (จุดขาย) ที่อนุญาตให้ชำระค่าสินค้าหรือคืนเงินได้ เมื่อชำระเงินหรือคืนเงินหนึ่งต้องระบุการโอนเงินที่หมายถึงการใช้: เงินสด EFT (~ = บัตรเครดิต) บัตรสะสมคะแนนบัตรกำนัล ฯลฯ
การโอนเงินหมายถึงชุดค่าที่แน่นอนและเป็นที่รู้จัก (ชนิดของ enum)
ส่วนที่ยุ่งยากคือฉันต้องสามารถจัดเก็บชุดย่อยที่กำหนดเองของวิธีการเหล่านี้สำหรับการชำระเงินและการคืนเงิน (ทั้งสองชุดอาจแตกต่างกัน) ในเครื่อง 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...
}
สาเหตุที่ไม่ใช่ "enum ธรรมดา" ก็คือมีพฤติกรรมบางอย่างที่อยู่ในชั้นเรียนเหล่านี้ ฉันต้องประกาศคลาสในที่สาธารณะ (แทนส่วนตัว) เพื่ออ้างอิงในการแม็พ FluentNHibernate (ดูด้านล่าง)
วิธีการใช้งาน
ทั้งการชำระเงินและการคืนเงินหมายถึงการจัดเก็บหรือดึงข้อมูลใน / จากฐานข้อมูลเป็นชุดเสมอ พวกเขาเป็นชุดที่แตกต่างกันสองชุดแม้ว่าค่าบางอย่างในทั้งสองชุดอาจเหมือนกัน
ใช้กรณีที่ 1: กำหนดวิธีการชำระเงิน / คืนเงินชุดใหม่
- ลบวิธีการชำระเงิน / คืนเงินที่มีอยู่ทั้งหมด
- ใส่อันใหม่
ใช้กรณีที่ 2: เรียกวิธีการชำระเงิน / คืนเงินทั้งหมด
- รับชุดของการชำระเงิน / คืนเงินที่เก็บไว้ทั้งหมดหมายถึง
ปัญหา
ฉันติดอยู่กับการออกแบบปัจจุบันของฉันในด้านความเพียร ฉันใช้ NHibernate (กับ FluentNHibernate เพื่อประกาศแผนที่ชั้นเรียน) และฉันไม่สามารถหาวิธีทำแผนที่กับ DB schema ที่ถูกต้องได้
ฉันพบว่าเป็นไปได้ที่จะแมปคลาสหลาย ๆ ครั้งโดยใช้เอนทิตีชื่อแต่ฉันไม่แน่ใจว่ามันเป็นไปได้กับคลาสย่อย
สิ่งที่ฉันยังไม่พร้อมที่จะทำคือการเปลี่ยน MoneyTransferMean API สาธารณะเพื่อให้สามารถคงอยู่ได้ (ตัวอย่างเช่นการเพิ่ม a bool isRefund
เพื่อแยกความแตกต่างระหว่างสอง) อย่างไรก็ตามการเพิ่มฟิลด์ discriminator ส่วนตัวบางส่วนหรือดังนั้นก็โอเค
การทำแผนที่ปัจจุบันของฉัน:
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
มีโต๊ะที่แตกต่างกันและกิจการชื่อ Duplicate class/entity mapping MoneyTransferMean+CashMoneyTransferMean
แต่นำไปสู่การนี้ผมที่จะมีข้อยกเว้น
ฉันพยายามทำการแมปคลาสย่อยซ้ำ แต่ฉันไม่สามารถระบุ "การแมปหลัก" ซึ่งทำให้ฉันมีข้อยกเว้นเช่นเดียวกับข้างต้น
คำถาม
วิธีแก้ไขมีอยู่เพื่อคงอยู่ของโดเมนปัจจุบันของฉัน
ถ้าไม่ได้สิ่งที่เป็น refactor ที่เล็กที่สุดที่ฉันต้องดำเนินการกับหน่วยงานของฉันเพื่อให้พวกเขาคงอยู่กับ 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).
: ทำไมจะไม่ล่ะ? เป็นการเปลี่ยนแปลงที่ง่ายและหวานที่ควรแก้ปัญหาของคุณ คุณสามารถทำขึ้นมีค่าที่เป็นไปได้สาม (แม้ว่าทั้งสองยังจะทำอย่างไรกับระเบียนที่ซ้ำกันหรือFlag
พิมพ์):Payment
, ,Refund
Both
หากมีสองค่าที่เหมาะกับคุณbool
คุณสมบัติก็ยอดเยี่ยม