40
301AA - Advanced Programming Lecturer: Andrea Corradini [email protected] h;p://pages.di.unipi.it/corradini/ Course pages: h;p://pages.di.unipi.it/corradini/Dida@ca/AP-18/ AP-2018-11: Frameworks and Inversion of Control

301AA - Advanced Programmingpages.di.unipi.it/corradini/Didattica/AP-18/SLIDES/AP-2018-11.pdf · – Using connecPon oriented programming (event source and listeners/delegates) 3

Embed Size (px)

Citation preview

301AA-AdvancedProgramming

Lecturer:AndreaCorradini [email protected]

h;p://pages.di.unipi.it/corradini/

Coursepages:h;p://pages.di.unipi.it/corradini/Dida@ca/AP-18/

AP-2018-11:FrameworksandInversionofControl

FrameworksandInversionofControl

•  Recap:JavaBeansasComponents•  Frameworks,ComponentFrameworksandtheirfeatures

•  FrameworksvsIDEs•  InversionofControlandContainers•  FrameworksvsLibraries•  DecouplingComponents•  DependencyInjecPon•  IoCContainersinSpring

2

Components:arecap

•  Examples:JavaBeans,CLRAssemblies•  Contractuallyspecifiedinterfaces:events,methodsandproperPes

•  Explicitcontextdependencies:serializable,constructorwithnoargument

•  Subjecttocomposi?on:connecPontootherbeans–  UsingconnecPonorientedprogramming(eventsourceandlisteners/delegates)

3

Aso,warecomponentisaunitofcomposi4onwithcontractuallyspecifiedinterfacesandexplicitcontextdependenciesonly.AsoXwarecomponentcanbedeployedindependentlyandissubjecttocomposi4onbythirdparty.ClemensSzyperski,ECOOP1996

TowardsComponentFrameworks

•  So,wareFramework:AcollecPonofcommoncodeprovidinggenericfunc?onalitythatcanbeselec?velyoverriddenorspecializedbyusercodeprovidingspecificfunc?onality

•  Applica4onFramework:AsoXwareframeworkusedtoimplementthestandardstructureofanapplicaPonforaspecificdevelopmentenvironment.

•  Examples:–  GUIFrameworks– WebFrameworks–  ConcurrencyFrameworks

4

Web Application Frameworks

GUI Toolkits

5

ExamplesofFrameworks

Examples:GeneralSoXwareFrameworks

–  .NET–Windowspla^orm.Provideslanguageinteroperability

– AndroidSDK–SupportsdevelopmentofappsinJava(butdoesnotuseaJVM!)

– Cocoa–Apple’snaPveOOAPIformacOS.IncludesCstandardlibraryandtheObjecPve-CrunPme.

– Eclipse–Cross-pla^orm,easilyextensibleIDEwithplugins

6

Examples:GUIFrameworks

•  FrameworksforApplicaPonwithGUI– MFC-MicrosoXFoundaPonClassLibrary.C++object-orientedlibraryforWindows.

– Gnome–Wri;eninC;mainlyforLinux

– Qt-Cross-pla^orm;wri;eninC++

7

Examples:WebFrameworks

•  WebApplicaPonFrameworks[basedonModel-View-Controllerdesignpa;ern]– ASP.NETbyMicrosoXforwebsites,webapplicaPonsandwebservices

– GWT-GoogleWebToolkit(GWT)–  Rails-Wri;eninRuby-Providesdefaultstructuresfordatabases,webservicesandwebpages.

–  Spring- forJava-basedenterprisewebapplicaPons–  Flask–micro-frameworkinPython,highlyextensible(authenPcaPon,validaPon,ORmapper…asextensions)

https://en.wikipedia.org/wiki/Comparison_of_web_frameworks!

ExamplesofFrameworks

•  Concurrency– HadoopMap/Reduce-soXwareframeworkforapplicaPonswhichprocessbigamountsofdatain-parallelonlargeclusters(thousandsofnodes)inafault-tolerantmanner.

• Map:Takesinputdataandconvertsitintoasetoftuples(key/valuepairs).

•  Reduce:TakestheoutputfromMapandcombinesthedatatuplesintoasmallersetoftuples.

9

FeaturesofFrameworks

•  Aframeworkembodiessomeabstractdesign,withmorebehaviorbuiltin.

•  Inordertouseityouneedtoinsertyourbehaviorintovariousplacesintheframeworkeitherbysubclassingorbyplugginginyourownclasses.

•  Theframework’scodethencallsyourcodeatthesepoints.

•  Averygeneralconcept,emphasizinginversionofcontrol:asopposedtolibrariesisthecodeoftheframeworkthatcallsthecode

10

ComponentFrameworks•  Frameworksthatsupportdevelopment,deployment,composiPon

andexecuPonofcomponentsdesignedaccordingtoagivenComponentModel

•  Supportthedevelopmentofindividualcomponents,enforcingthedesignofpreciseinterfaces

•  Supportthecomposi4on/connec4onofcomponentsaccordingtothemechanismsprovidedbytheComponentModel

•  Allowsinstancesofthesecomponentstobe“plugged”intothecomponentframeworkitself

•  Provideprebuiltfunc4onali4es,suchasusefulcomponentsorautomatedassemblyfuncPonsthatautomaPcallyinstanPateandcomposecomponentstoperformcommontasks.

•  Thecomponentframeworkestablishesenvironmentalcondi4onsforthecomponentinstancesandregulatestheinterac4onbetweencomponentinstances.

11

FrameworksvsIntegratedDevelopmentEnvironments(IDEs)

•  Orthogonalconcepts•  AframeworkcanbesupportedbyseveralIDEs

– Eg:SpringsupportedbySpringToolSuite(basedonEclipse),NetBeans,IntelliJIDEA,Eclipse,…

•  AnIDEcansupportseveralframeworks– Eg:NetBeanssupportsJavaBeans,Spring,J2EE,Maven,Hibernate,JavaServerFaces,Struts,Qt,…

12

FrameworksFeatures•  Consistofpartsthatarefoundinmanyappsofthattype

–  LibrarieswithAPIs(classeswithmethodsetc.)–  Ready-madeextensibleprograms("engines")–  SomePmesalsotools(e.g.fordevelopment,configuraPon,content)

•  Frameworks,likesoXwarelibraries,providereusableabstrac>onsofcodewrappedinawell-definedAPI

•  But:Inversionofcontrol–  unlikeinlibraries,theoverallprogram'sflowofcontrolisnotdictated

bythecaller,butbytheframework •  Helpssolvingrecurringdesignproblems

–  Providingadefaultbehavior–  DictaPnghowtofill-in-the-blanks

•  Non-modifiableframeworkcode–  Extensibility:usuallybyselecPveoverriding

13

Extensibility•  Allframeworkscanbeextendedtocaterforapp-specificfuncPonality.– AframeworkisintendedtobeextendedtomeettheneedsofaparPcularapplicaPon

•  Commonwaystoextendaframework:–  Extensionwithintheframeworklanguage:

•  Subclassing&overridingmethods•  ImplemenPnginterfaces•  Registeringeventhandlers

–  Plug-ins:frameworkcanloadcertainextracodeinaspecificformat

14

Twoselectedtopics

Wegiveacloserlooktotwogeneraltopicsrelatedtoframeworks:•  Inversionofcontrol•  Masteringdependenciesamongcomponents

15

InversionofControl(IoC)inGUIs

•  Intext-basedinteracPon,theorderofinteracPonsandofinvocaPonsisdecidedbythethecode.

•  IntheGUI-basedinteracPon,theGUIloopdecideswhentoinvokethemethods,basedontheorderofevents

•  AlsoknownastheHollywoodPrinciple–“Don'tcallus,we'llcallyou”.

16

#rubyputs'Whatisyourname?'name=getsprocess_name(name)puts'Whatisyourquest?'quest=getsprocess_quest(quest) TEXT

require'tk'root=TkRoot.new()name_label=TkLabel.new(){text"WhatisYourName?"}name_label.packname=TkEntry.new(root).packname.bind("FocusOut"){process_name(name)}quest_label=TkLabel.new(){text"WhatisYourQuest?"}quest_label.packquest=TkEntry.new(root).packquest.bind("FocusOut"){process_quest(quest)}Tk.mainloop() GUI

https://martinfowler.com/bliki/InversionOfControl.html!

InversionofControlinFrameworks

•  WithFrameworkstheInversionofControlbecomesdominant

•  TheapplicaPonarchitectureisoXenfixed,evenifcustomizable,anddeterminedbytheFramework–  Whenusingaframework,oneusuallyjustimplementsafewcallbackfuncPonsorspecializesafewclasses,andtheninvokesasinglemethodorprocedure.

–  Theframeworkdoestherestoftheworkforyou,invokinganynecessaryclientcallbacksormethodsattheappropriatePmeandplace.

•  Example:Java'sSwingandAWTclasses,NetBeansprojects–  Theyhaveahugeamountofcodetomanagetheuserinterface,andthereisinversionofcontrolbecauseyoustarttheGUIframeworkandthenwaitforittocallyourlisteners

17

InversionofControlTradiPonalProgramExecuPon InversionofControl

TheapphascontrolovertheexecuPonflow,callinglibrarycodewhenitneedsto.

TheframeworkhascontrolovertheexecuPonflow,callingappcodeforapp-specificbehavior.

18

FrameworksvsLibraries•  Frameworksconsistoflargesetsofclasses/interfaces,suitablypackaged

•  Notmuchdifferentfromlibraries•  (Possible)Keyfeature:wideuseofInversionofControl

•  “Framework”somePmesintendedas“well-designedlibrary”

•  “JavaCollecPonFramework”vs“StandardTemplateLibrary”:arethemframeworksorlibraries?

19

20

JavaCollecPonFramework

StandardTemplateLibrary

Components,ContainersandIoC•  OXenFrameworksprovidecontainersfordeployingcomponents

•  AcontainermayprovideatrunPmefuncPonaliPesneededbythecomponentstoexecute

•  Example:EJBcontainersareresponsibleofthepersistentstorageofdataandoftheavailabilityofEJB’sforallauthorizedclients

•  UsingIoC,EJBcontainerscaninvokeonsessionbeansmethodslikeejbRemove,ejbPassivate(storetosecondarystorage),andejbAc?vate(restorefrompassivestate).

•  Spring’sIoCcontainers:arelatedconcept…

21

Looselycoupledsystems:advantagesandtechniques

•  GoodOOSystemsshouldbeorganisedaswebofinteracPngobjects

•  Goal:Highcohesion,lowcoupling•  Advantagesoflowcoupling

– Extensibility– Testability– Reusability

•  WediscussDependencyinjec>onandothertechniquestoachieveit

22NickHines-DependencyInjec?onandInversionofControl-ThoughtWorks,2006

AConcreteExample–ATradeMonitor

23

TradeMonitor–Thedesign

•  TradeMonitoriscoupledtoLimitDao[DataAccessObject]–thisisnotgood!–  Extensibility–whatifwereplacethedatabasewithadistributedcache?–  Testability–wheredothelimitsfortestcomefrom?–  Reusability–logicisfairlygeneric...

public class TradeMonitor { private LimitDao limitDao; public TradeMonitor() { limitDao = new LimitDao(); } public bool TryTrade(string symbol, int amount) { int limit = limitDao.GetLimit(symbol); int exposure = limitDao.GetExposure(symbol); return (exposure + amount > limit) ? false : true; } }

public class LimitDao { public int GetExposure(string symbol) { // Do something with the database } public int GetLimit(string symbol) { // Do something with the database } }

limitDao = new LimitDao();

24

TradeMonitor–TheDesignRefactored(1)

•  Introduceinterface/implementaPonseparaPon–  LogicdoesnotdependonDAOanymore.–  Doesthisreallysolvetheproblem?

public class TradeMonitor { private LimitRepository limitRepository; public TradeMonitor() { limitRepository = new LimitDao(); } public bool TryTrade(string symbol, int amount) {

. . . } }

public interface LimitRepository { int GetExposure(string symbol); int GetLimit(string symbol); }

limitRepository = new LimitDao();

•  TheconstructorsPllhasastaPcdependencyonDAO

25

•  IntroduceaFactory.Ithastheresponsibilitytocreatetherequiredinstance.

•  TradeMonitordecoupledfromLimitDao•  LimitDaosPllPghtly-coupledalbeittoFactory

public class LimitFactory { public static LimitRepository GetLimitRepository() { return new LimitDao(); } } public class TradeMonitor { private LimitRepository limitRepository; public TradeMonitor() { limitRepository = LimitFactory.GetLimitRepository(); } public bool TryTrade(string symbol, int amount) { . . . } }

LimitFactory

TradeMonitor

<<interface>>LimitRepository

LimitDao

<<creates>>

return new LimitDao();

26

TradeMonitor–TheDesignRefactored(2)

•  IntroduceaServiceLocator.Thisobjectactsasa(staPc)registryfortheLimitDaoyouneed.

•  Thisgivesusextensibility,testability,reusabilitypublic class ServiceLocator{ public static void RegisterService(Type type, object impl) {. . .} public static object GetService(Type type) {. . .} } public class TradeMonitor{ private LimitRepository limitRepository; public TradeMonitor(){ object o = ServiceLocator.GetService(typeof(LimitRepository)); limitRepository = (LimitRepository) o; } public bool TryTrade(string symbol, int amount){ . . . } }

27

TradeMonitor–TheDesignRefactored(3)

ServiceLocator–Prosandcons

•  TheServiceLocatorpa;ernsucceedsindecouplingtheTradeMonitorfromtheLimitDao

•  Itcanbegeneralizedinseveralways,eg.tocoverdynamiclookup

•  Cons:– Aformofsequencedependenceremains–  Cumbersomesetupintests–  Servicedependsoninfrastructurecode(theServiceLocator)

–  Codeneedstohandlelookupproblems

28

TowardsDependencyInjecPon•  IntheoriginalsituaPon,weaimat

relaxingthecouplingusingsoluPonsbasedonInversionofControl

Q: Which“control”isinverted?A: ThelookupoftheLimitRepositoryinstancefromTradeMonitor

ThepluginiscreatedbyanexternalAssembleranditispassedtoTradeMonitorinsomeway.Thedependencyisinjectedinthemaincomponent.

29

DependencyInjecPon•  Dependencyinjec4onallowsavoidinghard-codeddependencies(strongcoupling)andchangingthem

•  AllowsselecPonamongmulPpleimplementaPonsofagivendependencyinterfaceatrunPme

•  Examples:–  loadpluginsdynamically–  replacemockobjectsintestenvironmentsvs.realobjectsinproducPonenvironments

•  Threeforms:–  Se;erinjecPon–  ConstructorinjecPon–  (Interfaceinjec?on)

30

DependencyinjecPonbasedonse;ermethods

•  Idea:addaseYer,andletsomethingelseworryaboutcreaPonandresoluPon.

public class TradeMonitor { private LimitRepository limitRepository; public TradeMonitor() { } public LimitRepository Limits { set { limitRepository = value;} } public bool TryTrade(string symbol, int amount){ . . . } }

•  Thedependenciesareinjectedfromtheoutside

•  ComponentsarepassiveandarenotconcernedwithlocaPngorcreaPngdependencies

ThisisSeKerInjec>on

•  WidelyusedinSpring

31

DependencyInjecPonbasedonConstructors

•  Whynotjustusetheconstructor?

public class TradeMonitor { private LimitRepository limitRepository; public TradeMonitor(LimitRepository limitRepository) { this.limitRepository = limitRepository; } public bool TryTrade(string symbol, int amount){ . . . } }

•  Nose;ersfordependentcomponents,(obviously)

•  One-shotiniPalisaPon–componentsarealwaysiniPalisedcorrectly

•  Alldependenciesareclearlyvisiblefromcode

•  Itisimpossibletocreatecyclicdependencies

ThisisConstructorInjec>on

•  WidelyusedinPicoContainer

32

ExploiPngConstructorInjecPonforTesPng

[TestFixture] public class TradeMonitorTest { [Test] public void MonitorBlocksTradesWhenLimitExceeded() { DynamicMock mockRepository = new DynamicMock(typeof(LimitRepository)); mockRepository.SetupResult('GetLimit', 1000000, new Type[] { typeof(string) }); mockRepository.SetupResult('GetExposure', 999999, new Type[] { typeof(string) }); TradeMonitor monitor = new TradeMonitor((LimitRepository)mockRepository.MockInstance); Assert.IsFalse(monitor.TryTrade('MSFT', 1000), 'Monitor should block trade'); } }

public class TradeMonitor { private LimitRepository repository; public TradeMonitor(LimitRepository repository) { this.repository = repository; } public bool TryTrade(string symbol, int amount) { int limit = repository.GetLimit(symbol); int exposure = repository.GetExposure(symbol); return ((amount + exposure) <= limit); } }

33

WhichsoluPontouse?•  BothServiceLocatorandDependencyInjec4onprovide

thedesireddecoupling•  Withservicelocator,thedesiredcomponentisobtained

aXerrequestbytheTradeMonitortotheLocator:noIoC•  WithdependencyinjecPonthereisnoexplicitrequest:the

componentappearsintheapplicaPonclass•  Inversionofcontrolabithardertounderstand•  WithServiceLocatortheapplicaPonsPlldependsonthe

locator•  Itiseasiertofinddependenciesofcomponentif

DependencyInjecPonisused–  Checkconstructorsandse;ersvscheckallinvocaPonstolocatorinthesourcecode

34

TowardsIoCContainers•  TherearesPllsomeopenquesPons

– Whocreatesthedependencies?– WhatifweneedsomeiniPalisaPoncodethatmustberunaXerdependencieshavebeenset?

– Whathappenswhenwedon’thaveallthecomponents?

•  IoCContainerssolvetheseissues[eg:Spring]– HaveconfiguraPon–oXenexternal–  Createobjects–  EnsurealldependenciesaresaPsfied–  Providelifecyclesupport

35

OtherpossiblesoluPons•  Reflec4oncanbeusedtodeterminedependencies,reducingtheneedforconfigfiles.– Makecomponentsknowntocontainer.–  Containerexaminesconstructorsanddeterminesdependencies.

•  MostIoCcontainerssupportauto-wiring:automaPcwiringbetweenproperPesofabeanandotherbeansbased,eg,onnameortype

•  Auto-wiringprovidesotherbenefits:–  Lesstyping.–  StaPctypecheckingbyIDEateditPme.– MoreintuiPvefordeveloper.

36

SomeIoCContainersandtheirFeatures

Container Setter DI

Ctor DI

External config

Code config

Auto-wiring

Lifecycle support`

Url

System.ComponentModel a a Part of .Net framework

PicoContainer.Net a a a a a http://picocontainer.orgWindsor a a a ? a http://www.castleproject.orgStructureMap a a a P a http://sourceforge.net/projects/structuremapSpring.Net a a a ? a a http://www.springframework.net/ObjectBuilder a a a a ?? a http://msdn.microsoft.com

?? = More investigation

? = Setter based DI required for primitive dependenciesP = Partial still requires configuration to point to assemblies to scan

37

DependencyinjecPoninSpring•  TheobjectsthatformthebackboneofaSpringapplicaPonare

calledbeans•  AbeanisanobjectthatisinstanPated,assembled,andotherwise

managedbyaSpringIoCcontainer(Applica?onContext)•  BeandefiniPoncontainstheinformaPoncalledconfigura4on

metadata,whichisneededforthecontainertoknowthefollowing–  Howtocreateabean–  Bean’slifecycledetails–  Bean’sdependencies

•  TheconfiguraPonmetadatacanbesuppliedtothecontainerinthreepossibleways:–  XMLbasedconfigura4onfile(thestandard)–  Annota4on-basedconfiguraPon–  Java-basedconfiguraPon

38

SpringIoCcontainers•  TheSpringcontainerisatthecoreoftheSpring

Framework.•  Thecontainerwillcreatetheobjects,wirethemtogether,

configurethem,andmanagetheircompletelifecyclefromcreaPonPlldestrucPon.

•  TheSpringcontainerusesDependencyInjec4ontomanagethecomponentsthatmakeupanapplicaPon.

•  ThecontainergetsitsinstrucPonsonwhatobjectstoinstanPate,configure,andassemblebyreadingtheconfigura4onmetadataprovided.

•  Thediagramtotherightrepresentsahigh-levelviewofhowSpringworks.TheSpringIoCcontainermakesuseofJavaPOJOclassesandconfiguraPonmetadatatoproduceafullyconfiguredandexecutablesystemorapplicaPon.

•  QuicklybrowsingtheSpringArchitecture…https://docs.spring.io/spring/docs/3.0.x/reference/overview.html#overview-modules

39

//imports…publicclassMainApp{publicstaPcvoidmain(String[]args){ApplicaPonContextcontext=newClassPathXmlApplicaPonContext("Beans.xml");HelloWorldobj=(HelloWorld)context.getBean("helloWorld");obj.getMessage();}} Themainclass,loadinganApplica4onContext

40

publicclassHelloWorld{ privateStringmessage; publicvoidsetMessage(Stringmessage){ this.message=message; } publicvoidgetMessage(){ System.out.println("YourMessage:"+message); }} Thebean:aPOJO(PlainOldJavaObject)

<?xmlversion="1.0"encoding="UTF-8"?><beansxmlns="h;p://www.springframework.org/schema/beans"xmlns:xsi="h;p://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocaPon="h;p://www.springframework.org/schema/beansh;p://www.springframework.org/schema/beans/spring-beans-3.0.xsd”><beanid="helloWorld"class="com.tutorialspoint.HelloWorld"><propertyname="message"value="HelloWorld!"/></bean></beans> TheConfigura4onMetafile(XML)

Se;erInjecPon(performedbytheIoCcontainer)