Tải bản đầy đủ - 0 (trang)
Chapter 7. Let the Rules Rule

Chapter 7. Let the Rules Rule

Tải bản đầy đủ - 0trang

CategorizationofRules

Ifwetrytocategorizerules,wequicklyfindoutthatthereare

manydimensionstoconsider.Forexample,thereareattributes

suchasthefollowing:

Wheretoexecute(inwhichtier/layer)

Whentoexecute

Degreeofcomplexity(simpleconstraints,spanningseveral

fields,spanningseveralinstances,andsoon)

Startingactionsornot

Andsoon,andsoforth

I'msorry,butIwon'tbedealingwiththismuchotherthan

directingyoutosomeotherbooksonthesubject,suchasvon

Halle'sbook[vonHalleBRA],theonebyRoss[RossBRB],and

Halpin's[HalpinIMRD].Youwillfindthatthesebooksarepretty

data-focused,buttheyareneverthelesshighlyinteresting.

Let'strytogetstartedfromanotherangle.Let'sdefinesome

principlesandthengetourhandsdirty.







PrinciplesforRulesandTheirUsage

Ithinkthewordprincipleisverygoodbecauseit'snotstrict.

It'smucheasiertocomeupwithprinciplesthancategories,

probablybecauseofthebuilt-invagueness.Still,principlesare

descriptiveregardingintention.That'sexactlywhatIneedhere

andnow.



Two-WayRulesChecking:Optional(Possible)to

CheckProactively,Mandatory(andAutomatic)

toCheckReactively

Youshouldbeabletocheckinadvance(proactively)whether

therewillbeaproblem(forexample,tryingtopersistthe

currentchanges)sothatyoucantakecorrectivemeasures.

Thatway,theprogrammingmodelwillbeeasier.

Andifyoufailtocheckinadvance,thereisnomercy,butyou

willlearn(reactively)thattherewereproblemsviaan

exception.



AllStates,EvenWheninError,Shouldbe

Savable

Usershatetolearnfromapplicationsthattheycan'tsavethe

currentchangesbecauseoferrors.Afriendofminehas

comparedittonotbeingallowedtosaveawordprocessing

documentifyouhavespellingerrors.

Allisa"big"word,butwewilltrytoatleastcomeclose.We

shouldtrytoavoidreachingthosestatesthatwon'tbe



persistable.

It'salsoimportanttothinkaboutwhaterrormeanshere.An

ordermightbeconsideredtobeinerrorifit'stoolarge.But

untiltheusertriestosubmittheorderit'snotreallyanerror,

justasituationheneedstodealwithbeforesubmitting.Andhe

shouldbeabletosavethatorderbeforehesubmitsitsohecan

continueworkingonitlateron,tosolvetheproblemand

submititthen.



RulesShouldBeProductivetoUse

Itshouldbeproductivetoworkwithrules,bothwhen

consumingtherulesandwhendefiningtherulesthemselves.

Theproductivityforconsumingruleswillbeaddressedby

makingitpossibletofetchmetadatatobeusedforsettingup

theUI.Thatwillcutthetimesyoufindproblemswhenyou

checkbecausetheUIhashelpedsothatsomeproblemsjust

won'thappen.(Justwatchoutsoyoudon'ttrusttheUItobeall

thatisneededregardingruleschecking.)

Theproductivitygoalfordefiningrulesmightbereachedwitha

smallframeworkthatletsyoufocusontheinterestingpartsof

therules,andtheboilerplatecodewillbedealtwithforyou.



RulesShouldOptionallybeConfigurablesothat

YouCanAddCustomRules

Somerulesarescenariodependentwhileothersarenot,soit

mightbeimportantnotonlytobeabletodeclareallrules

directlyintheclassdefinitions.Instead,youneedtobeableto

addcustomrulesdynamicallyforcertainusecases,butalso

duringdeploymentasconfigurationinformation.



Ithinkthattheconfigurationaspectisparticularlyusefulwhen

youbuildproductsthatwillbeusedbymanydifferent

customers.Ifyouarebuildingasystemforasinglecustomer,

it'sprobablyoflessvalue.



RulesShouldBeLocatedwithState

Rulesshouldatleastbedefinedascloselyaspossibletothe

relevantDomainModelclasses.BythisIdon'tmeanthe

implementationoftherulesthemselvesbutthedeclarations.

Wewantencapsulationoftheusagesothatweeasilygetthe

"complete"pictureofaDomainModelclassbyinspectingits

class.

Ithinkthisprinciplehelpsanotherprinciplethatcouldbecalled

"Rulesshouldbeconsistent."Whenthecodebasereachesa

certainsize,thereisariskthattherulesmayinterfereoreven

contradicteachother.Havingtherulestogetherandtogether

withthestateshouldhelptosomedegreewithmanagingthe

rulebase.



RulesShouldbeExtremelyTestable

Wewillspendalotoftimeworkingwithandtestingtherules.

Forthisreason,it'simportanttohaveatest-friendlydesignfor

therules.

Inreality,addingrulesalsocreatesproblemswithtesting.You

needtosetupinstancestocorrectstates.Youcanwritetest

helpers(suchasprivatemethodsinthetestfixture)fordealing

withthat,butit'sstillahindrance.



TheSystemShouldStopYoufromGettingintoa



BadState

Agoodwayofsimplifyinghowtoworkwithrulesistoavoidthe

needforthemwhenpossible.Onewayofdoingthatis,for

example,toworkwithcreationmethodsthatwillsetupthe

DomainModelobjectsinavalidstatethatcanneverbemade

invalid.



StartingtoCreateanAPI

We'llcomebacktotheseprinciplesandevaluatehowwe

fulfilledthemlaterinthechapter,butnowit'stimetocome

backdowntoEarthandtakeupsomeoftheproblemsoutlined

inChapter4.I'mgoingtostartwiththeexternalAPIandsee

whereweendup.Ibelievethatwillgiveagood,pragmatic

feelingaboutthewholething.

Sotoremindyou,theproblemsorrequestsoutlinedinChapter

4werethefollowing:

1. Listcustomersbyapplyingaflexibleandcomplexfilter.

2. Listtheorderswhenlookingataspecificcustomer.

3. Anordercanhavemanydifferentlines.

4. Concurrencyconflictdetectionisimportant.

5. Acustomermaynotoweusmorethanacertainamountof

money.

6. Anordermaynothaveatotalvalueofmorethanone

millionSEK.

7. Eachorderandcustomershouldhaveauniqueanduserfriendlynumber.

8. BeforeanewcustomerisconsideredOK,hisorhercredit

willbecheckedwithacreditinstitute.

9. Anordermusthaveacustomer;anorderlinemusthavean

order.

10. Savinganorderanditslinesshouldbeautomatic.



11. Ordershaveanacceptancestatusthatischangedbythe

user.

Let'stakeoneoftheproblems;say,problem6,"Anordermay

nothaveatotalvalueofmorethanonemillionSEK."

Howshallweapproachthisproblem?Thereareseveraloptions

tochoosefrom.

Youcouldcreatesomethinglikeasimplerule-checkingengine

whereyoucansendyourinstancestobevalidated,oryoucould

lettheinstancestakeresponsibilityforthatthemselves.Ilike

theideaoflettingtheinstancestakeresponsibilityfor

themselvesasmuchaspossible(oratleastasfarasis

appropriate)andthereforepreferthelatter.Perhapsthisisabit

naïve,butalsoverysimpleinapositiveway.

IfIwriteatesttogetstarted,itcouldlooklikethis:

[Test]

publicvoidCantExceedMaxAmountForOrder()

{

Ordero=newOrder(newCustomer());

OrderLineol=newOrderLine(newProduct());

ol.NumberOfUnits=2000000;

ol.Price=1;

o.AddOrderLine(ol);

Assert.IsFalse(o.IsValid);

}



WhatwedidwastoaddapropertytotheOrdercalledIsValid.A

prettycommonapproachIthink.Therearealsosomeobvious

problems,suchasthefollowing:



Whatwastheproblem?Weonlyknowthattherewasone,

notwhatitwas.

Weallowedanincorrecttransition.

Whatifweforgottocheck?

AllwedidwastocheckifeverythingwasOKornot.Wewill

comebacktothementionedproblems,butwehavesomething

morebasictodealwithfirst.Amoreimportantproblemisthis

question:

Whatisittheorderisvalidfor(ornotvalidfor)?



Context,Context,Context!

Contextis,asalways,veryimportantbutprettymuchforgotten

intheapproachwestartedoutwith.Weneedtoaddressthis

beforemovingonbecauseit'scrucialtotherestofthe

discussion.

IthinkthereasonforthecommonapproachofIsValidassome

kindofgeneral,catch-alltestmightbebecauseoftoomuch

focusonpersistence.Ifwedecouplepersistencefromrulesabit

andtrytoadheretotheprincipleoflettingallstatesbesavable,

wemightendupwithanotherapproach.

ThenIthinkthetransitionswillbetheinterestingthing

regardingrules.Forexample,whenanorderisinthestateof

NewOrder,moreorlesseverythingmightbeallowed.Butwhen

theordershouldtransitiontotheOrderedstate,thatwillonlybe

allowedifcertainrulesarefulfilled.

SosavinganorderthatisinthestateofNewOrdershouldbe

possibleeveniftheorderisn'tvalidforenterOrderedstate.



Approachingrulesthiswaywillfocusrulesonthemodel

meaningandnotletatechnicality,suchaspersistedornot,

affectthemodel.

Thatsaid,thereisarealityfullofpracticalproblems,andwe

needtodealwiththatwell.Soevenifwehavetheintentionof

focusingonthemodel,wehavetobegoodcitizensregarding

theinfrastructurealso.Let'sseeifthinkingaboutpersistedor

notasaspecialstatehelps,butfirstIthinkit'simportantto

discusswhatcouldgiveusproblemsregardingrulesifwedon't

thinkenoughabouttheinfrastructure.



DatabaseConstraints

Eventhoughyoumightchoosetofocusonputtingallyourrules

intheDomainModel,youwillstillprobablyendupwithsome

rulesinthedatabase.Atypicalreasonforthisisefficiency.

Somerulesaremostefficientlycheckedinthedatabase;that's

justhowitis.Youcanprobablydesignaroundmostofthem,

buttherewillprobablystillbeacoupleofsituationswherethis

isafactoflife.

Anotherreasonisthatyoumightnotbeabletodesignanew

database,oryoumightnotbeabletodesignthedatabase

exactlyasyouwouldlikeit,butyouhavetoadjusttoacurrent

databasedesign.Yetanotherreasonisthatit'softenconsidered

agoodthingthatthedatabasecantakecareofitself,especially

ifseveraldifferentsystemsareusingthesamedatabase.

Theimpedancemismatchbetweenobject-orientationand

RelationaldatabasesthatwediscussedinChapter1,"Valuesto

Value,"willalsoshowuphere.Forexample,thestringsinthe

databasewillmostlikelyhavestaticmaxlengths,suchas

VARCHAR(50).Thatacertainstringisn'tallowedtobelongerthan

thatiskindofagenericrule,butit'smostlyrelatedto

persistence.ThetransitiontoPersistedstatewon'tbeallowedif



thestringistoolong.

Soit'sprobablethatyouwillhavetodealwithruleswhose

invaliditywon'tbedetecteduntilthestateispersistedtothe

database.Thatinitsturnrepresentsacoupleofproblems.

First,parsingerrorinformationistroublesome,especiallywhen

youconsiderthatatypicalO/RMappingsolutionoftentriesto

beportablebetweendifferentdatabases.Orrather,theheartof

theproblemisthattheO/RMapperprobablywon'tbeableto

dothemappingforyouwhenitcomestoerrorsandtellyou

whatfield(s)causedtheproblemintheDomainModel;for

example,whenthere'saduplicatekeyerror.

Furthermore,theerrorwillcomeataninconvenientpointin

time.YourDomainModelhasalreadybeenchanged,anditwill

probablybeveryhardforyoutorecoverfromtheproblem

withoutstartingalloveragain.Infact,thegeneralruleisoften

thatyoushouldstartoverinsteadoftryingtodosomething

smart.

Still,wedoliketheideaofmakingitpossibletosaveour

instancesatanytime.(Inanycase,wehavesetupsome

preferencesevenifwecan'tfollowthemto100%.Theextreme

isoftenextremelycostly.)

AsIseeit,trytodesignforasmuchproactivityaspossible(or

asappropriate)sothatthenumberofexceptionsfromthe

databasewillbeextremelyfew.Forthosethatarestillpossible,

bepreparedtodealwiththemonebyoneincode,orbe

preparedtorollbackthetransaction,tossouttheDomain

Modelchanges,andstartalloveragain.Abitdrastic,butthat's

thewayIseeit.Thekeytoallthisisdesign,soyoumakethe

problemassmallaspossible.

OK,thatwasthepurelytechnicalsideofit(thatthedatabase

mightshowitsdiscomfortwithus).Butit'snotjustamatterof

thattherulesareinfrastructure-relatedonlyordomain-related



only.Thereareconnections.



BindRulestoTransitionsRelatedtotheDomain

ortheInfrastructure?

Whatwehavesaidsofaristhatweshouldtryhardtonotenter

aninvalidstate.Ifwefollowthat,wecanalwayspersist(ifwe

don'tthinkabouttheinfrastructure-relatedconstraintsforthe

moment).

Thatprincipleistheideal.Inreality,itwillbehardnottobreak

certainrulesduringamultiplestepaction.Forexample,should

youdisallowthechangeofthenameofacustomertoaname

thattherulethinksistooshort?Well,perhaps,butitmightjust

preventtheuserfromdoingwhathewantstodo:namely

deletingtheoldnameandinsertinganewoneinstead.

It'spossibletodealwiththisbyhavingamethodcalled

Rename(stringnewName)thattakescareofthework.Duringthe

executionofthemethod,thestateoftheobjectisn'tcorrect,

butweonlyconsideritaproblembeforeandafterthemethod

execution.



Note

ThisisinlinewithinvariantsaccordingtoDesignby

Contract[MeyerOOSC].Suchinvariantsarelike

assertionsthattheinstanceshouldabidebyatall

times,bothbeforethemethodexecutionandafter.

Theonlyexceptionisduringthemethodexecution.



Anotherapproachistosimplynotsetthepropertyuntilyou've



Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Chapter 7. Let the Rules Rule

Tải bản đầy đủ ngay(0 tr)

×