Download presentation
Presentation is loading. Please wait.
Published byMyra Bradley Modified over 8 years ago
1
L’origine dei mali: le dipendenze tra componenti Stefano Leli 14° Workshop DotNetMarche Venerdì 16 aprile 2010 @sleli stefano.leli@gmail.com
2
Software Dependencies Software Dependencies Service Locator Service Locator Inversion of Control Inversion of Control Dependency Injection Dependency Injection Aspect Oriented Programming Aspect Oriented Programming Agenda
3
What is a Dependency?
4
ClassA +RequestService() ClassB public RequestService() { ClassB b = new ClassB() b.DoService(); } Dependencies dependent +DoService()
5
Layer Dependencies Presentation Layer Business Layer Data Access Layer Depends on High-level modules should not depend on low-level modules. Both should depend on abstractions Robert C. Martin DB Depends on Depends on
6
Why dependencies are evil? Tight coupling of software components Tight coupling of software components hard to change because every change affects too many other parts of the system (Rigidity) hard to change because every change affects too many other parts of the system (Rigidity) When you make a change, unexpected parts of the system break. (Fragility) When you make a change, unexpected parts of the system break. (Fragility) hard to reuse in another application. (Immobility) hard to reuse in another application. (Immobility) Software becomes hard to maintain Software becomes hard to maintain Difficult to isolate when testing Difficult to isolate when testing
7
Scenario
8
Copier Example Copier +PerformCopy() Keyboard +ReadFromKB(c : char) Video + WriteToVideo () : char
9
class Copier { Keyboard _reader; Keyboard _reader; Video _writer; Video _writer; public Copier() public Copier() { _reader = new Keyboard(); _reader = new Keyboard(); _writer = new Video(); _writer = new Video(); } public void PerformCopy() public void PerformCopy() { int chr; int chr; while ( (chr = _reader.ReadFromKeyboard() ) != '\r') while ( (chr = _reader.ReadFromKeyboard() ) != '\r') _writer.WriteToVideo(chr); _writer.WriteToVideo(chr); }} class Keyboard { public int ReadFromKeyboard() public int ReadFromKeyboard() { return Console.ReadKey(true).KeyChar; return Console.ReadKey(true).KeyChar; }} class Video { public void WriteToVideo(int chr) public void WriteToVideo(int chr) { Console.Write((char)chr); Console.Write((char)chr); }} Copier Example
10
class Copier { Keyboard _reader; Keyboard _reader; Video _writer; Video _writer; public Copier() public Copier() { _reader = new Keyboard(); _reader = new Keyboard(); _writer = new Video(); _writer = new Video(); } public void PerformCopy() public void PerformCopy() { int chr; int chr; while ( (chr = _reader.ReadFromKeyboard() ) != '\r') while ( (chr = _reader.ReadFromKeyboard() ) != '\r') _writer.WriteToVideo(chr); _writer.WriteToVideo(chr); }} class Keyboard { public int ReadFromKeyboard() public int ReadFromKeyboard() { return Console.ReadKey(true).KeyChar; return Console.ReadKey(true).KeyChar; }} class Video { public void WriteToVideo(int chr) public void WriteToVideo(int chr) { Console.Write((char)chr); Console.Write((char)chr); }} Copier Example Problem
11
Program to an interface, not an implementation
12
Copier Example > IWriterIReader Copier +PerformCopy() Keyboard +Read(c : char) Video + Write () : char Concrete class should depend on abstraction Robert Martin
13
class Copier { IReader _reader; IReader _reader; IWriter _writer; IWriter _writer; public Copier() public Copier() { _reader = new Keyboard(); _reader = new Keyboard(); _writer = new Video(); _writer = new Video(); } public void PerformCopy() public void PerformCopy() { int chr; int chr; while ( (chr = _reader.Read() ) != '\r') while ( (chr = _reader.Read() ) != '\r') _writer.Write(chr); _writer.Write(chr); }} class Keyboard : IReader { public int Read() public int Read() { return Console.ReadKey(true).KeyChar; return Console.ReadKey(true).KeyChar; }} class Video : IWriter { public void Write(int chr) public void Write(int chr) { Console.Write((char)chr); Console.Write((char)chr); }} Copier Example
14
class Copier { IReader _reader; IReader _reader; IWriter _writer; IWriter _writer; public Copier() public Copier() { _reader = new Keyboard(); _reader = new Keyboard(); _writer = new Video(); _writer = new Video(); } public void PerformCopy() public void PerformCopy() { int chr; int chr; while ( (chr = _reader.Read() ) != '\r') while ( (chr = _reader.Read() ) != '\r') _writer.Write(chr); _writer.Write(chr); }} class Keyboard : IReader { public int Read() public int Read() { return Console.ReadKey(true).KeyChar; return Console.ReadKey(true).KeyChar; }} class Video : IWriter { public void Write(int chr) public void Write(int chr) { Console.Write((char)chr); Console.Write((char)chr); }} Copier Example Problem Dependencies resolution is still here!!!
15
TowardsDecoupling
16
> Using a Factory > IWriterIReader Copier Keyboard +Read(c : char) Video + Write () : char ReaderFactory +GetInstance() : IReader +Copier(r : IReader, w : IWriter) +PerformCopy() WriterFactory +GetInstance() : IWriter
17
class Copier { IReader _reader; IReader _reader; IWriter _writer; IWriter _writer; public Copier() public Copier() { _reader = ReaderFactory.GetInstance(); _reader = ReaderFactory.GetInstance(); _writer = WriterFactory.GetInstance(); _writer = WriterFactory.GetInstance(); } public void PerformCopy() public void PerformCopy() { int chr; int chr; while ( (chr = _reader.Read() ) != '\r') while ( (chr = _reader.Read() ) != '\r') _writer.Write(chr); _writer.Write(chr); }} class ReaderFactory { public static IReader GetInstance() public static IReader GetInstance() { return new Keyboard(); return new Keyboard(); }} class WriterFactory { public static IWriter GetInstance() public static IWriter GetInstance() { return new Video(); return new Video(); }} Using a Factory
18
class Copier { IReader _reader; IReader _reader; IWriter _writer; IWriter _writer; public Copier() public Copier() { _reader = ReaderFactory.GetInstance(); _reader = ReaderFactory.GetInstance(); _writer = WriterFactory.GetInstance(); _writer = WriterFactory.GetInstance(); } public void PerformCopy() public void PerformCopy() { int chr; int chr; while ( (chr = _reader.Read() ) != '\r') while ( (chr = _reader.Read() ) != '\r') _writer.Write(chr); _writer.Write(chr); }} class ReaderFactory { public static IReader GetInstance() public static IReader GetInstance() { return new Keyboard(); return new Keyboard(); }} class WriterFactory { public static IWriter GetInstance() public static IWriter GetInstance() { return new Video(); return new Video(); }} Using a Factory We have just move the problem!!! Problem
19
> IWriterIReader Copier Keyboard +Read(c : char) Video + Write () : char +PerformCopy() ServiceLocator +Lookup() : Object +RegisterService(o : Object) _instance : ServiceLocator Service Locator …
20
> IWriterIReader Copier Keyboard +Read(c : char) Video + Write () : char +PerformCopy() ServiceLocator +Lookup() : Object +RegisterService(o : Object) _instance : ServiceLocator Service Locator … Assembler
21
Service Locator class ServiceLocator { /* Singleton instance */ /* Singleton instance */ private static ServiceLocator _instance; private static ServiceLocator _instance; public static void Load(ServiceLocator arg) public static void Load(ServiceLocator arg) { _instance = arg; _instance = arg; } /* Storing and Retrieve services */ /* Storing and Retrieve services */ private Dictionary _services = new Dictionary (); private Dictionary _services = new Dictionary (); public Object RegisterService(String key) public Object RegisterService(String key) { return _instance._services[key]; return _instance._services[key]; } public static void Lookup(String key, Object service) public static void Lookup(String key, Object service) { _services.Add(key, service); _services.Add(key, service); }}
22
Service Locator class Copier { IReader _reader; IReader _reader; IWriter _writer; IWriter _writer; public Copier() public Copier() { _reader = (IReader)ServiceLocator.Lookup("reader"); _reader = (IReader)ServiceLocator.Lookup("reader"); _writer = (IWriter)ServiceLocator.Lookup("writer"); ; _writer = (IWriter)ServiceLocator.Lookup("writer"); ; } public void PerformCopy() public void PerformCopy() { int chr; int chr; while ( (chr = _reader.Read() ) != '\r') while ( (chr = _reader.Read() ) != '\r') _writer.Write(chr); _writer.Write(chr); }} /* Configure Service Locator method*/ /* Configure Service Locator method*/ private void configureLocator() { ServiceLocator locator = new ServiceLocator(); ServiceLocator locator = new ServiceLocator(); locator.LoadService("reader", new Keyboard()); locator.LoadService("reader", new Keyboard()); locator.LoadService("writer", new Video()); locator.LoadService("writer", new Video()); ServiceLocator.Load(locator); ServiceLocator.Load(locator);}
23
Pro Pro Help to avoid coupling Help to avoid coupling Centralize dependencies resolution Centralize dependencies resolution Cons Cons Introduce dependencies with the locator Introduce dependencies with the locator Difficult to test Difficult to test Service Locator
24
Inversion of Control
25
Inversion of Control, or IoC, is an abstract principle describing an aspect of some software architecture designs in which the flow of control of a system is inverted in comparison to traditional programming. Inversion of Control, or IoC, is an abstract principle describing an aspect of some software architecture designs in which the flow of control of a system is inverted in comparison to traditional programming. Hollywood Principle Hollywood Principle “don't call us, we'll call you.” There are many implementations of IoC, Dependency Injections is one of there. There are many implementations of IoC, Dependency Injections is one of there. What is IoC?
26
Technique for supplying an external dependency to a software component. Technique for supplying an external dependency to a software component. Implemented by a Container (IoC) Implemented by a Container (IoC) Creates and assembles component/objects and manages their lifecycle Creates and assembles component/objects and manages their lifecycle Generally configured by coding or external file Generally configured by coding or external file Three forms of injection Three forms of injection Constructor Injection Constructor Injection Setter Injection Setter Injection Interface Injection Interface Injection What is Dependency Injection?
27
IoC Container IWriterIReader Copier Keyboard +Read(c : char) Video + Write () : char +Copier(r : IReader, w : IWriter) +PerformCopy()
28
> IoC Container > IWriterIReader Copier Keyboard +Read(c : char) Video + Write () : char IoCContainer … +Copier(r : IReader, w : IWriter) +PerformCopy() XML Config
29
DI: Constructor Injection class Copier { IReader _reader; IReader _reader; IWriter _writer; IWriter _writer; public Copier(IReader reader, IWriter writer) public Copier(IReader reader, IWriter writer) { _reader = reader; _reader = reader; _writer = writer; _writer = writer; } public void PerformCopy() public void PerformCopy() { int chr; int chr; while ( (chr = _reader.Read() ) != '\r') while ( (chr = _reader.Read() ) != '\r') _writer.Write(chr); _writer.Write(chr); }} To prefer in case of Mandatory Dependencies
30
DI: Setter Injection class Copier { private IReader _reader; private IReader _reader; public IReader Reader public IReader Reader { set{_reader = value;} set{_reader = value;} } private IWriter _writer; private IWriter _writer; public IWriter Writer public IWriter Writer { set{_writer = value;} set{_writer = value;} } public void PerformCopy() public void PerformCopy() { int chr; int chr; while ((chr = _reader.Read()) != '\r') while ((chr = _reader.Read()) != '\r') _writer.Write(chr); _writer.Write(chr); }} To prefer in case of Optional Dependencies
31
DI: Interface Injection class Copier { private IReader _reader; private IReader _reader; public void InjectReader(IReader reader) public void InjectReader(IReader reader) { _reader = reader; _reader = reader; } private IWriter _writer; private IWriter _writer; public void InjectWriter(IWriter writer) public void InjectWriter(IWriter writer) { _writer = writer; _writer = writer; } public void PerformCopy() public void PerformCopy() { int chr; int chr; while ((chr = _reader.Read()) != '\r') while ((chr = _reader.Read()) != '\r') _writer.Write(chr); _writer.Write(chr); }} interface IReaderInject { void injectReader(IReader reader); void injectReader(IReader reader);} interface IWriterInject { void injectWriter(IWriter reader); void injectWriter(IWriter reader);} Quite Never Used
32
Pro Pro High Decoupling level High Decoupling level Completely transparent to the Domain Model Completely transparent to the Domain Model High Configurable High Configurable Integrated with lots of framework Integrated with lots of framework Cons Cons Difficult to understand by newbie Difficult to understand by newbie Complex to debug Complex to debug DI: Consideration
33
Aspect Oriented Programming
34
AOP is a programming paradigm AOP is a programming paradigm AOP is a new way of thinking about software design AOP is a new way of thinking about software design Enhance OOP in separating concerns to improve modularization Enhance OOP in separating concerns to improve modularization OOP modularizes concerns OOP modularizes concerns AOP addresses cross-cutting concerns AOP addresses cross-cutting concerns What is AOP?
35
Separation of Concern Searching Booking Payment
36
Separation of Concern BookingPaymentSearching OOP Searching Booking Payment Reduce software complexity Reduce software complexity Limit the impact of change Limit the impact of change Facilitate reuse Facilitate reuse Simplify components integration Simplify components integration
37
Crosscutting Concern Booking Security Logging Payment Security Logging Searching Security Logging OOP Crosscutting concerns are functionalities that span multiple modules Crosscutting concerns are functionalities that span multiple modules Security Security Logging Logging Transaction Management Transaction Management … Hard to model with traditional OOP approach Hard to model with traditional OOP approach Code Scattering Code Scattering Code Tangling Code Tangling Crosscutting Concerns Searching Booking Payment
38
Crosscutting Concern Booking Payment Searching Security Logging AOP Booking Security Logging Payment Security Logging Searching Security Logging OOP Crosscutting Concerns Searching Booking Payment
39
Object_BObject_A How it works… method_Amethod_B Object Oriented Flow
40
Aspect Object_BObject_A How it works… method_Amethod_B advice Object Oriented Flow Aspect Oriented Flow pointcut = method_B Target Object = Object_B jointpoint = method invocation
41
Aspect Object_BObject_A How it works… method_Amethod_B advice Object Oriented Flow Aspect Oriented Flow pointcut = method_B Target Object = Object_B jointpoint = method invocation Aspect Aspect Equivalent to class in OOP Equivalent to class in OOP Used to describe a Crosscutting Concern Used to describe a Crosscutting Concern
42
Aspect Object_BObject_A How it works… method_Amethod_B advice Object Oriented Flow Aspect Oriented Flow pointcut = method_B Target Object = Object_B jointpoint = method invocation Join Point Join Point Well-defined point during the execution of a program (e.g. method invocation, attribute access, exception handling,…) Well-defined point during the execution of a program (e.g. method invocation, attribute access, exception handling,…)
43
Aspect Object_BObject_A How it works… method_Amethod_B advice Object Oriented Flow Aspect Oriented Flow pointcut = method_B Target Object = Object_B jointpoint = method invocation Advice Advice action taken by an aspect at a particular join point action taken by an aspect at a particular join point
44
Aspect Object_BObject_A How it works… method_Amethod_B advice Object Oriented Flow Aspect Oriented Flow pointcut = method_B Target Object = Object_B jointpoint = method invocation Pointcut Pointcut Predicate that matches join points Predicate that matches join points Advice is associated with a pointcut expression and runs at any join point matched by the pointcut Advice is associated with a pointcut expression and runs at any join point matched by the pointcut
45
Aspect Object_BObject_A How it works… method_Amethod_B advice Object Oriented Flow Aspect Oriented Flow pointcut = method_B Target Object = Object_B jointpoint = method invocation Target Object Target Object Also called Advised Object Also called Advised Object Object being advised by one or more aspects Object being advised by one or more aspects
46
Aspect Object_BObject_A method_Amethod_B advice Object Oriented Flow Aspect Oriented Flow pointcut = method_B Target Object = Object_B jointpoint = method invocation Weaving Weaving Weaving Run-Time Weaving Run-Time Weaving Compile-Time Weaving Compile-Time Weaving … behind the scenes
47
References Martin Fowler Martin Fowler Inversion of Control Containers and the Dependency Injection pattern Inversion of Control Containers and the Dependency Injection pattern Robert C. Martin Robert C. Martin The Dependency Inversion Principle The Dependency Inversion Principle AOP Alliance AOP Alliance
48
Questions?
49
Slide and Materials www.dotnetmarche.org Grazie!
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.