Dependency Injection, Design Principles and Patterns
1. Dependency Injection
Design Principles and Patterns
Part I
Prepared by
Juan Lopez, Software Developer
October 29, 2014
2. Overview
Successful software must be able to change.
The purpose of most programming techniques is to deliver working
maintainable software as efficiently as possible.
Writing well-crafted and self-explanatory software is almost as important as
writing working software.
One of many ways to make code maintainable is through loose coupling. Loose
coupling makes code extensible, and extensibility makes it maintainable.
3. What is Dependency Injection?
Dependency Injection is a set of object-oriented programming and design
principles and patterns.
Wikipedia:
Dependency Injection is a set of software design patterns that implements
inversion of control and allows a program design to follow the dependency
inversion principle.
Mark Seemann:
Dependency Injection is a set of software design principles and patterns that
enable us to develop loosely coupled code.
6. Dependency Injection
DI enables loose coupling, and loose coupling makes code more maintainable.
DI is a means to an end. DI also enables us to better manage futures changes
and other complexities in our software.
DI is more about abstract thinking and design code than it is about tools and
techniques.
7. Single Responsibility Principle
Maintainability is a benefit of the SINGLE RESPONSIBILITY PRINCIPLE,
which states that each class should have a single responsibility. Classes
should only deal with their given area of responsibility, without concerning
themselves with how DEPENDENCIES are created.
An important element of DI is to break up various responsibilities into
separate classes. One responsibility we take away from is the task of creating
instances of DEPENDENCIES.
8. Open/Closed Principle
Software entities should be open for extension but closed for modifications.
Loose coupling enables us to write code which is open for extensibility, but
closed for modifications, that is, such an entity can allow its behaviour to be
modified without altering its source code.
The implementation of a class could only be modified to correct errors; new or
changed features would require that a different class be created. Don’t change
existing code, instead add new classes and recompose the application.
9. Liskov substitution principle
Objects in a program should be replaceable with instances of their subtypes
without altering the correctness of that program.
A client should not care about the concrete types of its DEPENDENCIES.
10. Interface Segregation Principle
Many client specific interfaces are better than one general purpose interface.
No client should be forced to depend on methods it does not use.
ISP splits interfaces which are very large into smaller and more specific ones
so that clients will only have to know about the methods that are of interest to
them.
11. Dependency Inversion
Principle
Depend upon abstractions. Do not depend upon concretions.
Program to an interface, not an implementation.
The most prevalent benefit of programming to interfaces, is the ability to swap
out one service with another.
13. Adapter Pattern
The Adapter Design Pattern allows the interface of an existing class to be
used from another interface. It is often to make existing classes work with
others without modifying their source code.
An adapter helps two incompatible interfaces to work together by converting
the interface of one class into one expected by the client.
The adapter pattern is useful in situations where an already existing class
provides some or all of the services you need but does not the interface you
need.
14. Bridge Pattern
The Bridge Pattern is design to “decouple an abstraction from its
implementation so that the two can vary independently.”
The bridge pattern is useful when both the class and as well as what it does
vary often. The class itself can be thought as the implementation and what the
class can do as the abstraction.
15. Composite Pattern
When we aggregate several implementations in one, we use the Composite
Pattern. The Composite Pattern describes that a group of objects is to be
treated same way as a single instance of an object. The intent of a composite is
to “compose” objects into tree structures to represent part-whole hierarchies.
Favor composition over class inheritance.
16. Conclusion
The consequences of poor system design, software architecture or software
developer is Technical Debt.
If the debt is not paid, then it will keep on accumulating interest, making it hard
to implement changes later on.
more code to write = more code to test = more code to debug = more code to maintain
One of many ways to make code maintainable is through loose coupling. Loose
coupling makes code extensible, and extensibility makes it maintainable.
Dependency Injection enables loose coupling.