I have a bone to pick with dependency injection. It seems like such a simple concept has led to a lot of confusion amongst many, and the 'right' way to it seems to spiral out of control in terms of complexity. In keeping things really simple I just want to know:
Is it good practice if I use standard functions to register my dependencies, like this:
function someObject() {
return new someObject();
}
And can I pass parameters?
function someObject($param1) {
return new someObject($param1);
}
Finally how about using a simple custom container class:
class Dependencies {
function someObject($param1) {
return new someObject($param1);
}
}
And using it:
class SomeClass {
public function __construct(Dependencies $dependencies) {
$this->dependencies = $dependencies
}
public function methodNeedsDependency() {
$param1 = 'one';
$task = $this->dependencies->someObject($param1);
}
}
I guess what I'm asking is, is this a decent attempt at a very simple implementation of a DIC? Or are there some underlying major issues bubbling under the surface?
Thanks!
If SomeClass is a factory, designed to create some instance with some exact config given, then yes, we could say this is very simple implementation of DIC.
Issues here? Well, let's say You want to create someObject with other constructor params.
Solutions:
Create another SomeClass factory that will pass other params. It's redundant solution that also mixes two application layers ( config with object creation layer ).
Parametrize methodNeedsDependency with params that will be passed to someObject. It's something that allows You to postpone in code config creation.
and last but the most proper way: DIC should be flexible, should allow You to create any service instances with any dependencies, and all of configuration should be stored in configuration layer. Separation of concerns - try to make DIC unaware of what object type is creating. Just let him make objects that You described somewhere else.
There are a lot of other issues also, like for example what if You would like to have only one instance of given class for whole DIC ( it's easy to "if" it, but that's another workaround to proper solution ) or what with circular references.
This discussion can go on and on with other issues about architecture in general, like "services should be stateless" what makes it unnecesary to have more then one, but answer to your question are those 3 points. Of course remember it's not ultimate-mega-hiper answer for DIC. It's just my way of seeing it ;-)
Related
I like to know what the advantages to putting the logic in separate classes rather than putting all the logic in the RuleManager class.
For example
Separate the classes for each responsibility
class RuleManager {
public function create(string $name)
{
return (new CreateRuleCommand($name));
}
public function list()
{
return new ListRulesCommand();
}
}
vs:
class RuleManager {
public function create(string $name)
{
// Do all the create logic Here
return $something
}
public function list()
{
// Add all the listing Logic Here
return $something
}
}
There is no any advantages in the first class because commands just instantiated there. So it's possible to avoid using RuleManager easily (just by instantiating command class instead of calling create or list method). Even if we will use Factory pattern instead of direct classes creation, we still don't need RuleManager at all.
If all the methods in a class only return new instances of another classes -- without any additional logic -- probably something is wrong in the class (except some specific cases if adapter or proxy is required).
Another problem of Rule Manager is using coincidental cohesion -- methods there are probably grouped without any relations. It's worst case of cohesion (for example, you can read Steve McConnel's Code Complete) -- so it will be better to avoid it.
Generally, the major advantage of keeping logic in separate classes is changing/swapping that logic easily and of course it will decrease coupling significantly. For example, this way is extremely common when Strategy pattern is used -- so in that case, we keep the logic (strategies) in external classes, and can change particular strategy easily (of course we need to inject the strategy instead of instantiating it).
As I see it, for this particular structure, the only benefit, that you gain by employing this type of separate classes, would be limited adherence to OCP.
That means, if one of your "commands" have to change the logic, the "Rule Manager" is not actually affected.
To be honest, I dislike both options. But use of those "command" classes comes with logic in either __construct() or __invoke() methods. That will be quite hard to test. And and they are actually really fragile. A minor change in dependencies will still meant, that your "rule manager" has to also be altered. And you have no way to extend or replace those commands, without causing similar changes.
My advice would be actually to drop the entire structure and examine, whether there is a better solution. And try not to blindly focus on design patterns, because they are not recipes, but just short-hands, to describe what you have already written.
P.S.
The "manager" in RuleManger should be pronounced as "hmmm".
We have to implement a factory able to create several complex objects.
How should we handle it with dependency injection ?
I already read many topics about it in stackoverflow (and elsewhere), particularly the ones of Mark Seemann but can't take any decision so need your opinion.
For example:
<?php
class EventFactory
{
public function createEvent($type)
{
switch ($type) {
case 'upload':
return new UploadEvent(new FtpUploader(), new Mailer());
case 'download':
return new DownloadEvent(new FtpDownloader(), new Mailer());
case 'save':
return new SaveEvent(new EventDbModel());
case 'load':
return new LoadEvent(new EventDbModel());
case 'notify':
return new NotifyEvent(new HttpRequester());
}
}
}
I found some solutions but don't know which one to choose.
A solution would be, like in the example, to give to the factory the responsibility to instantiate the dependencies.
Problems: The same ones as not using depency injection.
Another one is to give dependencies to the factory constructor
Problems: There will be a lot of parameters in the constructors and the list can grow up
A third solution that I also found in internet is to create kind of builders instead of events. The factory keeps the responsibility to know which kind of object to create and the builders will know how to create them.
Problems: Is the role of the builder DP to handle dependencies? I'm afraid to get the same issues as solution #1.
What should we do ?
Ben
Personally I would go with option 2. Builders are usually used when you want to configure the building but hide the implementation from the client. When you only have to pass the parameters then a factory is usually better.
If you are worried about the number of parameters then you could either pass a parameter object to the factory, or produce single responsibility factories which each know the type of thing they create and how to create it and then assemble them into a chain of responsibility, asking each one if it can create the requested type and passing it along if it can't, or even just a simple list
of 'single type factory' instances.
That way each 'factory' only has the dependencies it needs, and the chain simply orchestrates the available factories and so only needs dependencies on them, knowing nothing about what dependencies they have.
Not using the chain of responsibility is simpler. Some solution like this:
public class EventFactory
{
IEnumerable<ISingleTypeEventFactory> factories
public EventFactory(IEnumerable<ISingleTypeEventFactory> factories)
{
this.factories = factories;
}
public Event CreateEvent($type)
{
foreach(factory in factories)
{
if (factory.CanHandleType($type))
{
return factory.CreateEvent($type);
}
}
}
}
My code is located here: https://github.com/maniator/SmallFry
Should I make it so that that the App class does not have to use static functions but at the same time be able to set and set variables for the app from anywhere?
Or should I keep it how it is now with App::get and App::set methods?
What are the advantages and disadvantages of both?
How would I accomplish that 1st task if I was to undertake it?
Related Question
Sample code:
//DEFAULT TEMPLATE
App::set('APP_NAME', 'SmallVC');
//END DEFAULT TEMPLAT
//
//DEFAULT TEMPLATE
App::set('DEFAULT_TEMPLATE', 'default');
//END DEFAULT TEMPLATE
//DEFAULT TITLE
App::set('DEFAULT_TITLE', 'Small-VC');
//END DEFAULT TITLE
//LOGIN SEED
App::set('LOGIN_SEED', "lijfg98u5;jfd7hyf");
//END LOGIN SEED
App::set('DEFAULT_CONTROLLER', 'AppController');
if(App::get('view')){
$template_file = $cwd.'/../view/'.App::get('view').'/'.App::get('method').'.stp';
if(is_file($template_file)){
include $template_file;
}
else {
include $cwd.'/../view/missingview.stp'; //no such view error
}
}
else {
App::set('template', 'blank');
include $cwd.'/../view/missingfunction.stp'; //no such function error
}
I think you have a feeling that static is bad. What I am posting may seem fairly crazy as it is a massive change. At the very least hopefully it presents a different idea of the world.
Miško Hevery wrote static methods are a death to testability.
I like testing, so for that reason I don't use them. So, how else can we solve the problem? I like to solve it using what I think is a type of dependency injection. Martin Fowler has a good but complicated article on it here.
For each object at construction I pass the objects that are required for them to operate. From your code I would make AppController become:
class AppController
{
protected $setup;
public function __construct(array $setup = array())
{
$setup += array('App' => NULL, 'Database' => NULL);
if (!$setup['App'] instanceof App)
{
if (NULL !== $setup['App'])
{
throw new InvalidArgumentException('Not an App.');
}
$setup['App'] = new App();
}
// Same for Database.
// Avoid doing any more in the constructor if possible.
$this->setup = $setup;
}
public function otherFunction()
{
echo $this->setup['App']->get('view');
}
}
The dependancies default to values that are most likely (your default constructions in the if statements). So, normally you don't need to pass a setup. However, when you are testing or want different functionality you can pass in mocks or different classes (that derive from the right base class). You can use interfaces as an option too.
Edit The more pure form of dependency injection involves further change. It requires that you pass always pass required objects rather than letting the class default one when the object isn't passed. I have been through a similar change in my codebase of +20K LOC. Having implemented it, I see many benefits to going the whole way. Objects encapsulation is greatly improved. It makes you feel like you have real objects rather than every bit of code relying on something else.
Throwing exceptions when you don't inject all of the dependencies causes you to fix things quickly. With a good system wide exception handler set with set_exception_handler in some bootstrap code you will easily see your exceptions and can fix each one quickly. The code then becomes simpler in the AppController with the check in the constructor becoming:
if (!$setup['App'] instanceof App)
{
throw new InvalidArgumentException('Not an App.');
}
With every class you then write all objects would be constructed upon initialisation. Also, with each construction of an object you would pass down the dependencies that are required (or let the default ones you provide) be instantiated. (You will notice when you forget to do this because you will have to rewrite your code to take out dependencies before you can test it.)
It seems like a lot of work, but the classes reflect the real world closer and testing becomes a breeze. You can also see the dependencies you have in your code easily in the constructor.
Well, if it was me, I would have the end goal of injecting the App dependency into any class (or class tree) that needs it. That way in testing or reusing the code you can inject whatever you want.
Note I said reuse there. That's because it's hard to re-use code that has static calls in it. That's because it's tied to the global state so you can't really "change" the state for a subrequest (or whatever you want to do).
Now, on to the question at hand. It appears that you have a legacy codebase, which will complicate things. The way I would approach it is as follows:
Create a non-static version of the app class (name it something different for now) that does nothing but proxy its get/set calls to the real app class. So, for example:
class AppProxy {
public function set($value) {
return App::set($value);
}
}
For now, all it has to do is proxy. Once we finish getting all the code talking to the proxy instead of the static app, we'll make it actually function. But until then, this will keep the application running. That way you can take your time implementing these steps and don't need to do it all in one big sweep.
Pick a main class (one that does a lot for the application, or is important) that you easily control the instantiation of. Preferably one that you instantiate in only one place (in the bootstrap is the easiest). Change that class to use Dependency Injection via the constructor to get the "appproxy".
a. Test this!
Pick another class tree to work on, based on what you think will be most important and easiest.
a. Test!!!
If you have more calls to App::, Go to #3
Change the existing App class to be non-static.
a. Test!!!!!!!!!!
Remove the AppProxy and replace with App in the dependency injectors. If you did it right, you should only have one place to change to make this switch.
Pat yourself on the back and go get a drink, cause you're done.
The reason that I segmented it out like this is that once a step is completed (any step), you can still ship working software. So this conversion could take literally months (depending on the size of your codebase) without interrupting business as usual...
Now, once you're done, you do get some significant benefits:
Easy to test since you can just create a new App object to inject (or mock it as needed).
Side effects are easier to see since the App object is required wherever it could be changed.
It's easier to componentize libraries this way since their side effects are localized/
It's easier to override (polymorphism) the core app class if it's injected than if it's static.
I could go on, but I think it's pretty easy to find resources on why statics are generally bad. So that's the approach I would use to migrate away from a static class to an instance...
If you don't want to have static functions but global access from everywhere WITHOUT passing the object to the places where it is actually needed then you pretty much can only use one thing:
A global variable
So you are not really better of doing that. But that is the only thing i can think of that would fulfill your requirements.
If you App object is something like an application config a first possible step would be to pass it to the objects that need it:
class Login {
public function __construct() {
$this->_login_seed = App::get('LOGIN_SEED');
self::$_ms = Database::getConnection();
}
changes into:
class Login {
public function __construct(App $app) {
$this->_login_seed = $app->get('LOGIN_SEED');
self::$_ms = Database::getConnection();
}
I'm building out a small project to try to teach myself as much of the fundamentals as possible, which for me means not using a prefabricated framework (As Jeff once put it, "Don't reinvent the wheel, unless you plan on learning more about wheels" [emphasis mine]) and following the principles of Test Driven Development.
In my quest, I recently ran into the concept of Dependency Injection, which appears essential to TDD. My problem is that I can't quite wrap my head around it. My understanding so far is that it more or less amounts to "have the caller pass the class/method any other classes it may need, rather than letting them create them themselves."
I have two example issues that I'm trying to resolve with DI. Am I on the right track with these refactorings?
Database Connection
I'm planning to just use a singleton to handle the database, as I'm currently not expecting to use multiple databases. Initially, my models were going to look something like this:
class Post {
private $id;
private $body;
public static function getPostById($id) {
$db = Database::getDB();
$db->query("SELECT...");
//etc.
return new Post($id, $body);
}
public function edit($newBody) {
$db = Database::getDB();
$db->query("UPDATE...");
//etc.
}
}
With DI, I think it would look more like this:
class Post {
private $db; // new member
private $id;
private $body;
public static function getPostById($id, $db) { // new parameter
$db->query("SELECT..."); // uses parameter
//etc.
return new Post($db, $id, $body);
}
public function edit($id, $newBody) {
$this->db->query("UPDATE..."); // uses member
//etc.
}
}
I can still use the singleton, with credentials specified in the application setup, but I just have to pass it from the controller (controllers being un-unit-testable anyway):
Post::getPostById(123, Database::getDB);
Models calling models
Take, for example, a post which has a view count. Since the logic to determine if a view is new isn't specific to the Post object, it was just going to be a static method on its own object. The Post object would then call it:
class Post {
//...
public function addView() {
if (PageView::registerView("post", $this->id) {
$db = Database::getDB();
$db->query("UPDATE..");
$this->viewCount++;
}
}
With DI, I think it looks more like this:
class Post {
private $db;
//...
public function addView($viewRegistry) {
if ($viewRegistry->registerView("post", $this->id, $this->db) {
$this->db->query("UPDATE..");
$this->viewCount++;
}
}
This changes the call from the controller to this:
$post->addView(new PageView());
Which means instantiating a new instance of a class that only has static methods, which smells bad to me (and I think is impossible in some languages, but doable here because PHP doesn't allow classes themselves to be static).
In this case we're only going one level deep, so having the controller instantiate everything seems workable (although the PageView class is getting its DB connection indirectly by way of the Post's member variable), but it seems like it could get unwieldy if you had to call a method that needed a class that needed the class that needed a class. I suppose that could just mean that's a code smell too though.
Am I on the right track with this, or have I completely misunderstood DI? Any criticisms and suggestions are greatly appreciated.
Yes. It looks like you have the right idea. You'll see that as you implement DI all your dependencies will float to the "top". Having everything at the top will make it easy to mock the necessary objects for testing.
Having a class that needs a class that needs a class is not a bad thing. What your describing there is your object graph. This is normal for DI. Lets take a House object as an example. It has a dependency on a Kitchen; the Kitchen has a dependency on a Sink; the Sink has a dependency on a Faucet and so on. The House's instantiation would look something like new House(new Kitchen(new Sink(new Faucet()))). This helps to enforce the Single Responsibility Principle. (As an aside you should do this instantiation work in something like a factory or builder to further enforce the Single Responsibility Principle.)
Misko Hevery has written extensively about DI. His blog is a great resource. He's also pointed out some of the common flaws (constructor does real work, digging into collaborators, brittle global state and singletons, and class does too much) with warning signs to spot them and ways to fix them. It's worth checking out sometime.
Dependency injection is about injecting. You need some solution to inject the external object.
The traditional approaches are:
constructor injection __construnctor($dependecy) {$this->_object = $dependency}
setter injection setObject($dependency) {$this->_object = $dependency}
gettter injection getObject() {return $this->_dependency} and oveloading this method eg. from stub or mock in the tests.
You may also mix all the above, depends what you need.
Avoid static calls. My personal rule is use static only when you call some functions, e.g. My::strpos() or when dealing with singletons or registry (which should be limited to minimum, because global state is evil).
You will rarely need static methods when your app has a good dependency container.
Take a look at the other dependency injection + [php] topics on SO.
Edit after comment:
The container
Different frameworks handle the container in different way. Generally this is an object, which holds the instances of objects you need, so you don't have to instantiate new object each time. You may register any object with such a container, and then access it anytime you need.
The container may instantiate all the resources you need at boot time, or lazy load the resource when accessed (better solution).
As an example, consider:
Zend Application Resource Plugins
Symfony Dependency Injection Container
Another great reference:
http://martinfowler.com/articles/injection.html
It's certainly going into the right direction but you should not stop there.
The point of DI is to remove strong couplings between classes to allow for easier substitution of single components. This will allow for better testability because you can substitute dependencies more easily with Mocks and Stubs. And once your code is tested, it is much easiert to change and maintain.
Consequently, you should also remove those other aspects in your code that create strong coupling smells as well, e.g. remove the static methods and the singleton and any other globals.
For some more information on that, please see
How is testing the registry pattern or singleton hard in PHP?
http://gooh.posterous.com/singletons-in-php
http://kore-nordmann.de/blog/0103_static_considered_harmful.html
http://fabien.potencier.org/article/11/what-is-dependency-injection
EDIT: with a couple of others answers suggesting to use a DI container, I feel it's necessary to stress that you do not need a DI container to do DI. The second blog post in the last link given above discusses this.
To answer your questions: yes, you are on the right track. To give you more details: this is one of the best posts I found related to DI:
http://www.potstuck.com/2009/01/08/php-dependency-injection
You will understand what a container is:
$book = Container::makeBook();
Regarding the second example: in your method addView I would try to avoid passing the object $viewRegistry, I would check the condition outside in the controller.
I hear people talking about dependency injection and the benefit of it all the time, but I don't really understand it.
I'm wondering if it's a solution to the "I pass database connections as arguments all the time" problem.
I tried reading wikipedia's entry on it, but the example is written in Java so I don't solidly understand the difference it is trying to make clear. ( http://en.wikipedia.org/wiki/Dependency_injection ).
I read this dependency-injection-in-php article ( http://www.potstuck.com/2009/01/08/php-dependency-injection/ ), and it seems like the objective is to not pass dependencies to an object directly, but to cordon off the creation of an object along with the creation of it's dependencies. I'm not sure how to apply that in a using php functions context, though.
Additionally, is the following Dependency Injection, and should I bother trying to do dependency injection in a functional context?
Version 1: (the kind of code that I create, but don't like, every day)
function get_data_from_database($database_connection){
$data = $database_connection->query('blah');
return $data;
}
Version 2: (don't have to pass a database connection, but perhaps not dependency injection?)
function get_database_connection(){
static $db_connection;
if($db_connection){
return $db_connection;
} else {
// create db_connection
...
}
}
function get_data_from_database(){
$conn = get_database_connection();
$data = $conn->query('blah');
return $data;
}
$data = get_data_from_database();
Version 3: (the creation of the "object"/data is separate, and the database code is still, so perhaps this would count as dependency injection?)
function factory_of_data_set(){
static $db_connection;
$data_set = null;
$db_connection = get_database_connection();
$data_set = $db_connection->query('blah');
return $data_set;
}
$data = factory_of_data_set();
Anyone have a good resource or just insight that makes the method and benefit -crystal- clear?
Dependency injection is a big word for "I have some more parameters in my constructor".
It's what you did before the awfull Singleton wave when you did not like globals :
<?php
class User {
private $_db;
function __construct($db) {
$this->_db = $db;
}
}
$db = new Db();
$user = new User($db);
Now, the trick is to use a single class to manage your dependencies, something like that :
class DependencyContainer
{
private _instances = array();
private _params = array();
public function __construct($params)
{
$this->_params = $params;
}
public function getDb()
{
if (empty($this->_instances['db'])
|| !is_a($this->_instances['db'], 'PDO')
) {
$this->_instances['db'] = new PDO(
$this->_params['dsn'],
$this->_params['dbUser'],
$this->_params['dbPwd']
);
}
return $this->_instances['db'];
}
}
class User
{
private $_db;
public function __construct(DependencyContainer $di)
{
$this->_db = $di->getDb();
}
}
$dependencies = new DependencyContainer($someParams);
$user = new User($dependencies);
You must think you just another class and more complexity. But, your user class may need something to log messages like lot of other classes. Just add a getMessageHandler function to your dependency container, and some $this->_messages = $di->getMessageHandler() to your user class. Nothing to change in the rest of your code.
You'll get lot of infos on symfony's doc
Your first example IS dependancy injection, you are injecting the dependency on the database object into the function.
Sarah has said this isn't, but imo it is, I believe she is thinking of dependency injection containers which are the next level up:
http://components.symfony-project.org/dependency-injection/trunk/book/02-Dependency-Injection-Containers
None of your examples look like dependency injection, version one is the closest though. Dependency injection is a technique used in object oriented programming, where the constructor of an object has arguments for the service objects it needs, and those service objects are passed in by the creator of the instance (which could be a factory, a test, or a dependency injection framework).
To get around your 'always passing the connection object' problem you may want to consider the template pattern. The template pattern is basically an abstract base class with the common part of a repeated code block, and abstract methods to allow for the variation between the instances of those repeated code blocks. Basically the base is a template of a block of code, and the abstract methods are the blanks to be filled in. I personally use the template method pattern to do my database resource control in Java.
I have done much searching on this topic myself (PHP Dependency Injection) and haven't found much to my liking. A lot has been written on the subject for other languages (Google Guice - http://code.google.com/p/google-guice/ ; Java Spring), but I couldn't find much available for PHP. Regardless of the language, however, the challenges are similar.
The three versions you list in your question are the typical approach. Version 3 is the closest to the direction in which I have seen the industry going. By shifting the responsibility of creating your dependent objects outside of your class, you are free to manipulate them as you please in your test code. However, the problem that I encountered with that approach is that you end up with long chains of dependent objects in your constructor that can potentially not even be used by the receiving object, but get passed through to an secondary dependent object. It gets messy and you lose knowledge of what is coming from where.
The Dependency Container example by #Arkh and #mmmshuddup is a great start, but I nonetheless found limitations with that approach as well. The final solution upon which I arrived was a custom built solution modeled somewhat after the Cake Pattern popular in Scala. It allows you to pass a single dependency into each of your constructors AND it lets you define the default construction of the dependent objects per class. This frees you from long dependency chains as well as losing control of the default implementations of your dependencies.
I called the system Diesel and I've been really happy with it. I published the code on github for anyone interested. You can get to it from the blog I wrote on the subject, which describes the basic usage as well as goes into more detail on your question. http://developers.blog.box.com/2012/02/15/introducting-diesel-php-dependency-injection/
Dependency Injection is the idea of removing the dependency between 2 components in order to focus on why they are dependent.
Imagine you have a component A that needs to use the services of another component B.
If you hardcode the existence of B inside A, then you will be stuck when you will want A to use the sames services, but implemented by another component.
So usually, you define a service interface that B and C will implement, and you make sure that when you use A, you feed it with objects compatible with the needed interface.
In your case, you might consider that your interface is a service on which you can make a query.
Your first case is the one that is the closer to the idea of Dependency Injection.