I got a huge Symfony project. I created many service and subservices to epurate the Controller and Services code.
In my code i instantiate these services with:
$this->get('MyServiceName')->myMethod($foo);
One of my coworker use the new keyword to instantiate the class:
$myservice = new Service();
$refid = $myservice->mymethod($foo);
So i wondering, is it a best practice? Should i rewrite that codeĀ ? What are the impact of this kind of code on the maintenability and the performance of the application?
If the service is defined in the Ioc container, then by all means use it from there, because it will be constructed by the container. It takes the responsibility of instantiating new classes away from the developer. If the explicit dependencies change, you will only need to change them in container, not hunt them in the whole project code. This also in most cases has the performance benefit, because some classes need to be instantiated only once. In any way, talk to your co-worker, why he does it like this.
I always use the first way (ie. using the service container) because with Symfony's dependency injection you don't need to worry about dependecies and/or parameters; I've never used the second way (ie. instantiating a service "by hand" with the new keyword) and I'm pretty sure that it is the worst way.
By the way, you should check out the official "best practices" guide and these blog posts by Fabien Potencier.
When should I use singleton pattern and static (static methods and static properties)?
I have read many blogs/ tutorials/ comments that always say that singleton pattern so I never use it.
But again, there are many php frameworks are using singletons, such as Laravel which is getting more and more popular these days.
For an example, in Laravel,
$app->singleton(
'Illuminate\Contracts\Http\Kernel',
'App\Http\Kernel'
);
$app->singleton(
'Illuminate\Contracts\Console\Kernel',
'App\Console\Kernel'
);
$app->singleton(
'Illuminate\Contracts\Debug\ExceptionHandler',
'App\Exceptions\Handler'
);
If you check it through, you can singleton is heavily used in Laravel (it seems). So what is going on?
Singleton is the first letter in STUPID that we should avoid as far as understand.
But I believe that some programmers will strongly disagree - Its the best way to do it in that situation - if you need to use them, use them. Simple as that.
So, in what situations then you should use singletons if you disagree with STUPID?
Also, in Laravel, you see lots of these,
$users = DB::table('users')->get();
It is either a singleton or a static method I guess (I am not very good at Laravel - just beginning to look into it).
It seems easy to use, but what about in testing, are they going to be difficult to test?
I see this method (DB::something(...)) a lot in other framework as well. They seem not a good idea but many would disagree too I believe. So in what situations you should use static methods then?
I would suggest that the best use of a singleton, which makes practical sense, is when you need to configure a resource that is costly to build.
In most cases, you'll find frameworks tend to create a singleton around database connections. This allows the resource of the database connection to be reused across the framework without having to rebuild the connection with the configurations every query.
The way laravel uses static methods like DB::table is that it will just be a wrapper around the singleton, or as they like to call it, an Inversion of Control Container (http://laravel.com/docs/4.2/ioc). The purpose there is to allow you to have a static interface for which you can change out the back-end singleton provider, should you need to use a different resource.
To answer the last part, the best purpose of a static method, would be either to run some computation over static or constant properties of the class which do not need an instance to exist (consider Java: when to use static methods).
I didn't find a similar question, so I apologize if it already exists.
In my system I want a number of function libraries to ease a number of tasks across the whole system. That could be validating an e-mail. There's no reason to write the full regular expression each time if I can have a function do it, so I only need to change things and fix errors in one place.
Say I write a class called Files_Tools.
I can make it work both by dependency injecting an instance of this class into the objects that needs functions from this class. But I can also write the Files_Tools class with static functions and access them with the scope resolution operator. But as I have come to understand one of the major things about DI (dependency injection) is to avoid this kind of "global use". So my logic tells me to go with the DI approach. Yet, it still doesn't feel "right" that I'm doing it this way.
So my question is - What is regarded as the most correct way to create a toolset for a system? First of all, is it to make it as a class, instead of just plain functions? And then if it really is a class is the way to go, should I aim for the SRO or DI?
I understand there is probably not a definitive answer to this question, but I want to know if I'm completely off track or heading where many other coders would have done too.
Thanks in advance :)
DI makes it easier to unit test your classes and methods without dependency on the injected class... you can mock the injected object and manipulate its returns as appropriate for your tests. Scope resolution leaves you with this dependency so the tests aren't fully isolated.
Many of my earlier projects use static classes for such functionality, and trying to write unit tests for them 6 years on is now a real chore because I didn't use DI.
Normally when I need to inject one or more services into another service, I explicitly inject each one. However, I have a situation where injecting the service container itself will really make things easier. I know this is not a recommended practice, but I'm curious what the technical reasons are for discouraging this. Is it something legitimate like it's too resource intensive, or a more personal feeling that it's too messy?
If you inject the container, you're not making dependencies clear. In fact, you're obscuring them more than before. If you have a class like this...
class DocumentCreator(IFileNamer fileNamer, IRepository repository)
{ ... }
...you can see what the dependencies are. You can also easily mock those dependencies for unit testing, to ensure that you isolate the DocumentCreator and can know that any test failures are a result of its code rather than code in one of its dependencies.
If, on the other hand, you do this...
class DocumentCreator(IDependencyContainer container)
{ ... }
...you've obscured the dependencies. You can't know, without examining the internals of the class, that it requires an IFileNamer and an IRepository.
Nor can you easily know what mocks you need to put in the container in order to test DocumentCreator. Mocking the IDependencyContainer won't help you at all; your class will still fail in testing because the container won't contain an IFileNamer and an IRepository, unless you examine the internals of the class to see that they're required.
What you describe is a ServiceLocator. This is considered an anti-pattern in modern application design. This article describes why.
I think the main problem with this approach is that you don't see the dependencies clearly anymore. Another problem might be that it is more difficult to test.
How to solve the problem of composing a Controller class in PHP, which should be:
easily testable by employing Dependency Injection,
provide shared objects for end programmer
provide a way to load new user libraries
Look down, for controller instantiation with a Dependency injection framework
The problem is, that derived Controllers may use whatever resources the programmer wants to (eg. the framework provides). How to create a unified access to shared resources (DB, User, Storage, Cache, Helpers), user defined Classes or another libraries?
Elegant solution?
There are several possible solutions to my problem, but neither one looks to be a elegant
Try to pass all shared objects by constructor? (may create constructor even with 10 placeholders)
Create getters, settters? (bloated code) $controller->setApplication($app)
Apply singletons on shared resources? User::getInstance() or Database::getInstance()
Use Dependency Injection container as a singleton for object sharing inside the controller?
provide one global application singleton as a factory? (this one looks very used in php frameworks, hovewer it goes strongly against DI principles and Demeter's law)
I understand, that creating strongly coupled classes is discouraged and banished for :), however I don't know how this paradigm applies to a starting point for other programmers (a Controller class), in which they should be able to access shared resources provided to the MVC architecture. I believe, that breaking up the controller class into smaller classes would somehow destroy the practical meaning of MVC.
Dependency Injection Framework
DI Framework looks like a viable choice. However the problem still persists. A class like Controller does not reside in the Application layer, but in the RequestHandler/Response layer.
How should this layer instantiate the controller?
pass the DI injector into this layer?
DI Framework as a singleton?
put isolated DI framework config only for this layer and create separate DI injector instance?
Are you developing a framework yourself? If not, your question does not apply, because you have to choose from already existing frameworks and their existing solutions. In this case your question must be reformulated like "how do I do unit testing/dependency injection in framework X".
If you are developing a framework on you own, you should check first how already existing ones approach this issue. And you must also elaborate your own requirements, and then just go with the simplest possible solution. Without requirements, your question is purely aesthetic and argumentative.
In my humble opinion the simplest solution is to have public properties which initialize to defaults provided by your framework, otherwise you can inject your mocks here. (This equals to your getters/setters solution, but without the mentioned bloat. You do not always need getters and setters.) Optionally, if you really need it, you may provide a constructor to initialize those in one call (as you suggested).
Singletons are an elegant solution, but again, you must ask yourself, is it applicable in your case? If you have to have different instances of the same type of object in your application, you can't go with it (e.g. if you wish to mock a class only in half of your app).
Of course it is really awesome to have all the options. You can have getters/setter, constructors, and when initialization is omitted, default are taken from a singleton factory. But having too many options when not needed, is not awesome, it is disturbing as the programmer has to figure out which convention, option and pattern to use. I definitely do not want to make dozens of design decisions just to get a simple CRUD running.
If you look at other frameworks you will see that there is no silver bullet. Often a single framework utilizes different techniques depending on the context. In controllers, DI is a really straightforward thing, look at CakePHP's $helpers, $components variables, which instruct to inject appropriate variables into the controller class. For the application itself a singleton is still a good thing, as there is always just a single application. Properties less often changed/mocked are injected utilizing public properties.
In case of an MVC, subclassing is perfectly viable option as well: just as AppController, AppView, AppModel in CakePHP. They are inserted into the class hierarchy between the frameworks's and all your particular Controller, View and Model classes. This way you have a single point to declare globals for your main type of classes.
In Java, because of dynamic class loaders and reflection, you have even much more options to choose from. But on the other hand, you have to support much more requirements as well: parallel requests, shared objects and states between worker threads, distributed app servers etc.
You can only answer the question what is right for you, if you know what you need in the first place. But actually, why do you write just another new framework anyway?
Singletons are frowned upon when Dependency Injection is viable (and I have yet to find a case where a Singleton was necessary).
More than likely you will have control of instantiation of controllers, so you can get away with the mentioned $controller->setApplication($application), but if necessary you can use static methods and variables (which are far less harmful to the orthogonality of an application than Singletons); namely Controller::setApplication(), and access the static variables through the instance methods.
eg:
// defining the Application within the controller -- more than likely in the bootstrap
$application = new Application();
Controller::setApplication($application);
// somewhere within the Controller class definition
public function setContentType($contentType)
{
self::$application->setContentType($contentType);
}
I have made of a habit of separating static and instance properties and methods (where necessary, and still grouping properties at the top of the class definition). I feel that this is less unwieldy than having Singletons, as the classes still remain quite compact.
How about refactoring?
Granted that was not one of your options, but you state the code is a largely coupled class. Why not take this time and effort to refactor it to more modular, testable components?
As far as I understand, the Application class of yours should be the dispatcher. If so, I would rather use the controller constructor to pass an instance of the Application, so the controller would know who's invoking it. At later point if you want to have a different Application instance depending on whether the code is invoked from within CLI, you can have an ApplicationInterface which the Application\Http and Application\Cli would implement and everything would be easy to maintain.
You could also implement some factory pattern to get a nice implementation of the DI. For example, check the createThroughReflection method here: https://github.com/troelskn/bucket/blob/master/lib/bucket.inc.php
I hope this makes sense.
Regards,
Nick
You could also use a ControllerFatory in which you would give to your Application or Router/Dispatcher
Sou you could call $controllerFactory->createController($name);
Your Application would have no idea how to create your controllers the Factory would. Since you ca inject your own ControllerFactory in to your DI container you can manage all dependencies you want depending on the controller.
class ControllerFactory {
public function __construct(EvenDispatcher $dispatcher,
Request $request,
ResponseFactory $responseFactory,
ModelFactory $modelFactory,
FormFactory $formFactory) {
...
}
public function createController($name = 'Default') {
switch ($name) {
case 'User':
return new UserController($dispatcher,
$request,
$responseFactory->createResponse('Html'),
$modelFactory->createModel('User'),
$formFactory->createForm('User'),...);
break;
case 'Ajax':
return new AjaxController($dispatcher,
$request,
$responseFactory->createResponse('Json'),
$modelFactory->createModel('User'));
break;
default:
return new DefaultController($dispatcher, $request, $responseFactory->createResponse('Html'));
}
}
}
So you just need to add this factory in your DI container and pass it to your Application.
Whenever you need a new controller you add it to the factory and if new dependencies are required you give them to the factory through your DI container.
class App {
public function __construct(Router $router,Request $request, ControllerFactory $cf, ... ) {
...
}
public function execute() {
$controllerName = $this->router->getMatchedController();
$actionName $this->router->getMatchedAction();
$controller = $cf->createController($controllerName);
if(is_callable($controller, $actionName)) {
$response = $controller->$action(request);
$response->send();
}
}
}
This is not production code, I haven't tested, but this is how you decouple your controllers from your application. Notice here though that there is one bad coupling here because my controller return's a response and I execute the response in the App. But like I said this is just a small example.
It is usually a good idea to pass factories for Models, Forms, and Controllers to their respective parents, because you will end up loading all your object Graph at bootstrap time wich is really bad and memory consuming.
I know this answer was already approved, but it's my 2 cents on the subject
There is a good article on the subject
http://miller.limethinking.co.uk/2011/07/07/dependency-injection-moving-from-basics-to-container/