How to properly inject dependencies in PHP - php

I'm having some issues with dependency injection that I'd like to clearify. The first thing to mention is a dependency injection container (DIC) I implemented, which is capable of registering and resolving dependencies through constructors using ReflectionClass.
$container = new DiC;
$container->register('session', 'CSession');
$container->register('response', 'CResponse');
$container->register('model', 'CSomeModel');
$container->register('view', 'CSomeView');
$container->register('controller', 'CSomeController');
A dependent controller:
class CSomeController extends CController
{
public function __construct(CSomeModel $model, CSomeView $view)
{
// assign arguments here
}
}
Now the controller can be instantiated through DIC:
$controller = $container->resolve('controller');
I like this approach because it is automated and descriptive, however class CController depends on specific classes CSomeModel, CSomeView which is bad. MVC triads should be instantiated independently - I cannot pass COtherView to CSomeController for example.
My second guess is to inject the DIC:
class CSomeController extends CController
{
public function __construct(DiC $dic)
{
// resolve dependencies through $dic
}
}
This one makes DiC object global, many people argue this is not the way to implement DI.
Is there a third way that eliminates the weaknesses from both approaches?

If your looking for "auto-wiring", switch to Interfaces and implement your concrete Model/View/etc. classes against that interface. That way you could use reflection to pair up both sides.
It would also make sense to have a mechanism for explicitly specifying dependencies at the container level.

I think both approaches are relevant. In case you want to be more flexible in the first approach you could change the constructor to have a parent class as a dependency. Then every object that inherits from that parent class could be injected. I.e.
class CSomeModel extends AbstractCModel {}
class CSomeOtherModel extends AbstractCModel {}
public function __construct(AbstractCModel $model, AbstractCView $view) {}
The second approach is suitable if you need to access factories. I.e. if you need to access multiple instances of the same object.

Related

What is a Dependency Injection Container?

I am trying to understand the role of a Dependency Injection Container because it strikes me as fundamental in maintainable code.
As I understand it, a DIC is just as the title suggests: a container where all your dependencies are collected together. Instead of seeing new Foo\Bar all over the application, all the new instances are generated inside of the container and then passed through to each other where they are needed (e.g., Model is instantiated with an instance of Database, which is instantiated with an Instance of Config).
I have attempted to make a very simple DIC. This is the result.
In my front controller I am instantiating a new App\Core\Container.
My Container looks like this:
<?php
namespace App\Core;
use App\Config;
class Container
{
public $config;
public $router;
public $database;
public $model;
public $view;
public $controller;
public function __construct()
{
$this->config = new Config;
$this->router = new Router;
$this->database = new Database($this->config);
}
public function add()
{
// add dependencies from the outside?
}
public function getInstance(/* string */)
{
// return an instance for use somewhere?
}
public function newModel($model)
{
$model = $this->getModelNamespace() . $model;
$this->model = new $model($this->database);
return $this->model;
}
private function getModelNamespace()
{
$namespace = 'App\Models\\';
if (array_key_exists('namespace', $this->params = [])) {
$namespace .= $this->params['namespace'] . '\\';
}
return $namespace;
}
public function newView($params)
{
$this->view = new View($this->model, $params);
return $this->view;
}
public function newController($controller)
{
$controller = $this->getControllerNamespace() . $controller;
$this->controller = new $controller;
return $this->controller;
}
private function getControllerNamespace()
{
$namespace = 'App\Controllers\\';
if (array_key_exists('namespace', $this->params = [])) {
$namespace .= $this->params['namespace'] . '\\';
}
return $namespace;
}
}
Questions
Could my implementation above, although very simple, be classed as a basic dependency injector?
Is a Dependency Injection Container generally comprised of one class?
Note: the first three headings answer your questions, while the following ones answer anticipated questions and provide coverage of anything in the first two sections.
Could this be classified as a dependency injection container?
No, this does not look like a dependency injection container. A dependency injection container is meant to reduce the work that instantiation requires by determining, creating, and injecting all dependencies. Rather what you have there appears to be a combination of a factory and a service locator.
Factories abstract the creation of objects. This is essentially what your Container class is doing. By calling designated methods (i.e., newModel), your container takes on the responsibility of locating the exact object to be instantiated and constructing an instance of that object.
The reason I would call this a "poor" factory is that it's beginning to look like it might be used to locate services. Service locators work by hiding an object's dependencies: instead of being dependent on GenericService, an object might depend on a service locator. Given the service locator, it can request an instance of GenericService. I see similar behavior beginning to take hold in your add() and getInstance() methods. Service locators are generally considered anti-patterns because they abstract dependencies therefore making code impossible to test!
Is a dependency injection container comprised of one class?
It depends. You could very easily make a simple dependency injection container with one class. The issue is that the nature of a simple container tends to get more advanced into a not-so-simple container. When you start improving your pattern, you need to consider how the different components play together. Ask yourself: do they follow SOLID principles? If not, refactoring is necessary.
What is a dependency injection container?
I said it above, but again: a dependency injection container is meant to reduce the work that instantiation requires by determining, creating, and injecting all dependencies. A DIC will look at all dependencies of a class, and all dependencies those dependencies may have, and so on... In this sense, the container is responsible for hierarchically instantiating all dependencies.
The Container class you provide relies on very strict definitions of pre-defined classes. For example, classes in your model layer appear to only be dependent on a database connection. (Similar statements can be said about classes in your controller & view layer).
How does a dependency injection container find dependencies?
A dependency injection container will detect dependencies. Typically this happens through 1 of 3 mechanisms: autowiring, annotations, and definitions. PHP-DI docs provide a good idea of what all three of these entail here. In short, though: autowiring detects dependencies by reflecting on a class, annotations are used to write in dependencies using comments above a class, and definitions are used to hard-code dependencies. Personally, I prefer autowiring because it's clean & simple.
Can I create a simple dependency injection container or no?
Yes, you can. Start with the idea that an injector should be able to instantiate any object (service, view, controller, etc...). It needs to look at the relevant object and hierarchically instantiate all dependencies (hint: possibly through some method of recursion).
A quick example of a simple injector using autowiring looks like this:
<?php
class Injector
{
public function make($className)
{
$dependencies = [];
//Create reflection of the class-to-make's constructor to get dependencies
$classReflection = new ReflectionMethod($className, "__construct");
foreach($classReflection->getParameters() as $parameter) {
$dependencyName = $parameter->getClass()->getName();
//Use the injector to make an instance of the dependency
$dependencies[] = $this->make($dependencyName);
}
$class = new ReflectionClass($className);
//Instantiate the class with all dependencies
return $class->newInstanceArgs($dependencies);
}
}
Tested with something like the following, you can see how the injector recursively checks and instantiates all dependencies
class A {
protected $b;
public function __construct(B $b) { $this->b = $b; }
public function output(){ $this->b->foo(); }
}
class B {
protected $c;
public function __construct(C $c) { $this->c = $c; }
public function foo() { $this->c->bar(); }
}
class C {
public function __construct() { }
public function bar() { echo "World!"; }
}
$injector = new Injector;
$a = $injector->make("A");
//No need to manually instantiate A's dependency, B, or B's dependency, C
$a->output();
This basic injector has obvious faults. For example, there is an opportunity to create a recursion disaster if two classes are dependent on each other (there should be a check for that). However, as is, this works as a basic example of what an injector looks like.
Injector vs. Dependency Injection Container
To make this more powerful and fall under the definition of "dependency injection container", you'd want a way to share instantiated instances across multiple make() calls. For example, you may have another method called share(). This method would store the instance passed to it. Whenever a class is built through the make() method and depends on a class previously shared, instead of instantiating a new instance, it would use the already-instantiated one.
For a simple & powerful dependency injection container I suggest Auryn, but by all means, try to understand & create your own before using the ones already available.

Enforcing variable declaration for a subclass in php

I have an abstract class like this
<?php
abstract class AbastractCreationCommand extends AbstactCommand {
protected $repository;
function handle($payload) {
$this->repository->create($payload);
}
}
class TagCreationCmd extends AbstractCreationCommand {
function __constructor() {
$this->repository = new TagRepository();
}
}
?>
Questions:
is there a way I could enforce the definition of the repository class in the subclasseses of the AbstractCreationCommand ?
Do I need to create a test for each subclass and call handle method or is another way to test all my code?
Answering number 1: You cannot enforce the creation of anything in subclasses from within your abstract class. At least not during instantiation. Everything in the subclass is optional.
However, your code in the abstract class could check whether or not the necessary objects have been defined when executing the part of the code that needs it, like this:
abstract class AbastractCreationCommand extends AbstactCommand {
protected $repository;
function handle($payload) {
if (!$this->repository instanceof TagRepository) {
throw new \InvalidArgumentException('Need a TagRepository');
}
$this->repository->create($payload);
}
}
However, is likely doing the complaining too late. And the reason may be because you are using inheritance instead of composition, or are inheriting the wrong things.
First of all, you are not doing dependency injection. Your subclass should not directly instantiate that TagRepository. This leads to problems testing your abstract class' code, as well as the subclass code, because you cannot provide a mock object instead. This severely limits the ability to test your code in isolation.
Also, the subclass cannot work without knowing very specifically how to inherit the abstract class beyond implementing any abstract functions. If both abstract and subclass come from you as the author, I would consider it to be ok to impose doing all things correctly on you. But if you expect other developers to inherit that abstract class (and your question sounds like this might be the background problem), then you shouldn't do this at all.
Abstract classes do provide some common functions to a set of subclasses through inheritance. But the same thing could be achieved if you put all the code into a non-abstract class and inject this class into independent ex-sub classes. They will call these common functions as public methods instead of private or protected, and the testing of the common code is also easier, because the methods are public.
Also note that you already have three levels of inheritance, which is nearing a uncomfortable level: AbstractCommand -> AbstractCreationCommand -> TagCreationCmd.
The problem is that everything you change in AbstractCommand has to be done with two levels of inheriting objects in mind. You cannot simply change a protected variable's name. You cannot simply add a protected (or public) variable without checking if any of the sub classes already has such a variable with the same name - unless you intend to share it.
The problems with maintaining code that is inherited is not with the classes at the end of the inheritance chain, but with these at the top. Just think about how many classes might be affected with different usage contexts: If you have AbstractCreationCommands, you will have AbstractDeletionCommands and AbstractChangeCommands and AbstractDoNothingCommands, and a plethora of concrete commands of all these kinds doing plenty of different stuff. Just imaging that on each level, you have four classes - this makes you having to maintain one base class, four inheriting classes, and four times four concrete classes - for a whopping 21 classes in total, all of them having to be tested, and likely none of them gaining any benefit from being an instanceof AbstractCommand.
Answering number 2: Yes, you have to test all subclasses - these are the ones that get instantiated and used. You should also test the abstract class' code in isolation. PHPUnit offers to instantiate an abstract class with the mock framework, so any abstract method would be mocked and could be configured. However, I always have a bad feeling when I use a mock as the real tested object because I am not really testing the pure code, but some combination of mock code and real code.
A possible way out is to create a test class that barely does anything beyond extending the abstract class, and work with this one.
1.Yes. I do the same when I need to force instantiation of some dependancies. And this way is support GRASP: Creator principle.
Another way to accomplish that with dependency injection, but this way broke Creator principle:
class TagCreationCmd extends AbstractCreationCommand {
function __constructor(TagRepositoryInterface $tagRepository) {
$this->repository = $tagRepository;
}
}
If follow 3 rules of TDD you should write test for each line of code. So the answer is yes.
Is there a way I could enforce the definition of the repository class in the subclasseses of the AbstractCreationCommand ?
I don't see the necessity tbh. If your AbstractCreationCommand needs a repo to work, add it as a constructor param. This doesn't enforce the repo to be injected because a subtype can override the constructor, but it should be abundantly clear that an AbstractCreationCommand subtype requires some sort of repo then, e.g.
abstract class AbstractCreationCommand extends AbstractCommand
{
private $repository;
public function __construct(Repository $repository)
{
$this->repository = $repository
}
protected function getRepository(): Repository
{
return $this->repository;
}
// …
You could also use a Template Method pattern to indicate that any subtype will utilize a repo by adding an abstract getter for the repo. The subtype will have to implement that method then. It's then up to the developer to decide on the implementation:
abstract class AbstractCreationCommand extends AbstractCommand
{
public function handle()
{
$this->getRepository()->create();
}
abstract function getRepository(): Repository;
// …
If you really must enforce it at creation level, you can set the abstract type's constructor to final protected and do any subtype creation in a static factory method, e.g.
abstract class AbstractCreationCommand extends AbstractCommand
{
private $repository;
final protected function __construct(Repository $repository)
{
$this->repository = $repository;
}
// …
This now prevents direct instantiation of any subtypes via new. Trying to new a subtype, will result in PHP Fatal error.
Instead the subtype must be created like this:
class TagCreationCommand extends AbstractCreationCommand
{
private $foo;
public static function create(Repository $repository, Foo $foo)
{
$command = new static ($repository);
$command->setFoo($foo);
return $command;
}
protected function setFoo(Foo $foo)
{
$this->foo = $foo;
}
// …
Then you'd call TagCreationCommand::create(new TagRepository, new Foo); to get a new instance. Since you cannot override the constructor and have to call the parent constructor from within the static create method, you effectively enforce a Repository now to be there. I added the Foo stuff only to illustrate how you'd use additional dependencies.
As you can hopefully see, this requires quite a lot of gymnastics compared to the much more lightweight previous two approaches that will basically result in the same outcome. After all, if there is no repo, the code will fail. And since you are using tests, this will get noticed. So why bother?
Do I need to create a test for each subclass and call handle method or is another way to test all my code?
If you are overriding the handle method, you should test that behavior in a concrete test class for that subtype.
If your subtypes do not override the handle method, you can create an AbstractCreationCommandTest and put a test for the handle method in there. However, if that is the case, I wonder why you need the AbstractCreationCommand to be abstract in the first place because then it sounds like you just need a CreationCommand.
Following Yan Burtovoy's suggestion, I would go even further and actually enforce a DI container
<?php
abstract class AbastractCreationCommand extends AbstactCommand {
protected $repository;
function __constructor(\DI\Container $container) {
$this->repository = $container->get('TagRepository');
}
function handle($payload) {
$this->repository->create($payload);
}
}
You should create tests for everything that is exposed to users of your library (that would be your application).
So, if you have a subclass that relies on handle() being called then you should write a test for that. Reason being that in 6 months someone might change the inheritance or overwrite the handle() method and change the initial expected behaviour.

How to avoid duplicating implemented getter function in PHP

While this question is about methods of solving this problem, I am particularly interested in good clean OO design and solutions that conform to current PHP best practices. Thanks in advance for taking a look.
I have the following interface:
<?php
interface Tool {
/**
* Return the unique name of the tool
*/
public function getName();
}
The majority of classes that implement this interface in my project looks like this:
<?php
class Drill implements Tool {
protected $toolName = 'drill';
public function getName() {
return $this->toolName;
}
}
And so the problem is I have dozens of classes that repeat this logic, duplicating the $toolName property and getName() logic, breaking the simple rule of 'Don't repeat yourself'
One solution I have considered is the following:
<?php
abstract class BaseTool implements Tool {
public function getName() {
return $this->toolName;
}
}
Then simply have tool classes extend the abstract BaseTool class:
<?php
class Drill extends BaseTool {
protected $toolName = 'drill';
}
However this now means that I lose the ability to force implementing classes to define the function getName() if they extend the BaseTool class, which can lead to incorrect implementations.
I also think that by having the BaseTool class return $this->toolName, it is making assumptions about the implementing classes and breaks encapsulation.
I have used a simple example to demonstrate the problem but hope you get what I'm trying to solve, and that this problem may also relate to more complex situations. Appreciate your thoughts.
If you're using PHP 5.4.0+, check out traits!
You could create a ToolInterfaceTrait that just contains the getters / setters for the variable $toolName
Your attempt looks good. Nothing more to say.
However this now means that I lose the ability to force implementing classes to define the function getName() if they extend the BaseTool class, which can lead to incorrect implementations.
You still force them, they need to inherit a class which implements them or implement them on their own.
If it is not feasible that all classes which should implement Tool extend from BaseTool, feel free to create more base classes which implement getName() or implement it directly, like you wish.
Btw, if you plan that all tools should extend BaseTool, then the interface isn't necessary at all, at least not for this use case. Interfaces are used for situations where not all classes which are expeted to implement it are inherited from the same base class.
How to avoid duplicating implemented getter function in PHP
Abstract classes are often used to group duplicated code. You're on the right path. As for your doubts about the choice...
However this now means that I lose the ability to force implementing classes to define the function getName() if they extend the BaseTool class, which can lead to incorrect implementations.
By extending the BaseTool class, a class inherits getName() (that's the idea with defining it in the abstract class). I'm not sure why that leads to incorrect implementations or why you'd have to "force implementing classes to define it." They get it automatically by extending the abstract class.
I also think that by having the BaseTool class return $this->toolName, it is making assumptions about the implementing classes and breaks encapsulation.
It might be cleaner if you define the toolName in the abstract class, and you set its value in the constructor?
<?php
abstract class BaseTool implements Tool {
protected $toolName;
public function __construct($toolName)
{
$this->toolName = $toolName;
}
public function getName() {
return $this->toolName;
}
}
You define a constructor in the extended class to put its name:
<?php
class Drill extends BaseTool {
public function __construct()
{
parent::__construct("drill");
}
}

Two different ways to implement Decorator pattern in PHP

While doing some tutorials on Decorator pattern, I've encountered two different implementations.
Implementation 1 (referred to as I1)
Implementation 2 (referred to as I2)
In short,
I1's parent decorator class implements original object's interface (In the example, class PropertyDecorator implements PropertyInterface. The original object Property implements PropertyInterface as well).
I2's parent decorator class DOES NOT implement original object's interface (In the example, Decorator_Wrapper does not implements Cupcake interface. In fact, there is not even CupcakeInterface at all).
My question is,
Is this merely a personal preference of understanding and implementing Decorator pattern? or one is wrong and one is right?
Just depends on your needs.
Let's see:
Abstract class
Can provide abstract methods.
Can provide real functions and variables.
Can be extended. But a class can extend only 1 parent.
Interface
Can provide abstract methods.
A class may implement several interfaces.
I generally would prefer using a base abstract class, because I can declare some basic functions as well, since you could have a lot of different types of decorators with similar functionality. Methods can be overriden anyways + you can implement some interfaces.
class Decorator extends Decorator_Wrapper implements Interface1, Inteface2 {
public function __construct(){
parent::__construct() ; // Here you could perform some basic decorator actions. It is an advantage compared to interfaces.
}
}
The Decorator pattern is used when you wish to extend the functionality of an instance of a class without extending the class itself (thus, not affecting other instances of said class).
It's kind of an extension at runtime and it's pretty useful since it lets you customize the behavior of an object at runtime. You can even "simulate" multiple inheritance with it.
Since both your examples accomplish this, both are correct. There is no need for a decorator to implement the base interface or extend the original object.
HOWEVER...
If the decorator does not implement the base interface, it MIGHT not be able to be used interchangeably with the original class.
Which might defeat the purpose of using the decorator if you can't use it everywhere "safely".
Example:
interface FooInterface {
public function scare();
}
class Foo implements FooInterface {
protected $boo = 'boo';
public function scare() { echo $this->boo; }
}
class FooBar {
public function __construct(FooInterface $foo) {
$this->foo = $foo;
}
public function scareAlot() {
echo strtoupper($this->foo->scare());
}
}
class INeedFoo {
public static function gimmeFoo(FooInterface $foo) {}
}
$foo = new Foo();
$fooBar = new FooBar($foo);
INeedFoo::gimmeFoo($foo); //Works
INeedFoo::gimmeFoo($fooBar); //Does not Work
Also, if you implement the base interface or extend the base class it might be easier to add multiple decorators on top of eachother but ... you may also end up with a lot of replicated functionality.

Static classes in PHP via abstract keyword?

According to the PHP manual, a class like this:
abstract class Example {}
cannot be instantiated. If I need a class without instance, e.g. for a registry pattern:
class Registry {}
// and later:
echo Registry::$someValue;
would it be considered good style to simply declare the class as abstract? If not, what are the advantages of hiding the constructor as protected method compared to an abstract class?
Rationale for asking: As far as I see it, it could a bit of feature abuse, since the manual refers to abstract classes more as like blueprints for later classes with instantiation possibility.
Update: First of all, thanks for all the answers! But many answers sound quite alike: 'You cannot instantiate an abstract class, but for a registry, why not using a singleton pattern?'
Unfortunately, that was more or less exactly a repeat of my question. What is the advantage of using a singleton pattern (a.k.a. hiding __construct()) compared to just declaring it abstract and not having to worry about that? (Like, e.g., it is a strong connotation between developers, that abstract classes are not actually used or so.)
If your class is not meant to define some super-type, it should not be declared as abstract, I'd say.
In your case, I would rather go with a class :
That defines __construct and __clone as private methods
so the class cannot be instanciated from outside
And, this way, your class could create an instance of itself
See the Singleton design pattern, about that, btw
Now, why use a Singleton, and not only static methods ? I suppose that, at least a couple of reasons can be valid :
Using a singleton means using an instance of the class ; makes it easier to transform a non-singleton class to a singleton one : only have to make __construct and __clone private, and add some getInstance method.
Using a singleton also means you have access to everything you can use with a normal instance : $this, properties, ...
Oh, a third one (not sure about that, but might have its importance) : with PHP < 5.3, you have less possibilities with static methods/data :
__callStatic has only been introduced in PHP 5.3
There is no __getStatic, __setStatic, ...
Same for a couple of other Magic methods !
Late Static Binding has only been added with PHP 5.3 ; and not having it often makes it harder, when working with static methods/classes ; especially when using inheritance.
This being said, yes, some code like this :
abstract class MyClass {
protected static $data;
public static function setA($a) {
self::$data['a'] = $a;
}
public static function getA() {
return self::$data['a'];
}
}
MyClass::setA(20);
var_dump(MyClass::getA());
Will work... But it doesn't feel quite natural... and this is a very simple example (see what I said earlier with Late Static Binding, and magic methods).
What you describe is permitted by the PHP language, but it's not the intended usage of an abstract class. I wouldn't use static methods of an abstract class.
Here's the downside of doing that: Another developer could extend your abstract class and then instantiate an object, which is what you want to avoid. Example:
class MyRegistry extends AbstractRegistry { }
$reg = new MyRegistry();
True, you only need to worry about this if you're handing off your abstract class to another developer who won't comply with your intended usage, but that's why you would make the class a singleton too. An uncooperative developer can override a private constructor:
class Registry
{
private function __construct() { }
}
class MyRegistry extends Registry
{
public function __construct() { } // change private to public
}
If you were using this class yourself, you would simply remember not to instantiate the class. Then you wouldn't need either mechanism to prevent it. So since you're designing this to be used by others, you need some way to prevent those people from circumventing your intended usage.
So I offer these two possible alternatives:
Stick with the singleton pattern and make sure the constructor is also final so no one can extend your class and change the constructor to non-private:
class Registry
{
private final function __construct() {
}
}
Make your Registry support both static and object usage:
class Registry
{
protected static $reg = null;
public static function getInstance() {
if (self::$reg === null) {
self::$reg = new Registry();
}
return self::$reg;
}
}
Then you can call Registry::getInstance() statically, or you can call new Registry() if you want an object instance.
Then you can do nifty things like store a new registry instance inside your global registry! :-)
I implemented this as part of Zend Framework, in Zend_Registry
As other guys said, you cannot instantiate an abstract class. You could use static methods in your class to prevent instantiating, but I'm not really a fan of doing so unless I have a proper reason.
I might be little bit off-topic now, but in your example you said you wanted this for Registry pattern class. What is the reason you don't want to instantiate it? Wouldn't it better to create an instance of Registry for each registry you want to use?
Something like:
class Registry {
private $_objects = array( );
public function set( $name, $object ) {
$this->_objects[ $name ] = $object;
}
public function get( $name ) {
return $this->_objects[ $name ];
}
}
I wouldn't even use Singleton in this case.
Setting a class to abstract that only defines static properties/methods won't have a real effect. You can extend the class, instantiate it, and call a method on it and it would change the static class properties. Obviously very confusing.
Abstract is also misleading. Abstract is ment to define an class that implements some functionality, but needs more behaviour (added via inheritance) to function properly. On top of that it's usually a feature that shouldn't be used with static at all. You are practically inviting programmers to use it wrong.
Short answer: A private constructor would be more expressive and fail safe.
There are patterns in OO that are common and well-recognized. Using abstract in an unconventional way may cause confusion (sorry, my some examples are in Java instead of PHP):
abstract class - a class meant to conceptualize a common ancestor, but of which actual instances are not meant to exist (e.g. shape is an abstract superclass for rectangle and triangle).
Commonly implemented by:
use abstract modifier on class to prevent direct instantiation, but allow deriving from the class
utility class - a class that does not represent an object in the solution space, but rather is a collection of useful static operations/methods, e.g. Math class in Java.
Commonly implemented by:
make class non-derivable, e.g. Java uses the final modifier on class, and
prevent direct instantiation - provide no constructors and hide or disable any implicit or default constructors (and copy constructors)
singleton class - a class that does represent an object in the solution space, but whose instantiation is controlled or limited, often to insure there is only one instance.
Commonly implemented by:
make class non-derivable, e.g. Java uses the final modifier on class, and
prevent direct instantiation - provide no constructors and hide or disable any implicit or default constructors (and copy constructors), and
provide a specific means to acquire an instance - a static method (often getInstance()) that returns the only instance or one of the limited number of instances
abstract really is meant to indicate a "blueprint", as you call it, for class inheritance.
Registries generally follow a singleton pattern, which means they it would instantiate itself in a private variable. Defining it as abstract would prevent this from working.
I wouldnt use an abstract class. Id use something more akin to a singleton with a protected/private constructor as you suggest. There should be very few static properties other than $instance which is the actual registry instance. Recently ive become a fan of Zend Frameworks typical pattern which is something like this:
class MyRegistry {
protected static $instance = null;
public function __construct($options = null)
{
}
public static function setInstance(MyRegistry $instance)
{
self::$instance = $instance;
}
public static function getInstance()
{
if(null === self::$instance) {
self::$instance = new self;
}
return self::$instance;
}
}
This way you get a singleton essentially but you can inject a configured instance to use. This is handy for testing purposes and inheritance.
The purpose of an abstract class is to define methods that are 1) meaningful to other classes and 2) not meaningful when not in the context of one of those classes.
To paraphase some of the php docs, imagine you are connecting to a database. Connecting to a database doesn't make much sense unless you have a particular kind of database to connect to. Yet connecting is something you will want to do regardless of the kind of database. Therefore, connecting can be defined in an abstract database class and inherited, and made meaningful by, say, a MYSQL class.
From your requirements, it sounds like you don't intend to do this but instead simply require a class without an instance. Whilst you could use an abstract class to enforce this behaviour, this seems hacky to me because it abuses the purpose of abstract classes. If I encounter an abstract class, I should be able to reasonably expect that this will have some abstract methods, for example, but your class will have none.
Therefore, a singleton seems like a better option.
However, if the reason you wish to have a class without an instance is simply so that you can call it anywhere then why do you even have a class at all? Why not just load every variable as a global and then you can just call it directly rather than through the class?
I think the best way to do this is to instantiate the class and then pass it around with dependency injection. If you are too lazy to do that (and fair enough if you are! Its your code, not mine.) then don't bother with the class at all.
UPDATE: It seems like you are conflicted between 2 needs: The need to do things quickly and the need to do things the right way. If you don't care about carrying a ton of global variables for the sake of saving yourself time, you will assumedly prefer using abstract over a singleton because it involves less typing. Pick which need is more important to you and stick with it.
The right way here is definitely not to use a Singleton or an abstract class and instead use dependency injection. The fast way is to have a ton of globals or an abstract class.
From my understanding, a class without instance is something you shouldn't be using in an OOP program, because the whole (and sole) purpose of classes is to serve as blueprints for new objects. The only difference between Registry::$someValue and $GLOBALS['Registry_someValue'] is that the former looks 'fancier', but neither way is really object-oriented.
So, to answer your question, you don't want a "singleton class", you want a singleton object, optionally equipped with a factory method:
class Registry
{
static $obj = null;
protected function __construct() {
...
}
static function object() {
return self::$obj ? self::$obj : self::$obj = new self;
}
}
...
Registry::object()->someValue;
Clearly abstract won't work here.
I would say it's a matter of coding habbits. When you think of an abstract class it is usually something you need to subclass in order to use. So declaring your class abstract is counter-intuitive.
Other than that is it just a matter of using self::$somevar in your methods if you make it abstract, rather than $this->somevar if you implement it as a singleton.

Categories