Yakov Fain - Design Patterns a Deep Dive
-
Upload
360conferences -
Category
Technology
-
view
931 -
download
3
description
Transcript of Yakov Fain - Design Patterns a Deep Dive
DesignPa*erns,aDeepDive
ByYakovFainFarataSystems
(c)FarataSystems
2
Farata Systems: What do we wo
Consulting and training
Software development (for free) (open source project Clear Toolkit on Sourceforge.net)
Writing tech. books and articles on Java and Adobe Flex (making from $0 to $1 per hour)
www.faratasystems.com
($$$$$$$$$$$$$$$$$$)
Whatisthisabout?
Designpa*ernssuggestanapproachtocommonproblemsthatariseduringsoCwaredevelopmentregardlessofwhatprogramminglanguageyouuse.
ButthegoalofthispresentaGonistohighlightselectedpa*ernsasyoumayimplementthemtakingadvantageoftheFlexframework.
(c)FarataSystems
We’lltalkaboutthesepa*erns
• Singleton• Proxy• Mediator
• DataTransferObject• AsynchronousToken
(c)FarataSystems
SingletonYoucancreateonlyoneinstanceofsuchaclassThere’snoprivateconstructorsinAcGonScript
ConsiderasamplefileMySingleton.as
packagesomePackage{publicclassMySingleton{
privatestaGcconst_instance:MySingleton=newMySingleton(Lock);publicstaGcfuncGongetinstance():MySingleton{return_instance;}publicfuncGonMySingleton(lock:Class){if(lock!=Lock){thrownewError("IllegalinstanGaGon.");}}}//EndofpackageclassLock{}
(c)FarataSystems
Haveyoueverseenthis?
varmodel:AppModelLocator=AppModelLocator.getInstance();
andthis?service=ServiceLocator.getInstance().getHTTPService('loadEmployeesService');
(c)FarataSystems
EnhancingtheApplicaGonobjectpublicdynamicclassDynamicApplica5onextendsApplica5onimplementsIApplicaGonFacade{publicfuncGonDynamicApplicaGon(){
super();}
publicstaGcvarservices:DicGonary=newDicGonary();
publicfuncGongetService(name:String):Object{ returnservices[name];}publicfuncGonaddService(name:String,value:Object):void{ services[name]=value;}publicfuncGonremoveService(name:String):void{ deleteservices[name];}publicfuncGongetServices():DicGonary{ returnservices;}
}
TheIApplicaGonFacadejustdeclaresthesefourmethodstoenableFlexBuilder’sintellisensehelpwhencasGng.var myApp:IApplicationFacade = …
(c)FarataSystems
AddinganyproperGestomyModel
(c)FarataSystems
SampledynamicapplicaGon(beginning)<?xmlversion="1.0"encoding="uc‐8"?><fx:DynamicApplicaGonxmlns:mx="h*p://www.adobe.com/2006/mxml"layout="absolute"xmlns:fx="h*p://www.faratasystems.com/2009/components"creaGonComplete="addAllServices();"><mx:Script>
<![CDATA[importcom.farata.core.DynamicApplicaGon;importmx.core.ApplicaGon;
//AddrequiredservicestotheApplica3onobject,i.e.myModelandmyServicesprivatefunc5onaddAllServices():void{
DynamicApplicaGon.services["myModel"]=newObject(); DynamicApplicaGon.services["myServices"]=newObject(); }
privatefunc5ongetData(serviceName:String,key:Object):Object{
returnDynamicApplicaGon.services[serviceName][key];}
privatefunc5onsetData(serviceName:String,key:Object,value:String):void{
DynamicApplicaGon.services[serviceName][key]=newString(value);}
]]></mx:Script> (c)FarataSystems
<!‐‐AddingvaluestomyModel‐‐><mx:Bu*onlabel="AddtomyModel"x="193"y="59”click="setData('myModel',key.text,value.text)"/>
<mx:Labelx="14"y="42"text="Key"fontWeight="bold"/><mx:Labelx="14"y="14"fontWeight="bold"fontSize="14"><mx:text>Addoneormorekey/valuepairstotheobjectMyModel</mx:text>
<mx:Labelx="91"y="42"text="Value"fontWeight="bold"/><mx:TextInputx="8"y="59"id="key"width="75"/><mx:TextInputx="89"y="59"id="value"width="96"/>
<!‐‐RetrievingthevaluefromaSingleton.‐‐><mx:Bu*onlabel="Showthevalue"x="8"y="122"click="retrievedValue.text=getData('myModel',key.text)asString"/><mx:Labelx="135"y="121"width="95"id="retrievedValue"fontWeight="bold"fontSize="15"/><mx:Labelx="10"y="94"fontWeight="bold"fontSize="14"><mx:text>RetrieveanddisplaythevaluefromMyModelbykey</mx:text></fx:DynamicApplicaGon>
SampledynamicapplicaGon(ending)
(c)FarataSystems
ProxyAproxyisanobjectthatrepresentsanotherobjectandcontrolsaccesstoit.
Thinkofasecretarythatreceivesapackageforherboss.
InAcGonScriptyoucanwraptheclassXYZinmx.uGl.ObjectProxy,whichwillbeaproxythatcontrolsaccesstotheXYZ’sproperGes.
(c)FarataSystems
How[Bindable]works?[Bindable]varlastName:String;
Flexcompilergeneratesawrapperclasswithase*erthatdispatchespropertyChangeeventoneachmodificaGonoflastName
Youcandoitonyourownbyusingtheclassmx.uGls.ObjectProxy
(c)FarataSystems
packagecom.farata{publicdynamicclassPerson {publicvarlastName:String="Johnson";publicvarsalary:Number=50000;}}
WrappingPersoninObjectProxy
(c)FarataSystems
RunningthePersonproxy
(c)FarataSystems
ExtendingObjectProxy
AddsomeapplicaGonlogictoit.Ifthesalaryofapersonincreasesover$55K,shebecomesenGtledforthepensionintheamountof2%ofthesalary.YouwanttoaddthisfuncGonalitywithouttouchingthecodeoftheclassPerson.
InasubclassofObjectProxy,youcanoverridegetProperty() andsetProperty() fromthenamespaceflash_proxy.
Ifyou’llwriteMyPersonProxy.lastName=”McCartney”,thisobjectwillcallitsownmethodsetProperty(“lastName”, “McCartney”). InterceptthiscallandaddsomeprocessingtototheoverriddenmethodsetProperty().
(c)FarataSystems
TesGngMyPersonProxy
ACer3clicksaddingpension property
(c)FarataSystems
Mediator
Anycomplexscreen,moreorless,ofabusinessapplicaGonconsistsofanumberofcontainersandcomponents.
Wewanttocreateloosely‐coupledcustomcomponentsthatareselfcontained,donotknowaboutexistenceofeachotherandcancommunicatewiththe“outsideworld”bysendingandreceivingevents.
(c)FarataSystems
BeforethetraderclickedonthePricePanel
ACerthetraderclickedonthePricePanel
WallStreet:StockTradingApplicaGon
PricePanelcomponenthasthreevariables:symbol, bid and ask
PricePaneldispatchestheOrderEventdispatchEvent(new OrderEvent( OrderEvent.PREPARE_ORDER_EVENT, symbol, bid,ask,buy));
OrderPanellistenstoOrderEventaddEventListener(OrderEvent.PLACE_ORDER_EVENT,orderEventHandler)
func5onorderEventHandler(evt:OrderEvent){sym.text=evt.symbol;operaGon.text=evt.buy?"Buy":"Sell";price.text=(oper.text=="Buy"?evt.bid:evt.ask);}
(c)FarataSystems
PricePanelComponent.Take1
OrderEventcarries4variables
(c)FarataSystems
CustomEventOrderEvent
TheMediatorreceivesthiseventfromPricePanelanddispatchesittoOrderPanel
Toomanyuservariables.ItwouldbeagoodideatoencapsulatetheminoneDTO–DataTransferObjecta.k.a.ValueObject
(c)FarataSystems
TheMediatorapplicaGonListentotheOrderEventfromPricingPanel
…andsendittoOrderPanel
(c)FarataSystems
DataTransferObject
DataTransferObjects(DTO)a.k.a.ValueObjects(VO)areusedfordataexchangebetweenvariousapplicaGoncomponents,whichcanbeeitherco‐locatedinthesameprocessoronremotecomputers.
TheseDTO’scanevenbewri*enindifferentprogramminglanguages,forexampleJavaandAcGonScript.
(c)FarataSystems
IntroducingDTOinStockTradingApp.
Insteadofpassingseveralvariablesbetweenpricingandorderpanels,we’llencapsulateorderdetailsintheOrderDTO classandsenditinsidetheeventobjecttothemediator.
(c)FarataSystems
PricePanelComponent.Take2
startDataFeed() emulatesexternaldatafeed
PackagingaDTOinsidetheeventOrderEvent2
UIcomponentsareboundtoDTOproperGes
(c)FarataSystems
NowPricePanelDispatchesOrderEvent2
Theapplica5on(mediator)willgetthiseventanddispatvhittotheOrderPanel:
varorderEvt:OrderEvent2=newOrderEvent2(OrderEvent2.PLACE_ORDER_EVENT,evt.orderInfo);
ordPanel.dispatchEvent(orderEvt); (c)FarataSystems
OrderPanelreceivestheevent…
…extractstheDTOfromtheevent
…andpopulatesUIcomponentsofOrderPanel
(c)FarataSystems
AdvancedDTOs
Ifyouenvisiondynamicupdatestothedataontheclient,declaretheseclassesas[Bindable].
UseanArrayCollecGonofsuchbindableDTO’sasadataProviderinyourDataGrid,List,andsimilarcomponents.
Makesurethatbothserver‐sideandclient‐sideDTOsprovideuniquepropertyuuid.FlexusesthispropertytouniquelyidenGfythedataelementsoftheList‐basedcontrols.
ConsiderreplacingeachpublicproperGeswiththege*erandse*ertohavemorecontroloverthemodificaGonsoftheseproperGes.
Youcanandaddthecodetothesese*ers/ge*ersthatwillintercepttheacGonofdatamodificaGonandperformaddiGonalprocessingbasedonwhat’sbeingchanged.Then,these*ercandispatchtheeventPropertyChangeeventasshownonthenextslide
(c)FarataSystems
SampleDTOwithbidproperty
FarataSystemshascreatedDTOgeneratorforJavaprogrammerscalledDto2FxthatcreatesAcGonScriptDTOsfromtheirJavacounterparts.It’safreeware,andyoucangetitath*p://flexblog.faratasystems.com/?p=357
(c)FarataSystems
AsynchronousToken
TheusermakesseveralRemoteObjectrequestsandresultscomebackasynchronouslyinarbitraryorder.
EachrequestcallsaresulthandlerfuncGonprovidingtheresultevent.
HowtheapplicaGoncodecanmaparrivingresultobjectsbacktotheiniGalrequestors?
(c)FarataSystems
AsyncTokenClassThegoaloftheAsynchronousTokenpa*ernistoproperlyroutetheprocessingontheclientinresponsetothedataarrivingasynchronouslyformtheserver
AsyncTokenisadynamicclass,youcanaddanyproperGestothisclassduringrunGme<mx:RemoteObjectid=”ord”desGnaGon=”Orders”/>…
privatefuncGonsendOrder(/*argumentsgohere*/):void{
vartoken:AsyncToken=ord.placeOrder({item:”SonyTV”});token.orderNumber=”12345”;
token.responder=newResponder(processOrderPlaced,processOrderFault);token.addResponder(newResponder(createShipment,processOrderFault));}
(c)FarataSystems
Whentheresultcomesback
AsyncTokenisalocalobject.ItisidenGfiedbyamessageId thatispassedwiththerequesttoserver.
Whentheserverresponds,itincludesacorrelationId propertyinthemessageheader,andFlexautomaGcallycallstheappropriateAsyncTokenrespondersintheordertheyweredefined.
privatefuncGonprocessOrderPlaced(event:ResultEvent):void{
myOrderNumber:Object=event.token.orderNumber;
//ifmyOrderNumberis12345,processitaccordingly}
(c)FarataSystems
ContactInfo&LinksEmail:[email protected]
Website:h*p://www.faratasystems.com
ClearToolkit:h*p://sourceforge.net/projects/cleartoolkit/
O’ReillyBook“EnterpriseDevelopmentwithFlex”:h*p://my.safaribooksonline.com/9780596801465
(c)FarataSystems