Domain Logic Pattern Selector
by @quochungto
Choose domain logic pattern for enterprise application subsystems: Transaction Script vs Domain Model vs Table Module, and decide Service Layer thickness. Us...
Scenario A β Revenue Recognition Engine (Complex Rules β Domain Model)
Trigger: A team building a SaaS billing system. Revenue recognition rules vary by product type: word processors recognize 100% immediately; spreadsheets spread recognition over three dates; databases over two; and the CFO adds new product categories quarterly.
Process:
RevenueRecognition objects should carry the isRecognizableBy(date) method; strategy subclasses should carry calculateRevenueRecognitions(). The service layer only coordinates the transaction and sends notifications.Output: Domain Model with Contract, Product, RevenueRecognition, and a strategy hierarchy (CompleteRecognitionStrategy, ThreeWayRecognitionStrategy). RecognitionService is an Operation Script service layer that delegates domain logic to domain objects and handles email/integration notifications.
Scenario B β Simple Order Management (.NET CRUD β Table Module)
Trigger: A .NET team building internal order management. Rules are mostly: validate fields, calculate totals, apply standard discounts. All UI is data-grid based. ADO.NET DataSets flow through every layer.
Process:
Order Table Module, not in a SQL stored procedure.Output: Contract Table Module, Product Table Module, RevenueRecognition Table Module operating on a shared DataSet. No domain object identity β every operation takes a primary key parameter.
Scenario C β Legacy Transaction Scripts Hitting Complexity Wall β Refactor to Domain Model
Trigger: A Java team's billing service has grown to a 2,000-line BillingService class. Discount logic is copy-pasted across five methods. Adding a new rule requires touching seven places.
Process:
BillingService as an Operation Script service layer; move business rules onto Contract, LineItem, and Discount domain objects.Data Mapper to decouple persistence; migrate rule-specific conditional branches into strategy classes.BillingService to new classes that only hold data. Behavior must move too.Output: Decision record documenting the refactor direction, a domain object skeleton (Contract, LineItem, Discount), BillingService reduced to coordinating transactions and notifications, and a Data Mapper recommendation for persistence.
clawhub install bookforge-domain-logic-pattern-selector