let's want perform operation involves updating data in several objects.
here's example:
void someoperation() { order.setstatus(orderstatus.readyforshipping); order.save(); email = emailfactory.createorderisreadyemail(order); mailservice.queueemail(email); mailservice.save(); shippinghandler = shippinghandlerselectionstrategy.select(order.location); shippinghandler.additem(order); shippinghandler.save(); }
where place put code this?
in it's own class?
class readyforshippingoperation : operation { override void execute() { // ... } }
but if operation has specific business rules when can executed, sort of rules require intimate knowledge of objects?
for example, can execute operation when order state. state not value on order, it's specific set of requirements that's ever relevant operation.
do want add order object?
class order { bool isreadyforthatshippingoperation(); }
this method concerns order insofar it's implementation highly coupled order's data. conceptually it's not part of order. it's relevant our 1 operation.
another option make details of order public. doesn't feel right. example, our operation class might like:
class readyforshippingoperation : operation { override void execute() { if (!orderisready(order)) { // handle error } // ... } bool orderisready(order) { if (order.createddate > somevalue) return false; if (order.lastupdateddate > somevalue) return false; if (!order.isvalid) return false; if (!order.chachingstate == inprogress) return false; return true; } }
what happens in case find myself forced expand order api, single purpose of giving orderisready() method permission grasp dirty hands around it.
perhaps example specific. in general want know how best organize business operations require intimate data many objects don't seem belong 1 object.
you can implement business operations in dedicated api class. example, api class concerned order-involving operations may called ordersapi
:
class orderoperationsapi { void someoperation() {} // implement someoperation here void someotheroperation() {} // implement else on orders, shippings, etc.. }
popular approach pass such business operations, can of complexity, business-wise, "unit of work" object.
this unit-of-work implemented transaction on database or other persistent storage. idea here keep track of objects modified during transaction, persist changed objects on commit (or discard on rollback).
it's important feature there's special accounting object purpose, decoupled business entities oversees.
usual approach make business api calls pass through unit-of-work objects employ form of aop (aspect-oriented programming). wraps call business api (someoperation()
in case) entry code, fills context business objects needed data sources , finalizing code, checks if transaction committed, , if yes, gathers modified objects , updates corresponding entries in persistent storage.
Comments
Post a Comment