diff --git a/_posts/06-01-01-Dependency-Injection.md b/_posts/06-01-01-Dependency-Injection.md new file mode 100644 index 0000000..e69c4a2 --- /dev/null +++ b/_posts/06-01-01-Dependency-Injection.md @@ -0,0 +1,13 @@ +--- +title: Dependency Injection +--- + +# Dependency Injection {#dependency_injection_title} + +From [Wikipedia](http://en.wikipedia.org/wiki/Dependency_injection): + +> Dependency injection is a software design pattern that allows the removal of hard-coded dependencies and makes it +> possible to change them, whether at run-time or compile-time. + +This quote makes the concept sound much more complicated than it actually is. Dependency Injection is providing a component +with it's dependencies either through constructor injection, method calls or the setting of properties. It is that simple. diff --git a/_posts/06-02-01-Basic-Concept.md b/_posts/06-02-01-Basic-Concept.md new file mode 100644 index 0000000..520415b --- /dev/null +++ b/_posts/06-02-01-Basic-Concept.md @@ -0,0 +1,51 @@ +--- +isChild: true +--- + +## Basic Concept {#basic_concept_title} + +We can demonstrate the concept with a simple, yet naive. + +Here we have a `Database` class that requires an adapter to speak to the database. We instantiate the +adapter in the constructor and create a hard dependency. This makes testing difficult and means the `Database` class is +very tightly coupled to the adapter. + +{% highlight php %} +adapter = new MySqlAdapter; + } +} + +class MysqlAdapter {} +{% endhighlight %} + +This code can be refactored to use Dependency Injection and therefore loosen the dependency. + +{% highlight php %} +adapter = $adapter; + } +} + +class MysqlAdapter {} +{% endhighlight %} + +Now we are giving the `Database` class it's dependency rather than it creating it itself. We could even create a method +that would accept an argument of the dependency and set it that way, or if the `$adapter` property was `public` we could +set it directly. diff --git a/_posts/06-03-01-Complex-Problem.md b/_posts/06-03-01-Complex-Problem.md new file mode 100644 index 0000000..9fd0f21 --- /dev/null +++ b/_posts/06-03-01-Complex-Problem.md @@ -0,0 +1,56 @@ +--- +isChild: true +--- + +## Complex Problem {#complex_problem_title} + +If you have ever read about Dependency Injection then you have probably seen the terms *"Inversion of Control"* or *"Dependency Inversion Principle"*. +These are the complex problems that Dependency Injection solves. + +### Inversion of Control + +Inversion of Control is as it says, "inverting the control" of a system by keeping organisational control entirely separate from our objects. +In terms of Dependency Injection, this means loosening our dependencies by controlling and instantiating them elsewhere in the system. + +For years, PHP frameworks have been achieving Inversion of Control, however, the question became, which part of control +are you inverting, and where to? For example, MVC frameworks would generally provide a super object or base controller that other +controllers must extend to gain access to its dependencies. This **is** Inversion of Control, however, instead of loosening +dependencies, this method simply moved them. + +Dependency Injection allows us to more elegantly solve this problem by only injecting the dependencies we need, when we need them, +without the need for any hard coded dependencies at all. + +### Dependency Inversion Principle + +Dependency Inversion Principle is the "D" in the S.O.L.I.D set of object oriented design principles that states one should +*"Depend on Abstractions. Do not depend on concretions."*. Put simply, this means our dependencies should be interfaces/contracts or abstract +classes rather than concrete implementations. We can easily refactor the above example to follow this principle. + +{% highlight php %} +adapter = $adapter; + } +} + +interface AdapterInterface {} + +class MysqlAdapter implements AdapterInterface {} +{% endhighlight %} + +There are several benefits to the `Database` class now depending on an interface rather than a concretion. + +Consider that you are working in a team and the adapter is being worked on by a colleague. In our first example, we would have +to wait for said colleague to finish the adapter before we could properly mock it for our unit tests. Now that the dependency +is an interface/contract we can happily mock that interface knowing that our colleague will build the adapter based on that contract. + +An even bigger benefit to this method is that our code is now much more scalable. If a year down the line we decide that we +want to migrate to a different type of database, we can write an adapter that implements the original interface and inject that instead, +no more refactoring would be required as we can ensure that the adapter follows the contract set by the interface. diff --git a/_posts/06-04-01-Containers.md b/_posts/06-04-01-Containers.md new file mode 100644 index 0000000..f0e5466 --- /dev/null +++ b/_posts/06-04-01-Containers.md @@ -0,0 +1,14 @@ +--- +isChild: true +--- + +## Containers {#containers_title} + +The first thing you should understand about Dependency Injection Containers is that they are not the same thing as Dependency +Injection. A container is a convenience utility that helps us implement Dependency Injection, however, they can be and often +are misused to implement an anti-pattern, Service Location. Injecting a DI container as a Service Locator in to your classes arguably +creates a harder dependency on the container than the dependency you are replacing. It also makes your code much less transparent +and ultimately harder to test. + +Most modern frameworks have their own Dependency Injection Container that allows you to wire your dependencies together through configuration. +What this means in practice is that you can write application code that is as clean and de-coupled as the framework it is built on. diff --git a/_posts/06-05-01-Further-Reading.md b/_posts/06-05-01-Further-Reading.md new file mode 100644 index 0000000..e1d3645 --- /dev/null +++ b/_posts/06-05-01-Further-Reading.md @@ -0,0 +1,11 @@ +--- +isChild: true +--- + +## Further Reading {#further_reading_title} + +- [Learning about Dependency Injection and PHP](http://ralphschindler.com/2011/05/18/learning-about-dependency-injection-and-php) +- [What is Dependency Injection?](http://fabien.potencier.org/article/11/what-is-dependency-injection) +- [Dependency Injection: An analogy](http://mwop.net/blog/260-Dependency-Injection-An-analogy.html) +- [Dependency Injection: Huh?](http://net.tutsplus.com/tutorials/php/dependency-injection-huh/) +- [Dependency Injection as a tool for testing](http://www.happyaccidents.me/dependency-injection-as-a-tool-for-testing/) diff --git a/_posts/06-01-01-Databases.md b/_posts/07-01-01-Databases.md similarity index 100% rename from _posts/06-01-01-Databases.md rename to _posts/07-01-01-Databases.md diff --git a/_posts/07-01-01-Errors-and-Exceptions.md b/_posts/08-01-01-Errors-and-Exceptions.md similarity index 100% rename from _posts/07-01-01-Errors-and-Exceptions.md rename to _posts/08-01-01-Errors-and-Exceptions.md diff --git a/_posts/07-02-01-Errors.md b/_posts/08-02-01-Errors.md similarity index 100% rename from _posts/07-02-01-Errors.md rename to _posts/08-02-01-Errors.md diff --git a/_posts/07-03-01-Exceptions.md b/_posts/08-03-01-Exceptions.md similarity index 100% rename from _posts/07-03-01-Exceptions.md rename to _posts/08-03-01-Exceptions.md diff --git a/_posts/08-01-01-Security.md b/_posts/09-01-01-Security.md similarity index 100% rename from _posts/08-01-01-Security.md rename to _posts/09-01-01-Security.md diff --git a/_posts/08-02-01-Web-Application-Security.md b/_posts/09-02-01-Web-Application-Security.md similarity index 100% rename from _posts/08-02-01-Web-Application-Security.md rename to _posts/09-02-01-Web-Application-Security.md diff --git a/_posts/08-03-01-Password-Hashing.md b/_posts/09-03-01-Password-Hashing.md similarity index 100% rename from _posts/08-03-01-Password-Hashing.md rename to _posts/09-03-01-Password-Hashing.md diff --git a/_posts/08-04-01-Data-Filtering.md b/_posts/09-04-01-Data-Filtering.md similarity index 100% rename from _posts/08-04-01-Data-Filtering.md rename to _posts/09-04-01-Data-Filtering.md diff --git a/_posts/08-05-01-Configuration-Files.md b/_posts/09-05-01-Configuration-Files.md similarity index 100% rename from _posts/08-05-01-Configuration-Files.md rename to _posts/09-05-01-Configuration-Files.md diff --git a/_posts/08-06-01-Register-Globals.md b/_posts/09-06-01-Register-Globals.md similarity index 100% rename from _posts/08-06-01-Register-Globals.md rename to _posts/09-06-01-Register-Globals.md diff --git a/_posts/08-07-01-Error-Reporting.md b/_posts/09-07-01-Error-Reporting.md similarity index 100% rename from _posts/08-07-01-Error-Reporting.md rename to _posts/09-07-01-Error-Reporting.md diff --git a/_posts/09-01-01-Testing.md b/_posts/10-01-01-Testing.md similarity index 100% rename from _posts/09-01-01-Testing.md rename to _posts/10-01-01-Testing.md diff --git a/_posts/09-02-01-Test-Driven-Development.md b/_posts/10-02-01-Test-Driven-Development.md similarity index 100% rename from _posts/09-02-01-Test-Driven-Development.md rename to _posts/10-02-01-Test-Driven-Development.md diff --git a/_posts/09-03-01-Behavior-Driven-Development.md b/_posts/10-03-01-Behavior-Driven-Development.md similarity index 100% rename from _posts/09-03-01-Behavior-Driven-Development.md rename to _posts/10-03-01-Behavior-Driven-Development.md diff --git a/_posts/09-04-01-Complementary-Testing-Tools.md b/_posts/10-04-01-Complementary-Testing-Tools.md similarity index 100% rename from _posts/09-04-01-Complementary-Testing-Tools.md rename to _posts/10-04-01-Complementary-Testing-Tools.md diff --git a/_posts/10-01-01-Servers-and-Deployment.md b/_posts/11-01-01-Servers-and-Deployment.md similarity index 100% rename from _posts/10-01-01-Servers-and-Deployment.md rename to _posts/11-01-01-Servers-and-Deployment.md diff --git a/_posts/10-02-01-Platform-as-a-Service.md b/_posts/11-02-01-Platform-as-a-Service.md similarity index 100% rename from _posts/10-02-01-Platform-as-a-Service.md rename to _posts/11-02-01-Platform-as-a-Service.md diff --git a/_posts/10-03-01-Virtual-or-Dedicated-Servers.md b/_posts/11-03-01-Virtual-or-Dedicated-Servers.md similarity index 100% rename from _posts/10-03-01-Virtual-or-Dedicated-Servers.md rename to _posts/11-03-01-Virtual-or-Dedicated-Servers.md diff --git a/_posts/10-04-01-Shared-Servers.md b/_posts/11-04-01-Shared-Servers.md similarity index 100% rename from _posts/10-04-01-Shared-Servers.md rename to _posts/11-04-01-Shared-Servers.md diff --git a/_posts/10-05-01-Building-your-Application.md b/_posts/11-05-01-Building-your-Application.md similarity index 100% rename from _posts/10-05-01-Building-your-Application.md rename to _posts/11-05-01-Building-your-Application.md diff --git a/_posts/11-01-01-Caching.md b/_posts/12-01-01-Caching.md similarity index 100% rename from _posts/11-01-01-Caching.md rename to _posts/12-01-01-Caching.md diff --git a/_posts/11-02-01-Bytecode-Cache.md b/_posts/12-02-01-Bytecode-Cache.md similarity index 100% rename from _posts/11-02-01-Bytecode-Cache.md rename to _posts/12-02-01-Bytecode-Cache.md diff --git a/_posts/11-03-01-Object-Caching.md b/_posts/12-03-01-Object-Caching.md similarity index 100% rename from _posts/11-03-01-Object-Caching.md rename to _posts/12-03-01-Object-Caching.md diff --git a/_posts/12-01-01-Resources.md b/_posts/13-01-01-Resources.md similarity index 100% rename from _posts/12-01-01-Resources.md rename to _posts/13-01-01-Resources.md diff --git a/_posts/12-02-01-Frameworks.md b/_posts/13-02-01-Frameworks.md similarity index 100% rename from _posts/12-02-01-Frameworks.md rename to _posts/13-02-01-Frameworks.md diff --git a/_posts/12-03-01-Components.md b/_posts/13-03-01-Components.md similarity index 100% rename from _posts/12-03-01-Components.md rename to _posts/13-03-01-Components.md diff --git a/_posts/13-01-01-Community.md b/_posts/14-01-01-Community.md similarity index 100% rename from _posts/13-01-01-Community.md rename to _posts/14-01-01-Community.md