Reusing Complex Object Instances in PHP - php

Is there a reasonable way to ensure that you aren't unnecessarily re-instantiating expensive object instances in PHP?
I have an application that deal with US States. Each state is an instance of the USState class. I'd like to ensure that the application only ever has one instance of each state object, although they are used in many places throughout the application.
I looked into the singleton pattern, but that seems to be used for times when a class only has a single instance - here there are 50 instances, but no more.
I guess I could put them in the global scope and always refer to them that way (global $california), but that seems wrong.

I would use Service Locator Pattern or Dependency Injection, which is provided by your framework. Usually I go with Zend Framework, but not knowing your circumstances, I assume you have no framework at all. In this case I would suggest very simple Dependency Injection Container, but that would add a dependency on DIC itself. Pimple is one of them.

Related

What's the difference between Singleton and Registry design pattern

I have some confusion between those two patterns:
singleton
Check if the instance exists return it, or create a new one.
Registry
Check if the instance exists return it, or create a new one and store it.
What the difference between them?
Both are about instance control. The difference is that Singleton allows only one instance of a given class while Registry holds a 1-1 map of keys to instances. Typically, the key is (or represents) a class and the value is an instance of that class.
For example, Code Igniter framework holds a registry with an instance of each library/model/controller/helper you load and returning those same instances every time.
Level of access and complexity
One fun filled caveat I always love, is that a registry pattern is utilizing a singleton to store/retrieve a dynamic list of objects.
Singleton Pattern
Singleton pattern is a pattern by which you establish a single point of access and methodology. While many people believe it is an anti-pattern, I assure you it is only because of the level they work at and type of programming they do.
Singleton patterns are used at lower levels to manage strict resources. For instance, while most languages have libraries that wrap keyboard input, it is effectively a singleton pattern as it has very strict input/output and only one can exist, regardless of how many keyboards you have.
Testing Singleton patterns
One of the reasons people feel singleton patterns are anti-patterns, is they are in general untestable in a unit test system. It is not possible to even mock a singleton in most languages, as it is fixed to a specific identity.
For this reason the singleton should be minimal, and a wrapper used to interface it.
You can then inject the wrapper and it can be mocked to used a fake singleton mock.
Registry Pattern
The registry pattern is where you establish a single point of access, but not a single methodology. This very registry access will have at least 3 methods: put, find, and delete. These methods rely on a singleton pattern to work.
The map is testable, as it is not isolated to your use, and while the registry itself is not actually unit testable in connection to the units that consume it, you can utilize mocks of everything the registry is intended to contain.
However, if you utilize IoC in a given architecture consuming it, you can inject the registry from the container registry, allowing a mocked registry to be injected instead.
Final note
Inversion of control is vastly popular these days, however big parts of it are often not learned or ignored. Some frameworks boil it down to mostly the factory pattern for most things, abstracting the rest away.
I would strongly encouraging most to toss out everything they know about IoC.
Then learn SOLID.
Afterwards read a book on design patterns for OOD. (Note: If the book has pros and cons of the patterns, it is good, if it does not show the cons, I would be very wary of the book.)
While these terms were coined relatively recently, the principles were learned in one manner or another early on, and in fact became the basis of Object Oriented Design.
The patterns most object oriented developers use successfully are all based on SOLID principles.
A reference to SOLID, that is laid out and summed up.
https://www.digitalocean.com/community/conceptual_articles/s-o-l-i-d-the-first-five-principles-of-object-oriented-design
As a final suggestion: Even if you are not an object oriented developer, it is very useful to learn SOLID and OOD, as must system architecture follows similar patterns when integrating a system together.
In addition I would not suggest you assume that one language/pattern/philosophy fits best for all needs. Keep learning, keep an open mind. The more you know, the better the solutions you can bring to the table.
A Registry differs in that its principal purpose is to allow you to navigate to associated objects. See Martin Fowler.
The main difference between registry and singleton is that singleton allow us to create a single instance of a class at a time, whereas registry allows us to create multiple instance of the same class.
Registry Definition: When you want to find an object you usually start with another object that has an association to it, and use the association to navigate to it. Thus, if you want to find all the orders for a customer, you start with the customer object and use a method on it to get the orders. However, in some cases you won't have an appropriate object to start with. You may know the customer's ID number but not have a reference. In this case you need some kind of lookup method - a finder - but the question remains: How do you get to the finder?
A Registry is essentially a global object, or at least it looks like one - even if it isn't as global as it may appear.
Singleton Definition: Sometimes it's important to have only one instance for a class. For example, in a system there should be only one window manager (or only a file system or only a print spooler). Usually singletons are used for centralized management of internal or external resources and they provide a global point of access to themselves.
Based on these definitions their usage are completely different.

Why use Zend_Registry instead of the Singelton pattern?

Why should I use Zend_Registry instead of the Singleton pattern?
My coworker and me recently had a discussion about this. His point was that we should use Zend_Registry for all consistent objects, but I wanted to use the singleton pattern, since Zend_Registry just does the same, but wrapped.
I have a problem with code like this:
$list = Zend_Registry::get('database')->getList($sql);
Since theres a chance that database isn't in Zend_Registry. In cases of lazy loading, I would have to make my own registry with information about specific objects in my system. Like if the database takes specific parameters on loadtime, then it would have to know this.
I would instead use getInstance and then all the code would reside in the same object. Does that make sense?
Even though you phrased your question as an either/or, might I suggest a third alternative?
I try to avoid both singletons and Zend_Registry wherever possible, since they function, in effect, as globals. When a segment of code can reach into the global ether - via a call to a singleton or a global registry - to get something it needs, it creates a hidden - or at least, a non-explicit - dependency that makes things harder to debug and unit-test.
In contrast, I try to follow dependency injection advice, paraphrased as: "Give a component what it needs. Don't make it find what it needs."
I find that for most entities for which I might feel I need a registry/singleton - db connections, loggers, etc - I can create them at Bootstrap, store them in the Bootstrap registry and inject them into my controllers, usually during init() using $this->getInvokeArg('bootstrap')->getResource('myResource'). Only controllers reach back into the Bootstrap. Then, any models or services that need these dependencies get them passed-in explicitly by the controller, either via constructor or by setter injection.
A hybrid approach to which I do sometimes fall back is to design my service/model classes with getters/setters for these dependencies - getDbAdapter() and setDbAdapter(); getLogger() and setLogger(), etc. The getter lazy-loads from the global registry - whether some singleton or by Zend_Registry, throwing exceptions when they are not where I expect them to be. In that sense, it is similar to what you are suggesting. It does violate the purist dependency injection philosophy. But at least the presence of the getter/setter methods explicitly demonstrates that there is a dependency and allows me to mock it out or to provide non-default implementations.
It does for simple blog or something. Otherwise you're stuck with only one DB instance. And that's NOT what you want in the long run. You may want to connect to other server (to log errors to central db, to import products from someone, ...) or connect as different user (for security reasons - you don't want your API to have access to admin_users table, but you still need to connect to it to check if user is valid in the first place).
You can do one-purpose registers (My_Db_Admin, My_Db_ReadOnly, ...) but that does not make much sense to me. Using registry you're not stuck with one instance. You can create one outside registry and work with it for a while and then trash it ;)

Singleton class and using inheritance

I have am working on a web application that makes use of helper classes. These classes hold functions to various operation such as form handling.
Sometimes I need these classes at more than one spot in my application, The way I do it now is to make a new Object. I can't pass the variable, this will be too much work.
I was wondering of using singleton classes for this. This way I am sure only one instance is running at a time.
My question however is when I use this pattern, should I make a singleton class for all the objects, this would b a lot of code replication.
Could I instead make a super class of superHelper, which is a singleton class, and then let every helper extend it.
Would this sort of set up work, or is there another alternative?
And if it works, does someone have any suggestions on how to code such a superHelper class.
Thank you guys
I can't pass the variable, this will be too much work.
Are you sure though? People tend to overestimate the effort of passing around dependencies. If you do it in the constructor, it's usually fairly simple to do.
That said, you can put shared functionality in the global scope, in different ways in php. The simplest is to use a global function. Eg. a function that doesn't belong to any class. Another option is to use a static class method. These two a very similar; except for their syntax, they essentially have the same properties. A slightly looser coupled solution is to put the functionality as a method on an (abstract) base class, that your concrete class extends from. This shares the functionality between all child classes.
Common for the above-mentioned solutions is that they have a compile time coupling. You can't change the dependency at run time, which makes your application rather rigid. Their main benefit is the low level of complexity they carry.
If you want a looser coupled application, you can try to replace the hard dependency with a variable, to give a level of indirection. The simples is to create an object and make this shared globally throughout the application. There are a number of ways to do this in PHP, such as a singleton or simply a variable in the global scope (You can access this with the global keyword, or through the $GLOBALS array).
While global variables offer a level of indirection, they also tend to introduce a lot of complexity, since they make it very hard to figure out which parts of the application that depends on each other. For this reason, they are often avoided by experienced programmers. This is especially true if the variable has state; The problem is less prevalent if the shared object is stateless.
The only way to avoid the perils of global variables, is to use local variables instead. Eg. To pass the dependencies around. This can be a bit of a hassle, but in my experience it's often not as big a problem as it's made out to be. At least, the benefits often outweigh the problems. That said, there are techniques to easy the pain; Notably dependency injection containers, which are automatic factories that take care of all the wiring for you. They come with their own level of complexity though, but for larger applications they can certainly be a good solution.
Look into the factory pattern and dependency injection.
http://www.potstuck.com/2009/01/08/php-dependency-injection/
You can't extend a singleton class. Remember in singleton class we make the constructor private so if a constructor is private than how could you extend this class? We all know what we create an object of a class we call its constructor and in child class constructor it implicitly called the parent constructor. So in this scenario a private constructor can't be called in the child class.
While sometimes necessary, singletons are evil (because they're global state). Try to avoid them if you can help it.
EDIT: If you can't avoid singletons, at least parameterise the reference to that state. In other words, in a class, pass in the singleton to its constructor or those methods that use the singleton.
Simply making references all over your codebase to your singleton will compromise your ability to test classes in isolation.
If your singleton's stateful, your tests will suddenly become stateful, and your tests can start "cascade failing" because their preconditions become corrupted by earlier tests failing.

Accessing the DI container

I'm starting a new project and setting up the base to work on. A few questions have risen and I'll probably be asking quite a few in here, hopefully I'll find some answers.
First step is to handle dependencies for objects. I've decided to go with the dependency injection design pattern, to which I'm somewhat new, to handle all of this for the application.
When actually coding it I came across a problem. If a class has multiple dependencies and you want to pass on multiple dependencies via the constructor (so that they cannot be changed after you instantiate the object).
How do you do it without passing an array of dependencies, using call_user_func_array(), eval() or Reflection? This is what i'm looking for:
<?php
class DI
{
public function getClass($classname)
{
if(!$this->pool[$classname]) {
# Load dependencies
$deps = $this->loadDependencies($classname);
# Here is where the magic should happen
$instance = new $classname($dep1, $dep2, $dep3);
# Add to pool
$this->pool[$classname] = $instance;
return $instance;
} else {
return $this->pool[$classname];
}
}
}
Again, I would like to avoid the most costly methods to call the class. Any other suggestions?
Also, how do I access the DI class inside classes, for example, in controllers that need to access different models? Should I call it statically or pass it along each class that would require it? I don't think the last idea is feasible.
Thanks everyone.
[Before I start, let me say that I'm mostly a Java programmer - with only a little bit of PHP knowledge. But I'll simply try to get the most important concepts across without language specifics.]
Dependency Injection is based on two parts of code:
Construction
Execution
In its most extreme shape, there are no new operators to be found in the Execution part. All of them are moved into the Construction part. (In practice, this will be toned down.)
All of the construction happens - in the Construction part. It creates the graph of objects needed for Execution bottom up. So let's assume, it should construct A:
A depends on B, and
B depends on C.
Then
C is constructed first.
Then B is constructed with C as a parameter.
Then A is constructed with B as a parameter.
So C doesn't have to be passed as a constructor parameter to A. This small example doesn't illustrate strongly enough, how much this reduces the amount of objects that have to be passed around to quite a small number.
The Dependency Injector itself should not be passed into the Execution part. This is one of the basic mistakes everyone (including myself) tries to make, when they first come in contact with DI. The problem is, that this would completely blur the lines between Construction and Execution. Another way to say it is, that it would violate the Law of Demeter. Or in pattern speak: It would eventually "degrade" the Dependency Injection pattern to the Service Locator pattern. It's debatable, if this is really a degradation, but in any case it's usually not a good idea to misuse the Dependency Injector as a Service Locator.
So whenever you need to give one of your constructed objects the capability to produce other objects during execution, instead of passing the Dependency Injector, you would only pass simple Providers (a term used by the Java DI framework Guice). These are rather simple classes that can only create a certain kind of object. They have similarities with a factory.
First try to pass the required dependencies directly to the constructor.
So, to sum it up:
Build objects bottom-up.
Only pass as few dependencies as required to create an object.
Once your done, start executing.
During execution, you can still fetch newly created objects by using Providers.
But don't take it too far: Simple objects can still be created without a Provider :-)
And now, all you'll have to do is to translate this stuff into quality code. Maybe others can help you out with a few PHP examples.
Addendum: A little bit more about Providers
As noted above, the notion "Provider" (a specialized factory) is a bit specific to the Java DI framework Guice. This framework can automatically create a Provider for any type of object. However, the concept is generally useful for DI. The only difference is, that without the help of Guice or a similar framework, you'll have to write the Providers yourself - but that's quite easy:
Let's say, B depends on C.
If B just needs one fixed instance of C, then you don't need a Provider - you can simply construct B with the constructor argument C.
If B needs to create more instances of C during execution, then just write a class called CProvider with a get() method, that can create a new instance of C. Then pass an instance of CProvider into the constructor of B, and store the Provider in an instance field of B. Now B can call cProvider.get() when it needs a new instance of C.
Providers are part of the Construction code, so you're allowed to use new C(...)! On the other hand, they're not part of the Execution code, so you shouldn't have any execution logic there.
CProvider can be passed into multiple constructors of course. You can also write multiple versions CProvider1, CProvider2, ... - where each can construct different versions of C objects with different properties. Or you simple instantiate CProvider multiple times with different arguments.
You should look into using an IOC container to manage your dependencies for you. A good IOC container should take care of passing dependencies between dependent contructors for you.
There is an existing question asking about IOC container options for PHP.
It looks like you are trying to roll your own dependency injection container. Why not use one that already exists, like Symfony, Crafty or Sphicy?

ServiceLocator and the Open/Closed Principle

I'd like to:
Make commonly required services visible to all classes that need them,
with a minimum of boilerplate, and
without sacrificing testability!
It's a small project and I think DI might be overkill, but maybe I'm wrong? Anyhow, I have been focusing on the ServiceLocator pattern as described by Martin Fowler
In a client class' constructor, I have something like this:
this->db = Locator::getDb();
this->log = Locator::getLogger();
Then the rest of the class' methods access the service through those member attributes, e.g.:
this->fooModel = new fooModel(this->db);
fooItem1234 = this->fooModel->findById(1234);
However I would also like this level of visibility for "model" objects (like fooModel above) because they are accessed from several different places and there is no need to have more than one instance.
So my initial thought was to extend Locator to have a ::getFooModel() but now it seems I'm violating the Open/Closed Principle, since I'll have to modify Locator every time I introduce a new model class.
To satisfy OCP, I could use the Dynamic Service Locator (also described on Fowler's page) however I'm not totally sold on this for the same reasons as him, i.e. it's not explicit enough.
Another solution would be to just make all my models' methods static. So:
fooItem1234 = FooModel::findById(1234);
I like this because it's zero boilerplate. I can just create a new model class and start calling it from anywhere with a single line. But now the model depends on Locator to find its DB connection and I'm not sure how I feel about that. For one, if I ever needed to have two fooModels open on separate database connections, it would be a mess and/or impossible. That said, I don't actually need to do that currently so this option seems a little tempting.
Finally, there's DI. But like I said above I think it might be too much for this little project.
Conclusion: I'm a little stuck here and would appreciate some advice from the gurus of StackOverflow!
Why do you think that DI is overkill for your project? DI patterns such as Constructor Injection is way simpler and cleaner than Service Locator (which I consider an anti-pattern).
I consider Service Locator to be an anti-pattern since it is totally opaque to the user of the API which dependencies need to be in place; thus, one could easily invoke methods on your objects in a context where the Service Locator would throw, and the API gives you absolutely no clue that this is the case.
You don't need a DI Container to use DI. If just have a simple project, you can use what is known as Poor Man's DI where you wire up dependencies manually.
... and there is no need to have more than one instance.
You're mixing apples and oranges. The fact that you only need one instance of a class for an application, is not the same thing as it being a good idea to make that instance globally available. With DI you don't change the cardinality - there is still just one instance. What you change is the scope of variables that address said instance. There's a difference.

Categories