I have a custom framework where i have a class/method which uses my own Cache class.
Currently it is tightly coupled. So a method instantiates the Cache class like this:
public function someMethod ( )
{
$cache = new Cache\HHCache();
}
I want ro remove the tight coupling but that's actually where i'm a bit stuck.
I thought it would be a good idea to create some sort of ServiceProvider class. But i'm not sure if this is really the right approach.
To start i have HHConfig file which has a static property in which a cache class is defined. In short:
class HHConfig
{
static $_cacheClass = '\Core\Cache\HHCache';
}
So basically i have a class like this, which is part of the Core functionality of my framework:
interface IHHServiceProvider
{
public function getService ( );
}
Then i have another class which implements this interface.
class HHCacheProvider implements IHHServiceProvider
{
public static function getService ( )
{
$class = HHConfig::$_cacheClass;
return new $class();
}
}
So now someMethod can use the HHCacheProvider class to get an instance of a Cache class.
public function someMethod ( )
{
$cache = HHCacheProvider::getService ( );
}
My IHHServiceProvider isn't really like the typical Provider class since you can't really register any Services to it. It simply looks in the HHConfig class what "class" to load and returns in instance of that.
So somehow this method doesn't feel right to me, but i do think it shows what i want to achieve. In what ways can i improve this?
Please note that i'm not looking for a simple Dependency Injection pattern for this. Because i don't want to inject my Cache class to every constructors class. I need a non tight coupling way of getting an instance of the HHCache class somehow from within a method.
Some sort of provider class that can be part of my framework seems like the right direction.
Note: "provider" means nothing. There is not pattern by that name.
Instead of making some magical "privider", you should take a look at factory pattern. Basically the idea is a follows:
You inject a factory in classes that will use some services (assuming that Cache is not the only form of service that you aim for).
The class request from factory the service that it needs:
if service has been already initialized once, it just returns an instance to your
else it creates new instance, stores it and returns you to "consumer"
The simplest code example would be something like this:
class ServiceFactory
{
private $storage = [];
public function create( $name )
{
if ( false === array_key_exists( $name, $this->storage ))
{
$instance = new $name;
$this->storage[$name] = $instance;
}
return $this->storage[$name];
}
}
This is an extremely simplified example, but even in this case, if you inject an instance of this factory in any number of objects, they all will have access to same pool of instances.
If you ever decide to look into concept of DI Containers, then factories are also the place where it is appropriate to utilize them, without degrading them to as service locator anti-pattern.
.. and few lectures that you might find valuable:
The Clean Code Talks - Don't Look For Things!
The Clean Code Talks - Global State and Singletons
As per OP request
Especially since it will be part of the framework, you should inject the Cache. A DI Container is the best solution here, you can config the actually Cache implementation as a singleton. Your proposed solution is tightly coupled to some service and hard to test in isolation. Actually it looks more of a service locator pattern rather than provider.
If you're using a Factory that won't replace the DI Container. THe point of DI is that the code shouldn't be coupled to an outside static service. Unless you have a very good reason, any object should use only the injected (via constructor or as method argument) dependencies.
Related
Doctrine examples usually make use of Doctrine's $entityManager. Hence, whenever I need to do anything in my app with Doctrine, I need to get the entity manager into my code. But how? .... I can inject it into my class, but still I need to create manager somewhere first. I can also make it use PHP's trait which I put into my class to make it Doctrine-enabled.
What I have done in my OOP code is something like this -- I defined a class DoctrineConnector in its own namespace of DoctrineConnector, and inside the class I have a static function getEntityManager. Inside, I read Doctrine configuration, paths, parameters, and create an $entityManager, and then I return it to the caller.
Whenever I need to read or persist something in my Doctrine-unaware code, I do this:
//Pricing.php
use DoctrineConnector\DoctrineConnector;
class Pricing
{
public function getPricing()
{
$entityManager = DoctrineConnector::getEntityManager();
//further Doctrine code to read DB
}
}
DoctrineConnector is now a dependency of Pricing. Obvious answer may be "inject $entityManager into Pricing". But Pricing is called from another class, and that other class is called from another class, etc so I will have to make essentially every class I call be aware of the ORM variable. I want to avoid that.
Is what I currently have just fine or is there a better way?
How ZF2 module system does it
Out of curiosity I looked into how ZF2 manages Doctrine module and from DoctrineORMModule, it uses ServiceLocator pattern to call the inside of controller. So one of the leading framework module systems is not that far off from my implementation.
Singleton Pattern
Adapted from http://www.phptherightway.com/pages/Design-Patterns.html
namespace ABC;
use Doctrine\ORM\Tools\Setup;
use Doctrine\ORM\EntityManager;
class DoctrineConnector
{
private static $instance;
public static function getEntityManager()
{
if (null === static::$instance)
{
// Doctrine Config (from Docs)
include 'config/doctrine-config.php';
$config = Setup::createAnnotationMetadataConfiguration($paths, $isDevMode);
static::$instance = EntityManager::create($dbParams, $config);
}
return static::$instance;
}
protected function __construct()
{}
private function __clone()
{}
private function __wakeup()
{}
}
//to call
$em = DoctrineConnector::getEntityManager();
//if used later in the code - calls same instance
$em = DoctrineConnector::getEntityManager();
There are a couple of popular ways to get a dependency inside the class.
make the class aware of project environment and let the class locate the dependency (what you did with DoctrineConnector)
use dependency injection (what you are trying to achieve)
In your case, your class now depends on DoctrineConnector and is going to work as long as it can find DoctrineConnector. If you port your class to another project where DoctrineConnector isn't defined, your code isn't going to work.
Normally dependency injection is a decision you make when you start your new project. If you already have a large hierarchy of classes, the injection code will bubble up your hierarchy and there is going to be a lot of work refactoring your code. You might want to think wether you really need that and wether it's going to be worth your time.
If you are writing code for one particular app and have no plans to migrate it to other projects, then you probably don't care about dependency injection. Actually, without injection your code is going to be shorter and easier (faster) to write and understand. On the other hand if you have pieces of code that you want to be independent of the app, you might use dependency injection only for those code segments.
If you haven't injected ORM yet, chances are that the rest of the code is tightly coupled with your app as well, and injecting entityManager isn't going to make your code much more portable.
I have a class that is containing 10 methods. I always need to use one of those methods. Now I want to know, which approach is better?
class cls{
public function func1(){}
public function func2(){}
.
.
public function func10(){}
}
$obj = new cls;
$data = $obj->func3(); // it is random, it can be anything (func1, or func9 or ...)
OR
class cls{
public static function func1(){}
public static function func2(){}
.
.
public static function func10(){}
}
cls::func3(); // it is random, it can be anything (func1, or func9 or ...)
It is an interesting subject. I'm gonna give you a design oriented answer.
In my opinion, you should never use a static class/function in a good OOP architecture.
When you use static, this is to call a function without an instance of the class. The main reason is often to represent a service class which should not be instantiated many times.
I will give you 3 solutions (from the worst to the best) to achieve that:
Static
A static class (with only static functions) prevent you from using many OOP features like inheritance, interface implementation. If you really think of what is a static function, it is a function namespaced by the name of its class. You already have namespaces in PHP, so why add another layer?
Another big disadvantage is that you cannot define clear dependencies with your static class and the classes using it which is a bad thing for maintenability and scalability of your application.
Singleton
A singleton is a way to force a class to have only one instance:
<?php
class Singleton {
// Unique instance.
private static $instance = null;
// Private constructor prevent you from instancing the class with "new".
private function __construct() {
}
// Method to get the unique instance.
public static function getInstance() {
// Create the instance if it does not exist.
if (!isset(self::$instance)) {
self::$instance = new Singleton();
}
// Return the unique instance.
return self::$instance;
}
}
It is a better way because you can use inheritance, interfaces and your method will be called on an instanciated object. This means you can define contracts and use low coupling with the classes using it. However some people consider the singleton as an anti pattern especially because if you want to have 2 or more instances of your class with different input properties (like the classic example of the connection to 2 different databases) you cannot without a big refactoring of all your code using the singleton.
Service
A service is an instance of a standard class. It is a way to rationalize your code. This kind of architecture is called SOA (service oriented architecture). I give you an example:
If you want to add a method to sell a product in a store to a consumer and you have classes Product, Store and Consumer. Where should you instantiate this method? I can guarantee that if you think it is more logical in one of these three class today it could be anything else tomorrow. This leads to lots of duplications and a difficulty to find where is the code you are looking for. Instead, you can use a service class like a SaleHandler for example which will know how to manipulate your data classes.
It is a good idea to use a framework helping you to inject them into each others (dependency injection) in order to use them at their full potential. In the PHP community, you have a nice example of implementation of this in Symfony for instance.
To sum up:
If you do not have a framework, singletons are certainly an option even if I personally prefer a simple file where I make manual dependency injection.
If you have a framework, use its dependency injection feature to do that kind of thing.
You should not use static method (in OOP). If you need a static method in one of your class, this means you can create a new singleton/service containing this method and inject it to the instance of classes needing it.
The answer depends on what those methods do. If you're using them to mutate the state of the object at hand, you need to use the instance method calls. If they're independent functionality, then you can use the static versions, but then I'd question why they're part of a class at all.
So, there is a very basic difference in static methods.
To use static functions, you don't need to initialise the class as an object. For example, Math.pow(), here .pow() (in Java; but the explanation still holds) is a static method.
The general rule is to make the helper methods static.
So, for example, if you have a Math class, you wouldn't want to fill the garbage collector with classes which just help other, more important, classes.
You can use it as dynamic initializers, if you please!
Let's say you have a class RSAEncryptionHelper, now you can generally initialize it without any parameters and this will generate an object with a key size of (say) 512 bits; but you also have an overloaded object constructor which gets all of the properties from other classes:
$a = new RSAEncryptionHelper::fromPrimeSet(...);
Within a PHP class you can use class/methods/attributes: Abstract, Static, Private, Public, etc ...
The best way is to know how to mix them all within a class depending on the need, I will give you a basic example:
Within the Person class, you have private and public methods, but you have a method called "get_nationality" so this is a function that you need somewhere else but you do not have the Person class installed yet, so this method you put it as STATIC in this way you can invoke the "get_nationality" method without installing any Person class, this makes your business model more optimal and in turn now resources in the CPU.
Static functions are also very useful but
I usually make traits when I have to create functions that are independently related to a class.
I don't know if this approach is better or not but most times I found it useful.
Just sharing my approach here so that I can learn more about its pros and cons.
You can think a factory. You will give some materials, it will give you same output. Then you should use static function.
class ProductDetails
{
public static function getRow($id, PDO $pdo): SingleProduct
{
// this function will return an Object.
}
}
I am not defining the Object here. Just where you need a Single Product you can simply do that ProductDetails::getRow(10, $pdo);
I found myself in a situation where I'm not sure which way I should go. So far I'm using dependency injection where I pass PDO object to as a dependency.
This works quite fine, but now I need to have a Context class which would be for example holding the Info of current user. It could be something like this:
class Context
{
private $Pdo;
function __construct(PDO $Pdo) {
$this->Pdo = $Pdo;
}
function CurrentUser(){
if ($this->CurrentUser == null){
// get user logic
$this->CurrentUser = User;
}
return $this->CurrentUser;
}
}
So each time I would like to get the current user I would need to do something like this:
$Context = new Context($Pdo);
$User = $Context->CurrentUser();
I would like to be able to use this anywhere in project, but the PDO is not passed to each method there is.
I could make a singleton class for getting the PDO object anywhere I need and use that in my Context class. Would this be a good aproach? Or would a factory design be better?
Up until now I used global in such cases, but I would probably want to avoid there as the project grows rapidly.
I could make a singleton class for getting the PDO object anywhere I
need and use that in my Context class. Would this be a good aproach?
Or would a factory design be better?
Well, Singleton and Factory are not really the same thing, and your particular needs should dictate the solution.
Here is a short summary of a more in-depth post:
The Singleton pattern restricts the instantiation of a class to a single object. This provides a single point of access across the entire application, and ensure that you are always dealing with the same object.
The Factory pattern provides a new instance of the object whenever it is called. This may or may not be the same instance. Essentially the factory defines an interface for creating objects.
So, your needs will determine which pattern is better for your application. If you want a single instance of an object, go with a singleton.
I have a question concerning dependency injection. I have been keeping it simple so far, my methodology is basically to factor out object creation within objects and passing it instead in the constructer. I have come to a point where I am attacking larger classes that require multiple oblects. Some even have objects that contain other objects, with merry little singletons here and there. It gets ugly fast when testing these classes, as they are far from 'isolated' they are still hard-coded to their dependencies.
So. Injecting an object or 2 for a trivial class is straightforward,
I have looked into dependency containers, saw many implementations and am now wondering what is the advantage of using container vs. a registry for example. Couldn't one just as easily use a registry to hold anonymous functions that create the needed dependencies when called upon?
The 2 containers I peeked into, Php Dependency and Pimple differ greatly in the implementation.
I am wondering on the advantages of user a container vs. passing straight objects. I fail to understand how php-dependency's implementation would be tested, ie how would one implement the mock database object in phpunit without the actual class being injected when tested? Is there advantage to having dependency mapped out and used in doctags like this?
Class Book {
private $_database;
/**
* #PdInject database
*/
public function setDatabase($database) {
$this->_database = $database;
}
}
Pimple, on the other hand takes a totally different approach. No docblock tags, no mapping in seperate file, it seems like some kind of souped up registry ....
Objects are defined by anonymous functions that return an instance of the object:
// define some parameters
$container['cookie_name'] = 'SESSION_ID';
$container['session_storage_class'] = 'SessionStorage';
... that can behave as a factory at same time:
$container['session'] = function ($c) {
return new Session($c['session_storage']);
};
Declaring shared ressources always serves the same instance (singleton!?):
$c['session'] = $c->share(function ($c) {
return new Session($c['session_storage']);
});
This is were I got the idea of using a simple registry that holds either objects or anonymous functions. BUt am I missing something in this approach? Pimple, I can see to how to test, but Php-Dependency is unclear to me from a testing point of view.
Normally in our apps, we do constructor injection and define an interface for all components in our system:
class Book
{
/**
* #var Db_AdapterInterface
*/
private $_database;
public function __construct(Db_AdapterInterface $database)
{
$this->_database = $database;
}
}
We have then of course a standard Db_Adapter and then another Db_TestAdapter. In Db_TestAdapter we can define results of SQL queries in our tests.
For our normal app, we have something like this for our container:
$container->add('Db_AdapterInterface', new Db_Adapter());
And then in our tests, we have this line instead:
$container->add('Db_AdapterInterface', new Db_TestAdapter());
To get an instance of a Book, we simply ask the container for it:
$book = $container->construct('Book');
And the container injects all the needed dependencies into the object.
If you keep all your objects loosely coupled, ie object A only needs an interface B then you can always provide object A with a test implementation. At that point what container you use doesn't matter.
We have a very simple IoC container which can do basic constructor injection. Our tests inherit from a base class which fills the container with standard test objects. That way we don't have a lot of code just to construct an object we want to test.
Update:
I added an example of wiring things up in the container.
I have a class which depends on 3 classes, all 3 of which have other classes they rely on. Currently, I'm using a container class to build up all the required classes, inject them into one another and return the application.
The simplified version of the container looks something like this:
class Builder
{
private $_options;
public function __construct($options)
{
$this->_options = $options;
}
public function build()
{
$cache = $this->getCache();
$response = $this->getResponse();
$engine = $this->getEngine();
return new Application($cache,$response,$engine);
}
public function getResponse()
{
$encoder = $this->getResponseEncoder();
$cache = $this->getResponseCache();
return new Response($encoder,$cache);
}
// Methods for building each object
}
I'm not sure if this would be classified as FactoryMethod or a DI Container. They both seem to solve the same problem in the same way - They build objects and inject dependencies. This container has some more complicated building methods, like loading observers and attaching them to observable objects.
Should factories be doing all the building (loading extensions etc) and the DI container should use these factories to inject dependencies? That way the sub-packages, like Cache, Response etc, can each have their own specialised factories.
A DI Container is definitely a Factory, but it's a general-purpose factory.
However, if you use it in a pull-based way by asking it to create dependencies for you every time you need them, you would be employing the Service Locator anti-pattern. That's just a general-purpose factory and actually has little to do with DI.
True Dependency Injection is, as the name implies, push based. You write all your code using simple patterns like Constructor Injection, and use the DI Container to resolve your entire dependency graph in one go in the application's Composition Root, injecting all dependencies into their respective consumers.