1 / 26

Dependency Injection DI

The Problem with Software? (why it rots). Couplingi.e. dependencies between classesThese are examples of coupling:fred = new Student();TIGHT couplingpublic class Student extends Person {?TIGHT couplingfred = new Person(); A BIT LOOSERpersonFactory = new PersonFactory();MODERATE Fred

pepper
Télécharger la présentation

Dependency Injection DI

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


    1. Dependency Injection (DI) Or “Inversion of Control” Dave Elliman

    2. The Problem with Software… (why it rots) Coupling i.e. dependencies between classes These are examples of coupling: fred = new Student(); TIGHT coupling public class Student extends Person {… TIGHT coupling fred = new Person(); A BIT LOOSER personFactory = new PersonFactory(); MODERATE Fred = personFactory.createPerson(); might use Context Most Java APIs use an abstract factory like this Can we do better?

    3. Yes we can!

    4. Where do we create the objects and decide which to pass as arguments? This can be done in a container Specified in XML (or using annotations) Can be decided at run time We have a model like: Choose objects and create them Wire up constructor calls Run program This is now very loosely coupled Calling objects only need to know that an object passed can respond to a known method call Can replace objects with stubs, test objects, mock objects etc.

    5. Background Laws SRP – Single Responsibility Principle A class should have one and only one reason to change OCP – The Open-Closed Principle Code should be open to extension and closed to modification DI is a great help in doing what seems paradoxical at first sight

    6. The Law of Demeter Only talk to your friends…. Not to friends of friends This also limits coupling a.getX().getY() is a violation So is… serviceLocator.getService()

    7. This needs a bit of explaining

    8. PCTIP: Prefer Composition to Inheritance Principle Why? Because it is a looser form of coupling

    9. Design patterns are neat designs based on these principles

    10. What is Dependency Injection? DI is all about wiring up objects or plumbing if you prefer It is about ensuring loose coupling and fits well with design patterns Design to an interface and then inject the actual class at run time This is what inheritance is really for in Java, C# and C++ You don’t even need to use inheritance in dynamic languages such as Python, Ruby, Groovy, Objective-C etc.

    11. Martin Fowler Martin Fowler has been hugely influential in popularising this design pattern http://martinfowler.com/ The best description of the material in this lecture is here: http://martinfowler.com/articles/injection.html Rod Johnson is the other guru - the man behind Spring http://www.springsource.com/about/management

    12. An EXAMPLE Imagine you have a webapp that tracks the prices of stocks over time. The application is nicely partitioned into different modules that each handle a portion of the job. A StockQuotes module talks to a remote web service to pull down the current values of the stocks you are tracking. A Database module records the stock values over time. Because this data is highly competitive, you require a login to use the system and thus have an Authentication module to handle validation of user names and password. In addition to these "main" modules, there are a number of additional utility modules used by multiple modules: ErrorHandler to standardize the handling and reporting of error messages and Logger to provide a standard way of logging messsages. Imagine you have a webapp that tracks the prices of stocks over time. The application is nicely partitioned into different modules that each handle a portion of the job. A StockQuotes module talks to a remote web service to pull down the current values of the stocks you are tracking. A Database module records the stock values over time. Because this data is highly competitive, you require a login to use the system and thus have an Authentication module to handle validation of user names and password. In addition to these "main" modules, there are a number of additional utility modules used by multiple modules: ErrorHandler to standardize the handling and reporting of error messages and Logger to provide a standard way of logging messsages.

    13. Remember the old way public class WebApp { public WebApp() { quotes = new StockQuotes(); authenticator = new Authenticator(); database = new Database(); logger = new Logger(); errorHandler = new ErrorHandler(); } // More code here... }

    14. What about the child objects? How does the StockQuotes find the Logger? How does the Authenticator find the database? Suppose you want to use a TestingLogger instead? Or a MockDatabase?

    15. Service Locator Interface public interface ILocator { TObject Get<TObject>(); }

    16. Service Locator Example public class MyLocator : ILocator { protected Dictionary<Type, object> dict = new Dictionary<Type,object>(); public MyLocator() { dict.Add(typeof(ILogger), new Logger()); dict.Add(typeof(IErrorHandler), new ErrorHandler(this)); dict.Add(typeof(IQuotes), new StockQuotes(this)); dict.Add(typeof(IDatabase), new Database(this)); dict.Add(typeof(IAuthenticator), new Authenticator(this)); dict.Add(typeof(WebApp), new WebApp(this)); } }

    17. StockQuotes with Locator public class StockQuotes { public StockQuotes(ILocator locator) { errorHandler = locator.Get<IErrorHandler>(); logger = locator.Get<ILogger>(); } // More code here... }

    18. Good things Classes are decoupled from explicit imlementation types Easy to externalise the configuration

    19. Dependency Injection Containers Gets rid of the dependency on the ILocator Object is no longer responsible for finding its dependencies The container does it for you

    20. Then what? Write your objects the way you want Setup the container Ask the container for objects The container creates objects for you and configures dependencies

    21. Setting Up the Container (XML) <DIContainer> <TypeMap from=“ILogger” to=“Logger” /> <TypeMap from=“IDatabase” to=“Database” /> <TypeMap from=“IErrorHandler” to=“ErrorHandler” /> <TypeMap from=“IQuotes” to=“StockQuotes” /> <TypeMap from=“IAuthenticator” to=“Authenticator” /> </DIContainer>

    22. Java/Groovy Pico Container Spring Framework Guice (Google) HiveMind Ruby Rico Copland DI Frameworks

    23. Things are usually easier in Groovy, Python or Ruby This is Strappy - Register a new class

    24. Create an instance of a registered class

    25. Inject dependencies

    26. Using the autowired components

More Related