I’ve decided it’s about time I rewrite my CMS, which was always designed to build business applications around. I’ve had it in use at some large companies (including a very large UK electrical retailer’s repair workshop) for some years but it’s been a proper patch job to work around the fact that when I originally wrote it I didn’t even know about writing my own functions, never mind using classes.
So, many many years later, I think it’s time to rewrite it (actually to v3: v2 had my own functions but I’d only just started working with classes at that time so very few were implemented) and while I’m planning it (rather than just code for a change) I was thinking about whether to use any singleton classes or not.
I must admit that I’m a bit baffled by singletons. Most other class types make sense; static, abstract etc, but singletons have always been an enigma to me. I understand that you can only have one instance of a singleton, but why would you want to restrict yourself like that? The most common use I’m seeing for them as I research this is for a database connection, which is great, but what if you have a need to connect to two or more databases? Am I missing the point?
I’m also a bit confused about interfaces. Strikes me as you’re just defining all of the methods that a class should have, but if you’ve coded the class then shouldn’t you know what methods are available? Missed the point on that one too, eh?
Seriously, I consider myself pretty knowledgeable about PHP, though far from an expert, but this has me thinking that if I implement singletons and interfaces that I’ll be doing so because “it’s what you should do”, rather than actually understanding why I’m doing it, and I would like to know. I’ve not found a decent enough explanation yet as to why I’d want to use either, just what they do. Please educate me
Sometimes there are objects that have some form of highly undesirable overhead where you cannot have any more than absolutely necessary running around. Maybe the object’s initialization takes way to long for your application performance, maybe it eats up way too much memory on the server. Whatever the reason… you don’t want multiple instances.
The Singleton is a pattern for ensuring that there’s only ONE instance of something and any request that needs it, simply uses that one.
You’re going about this backwards. In order to decide whether you need to implement a design pattern, such as Singleton, you need a problem that needs solving. Otherwise you’re probably just creating more problems.
Putting the ball back in your court, what is the most pressing problem with your existing CMS? Surely you must have a few if you are thinking of rewriting it. Once we have a problem or two, I (or another poster) would be happy to suggest a best practice solution.
To answer your interfaces question. Interfaces are normally created to complement one or more classes. A class can for instance, say it needs an object that implements a particular interface. By doing this, the class expecting an object that implements a particular interface can be certain of what public methods that object will have. For instance, let’s say we had a class which was responsible for logging; let’s call it the “log” class. This class would be responsible for receiving events, and logging them to some data source. To make the class more flexible and powerful, instead of putting the actual logging logic straight into the “log” class (such as opening a file, writing the event information on a new line, closing the file), the “log” class could delegate this to one or more other objects, which would be responsible for actually saving the event information to an actual destination, whether it be a file or a database. We’ll call these objects, “logger” objects or classes.
For this to work, all the “logger” objects would need to provide the same public methods, so the “log” class could call the same set of methods on any number of “logger” objects, without needing to know precisely what the “logger” objects were doing. The best way to enforce this is with interfaces. You could create an interface called “logger”, and then you could code the “log” class to only accept objects which implement the “logger” interface. By doing this, as long as the “logger” objects implemented the “logger” interface, the “log” class will be able to use them to delegate logging to.
Here’s a code example which may help clarify what’s a relatively simple concept, albeit a little difficult to explain. First of all, here are the classes and interfaces…
And here is how you may use it…
<?php
$fileLogger = new FileLogger('log.txt');
$databaseLogger = new DatabaseLogger($db);
$log = new Log;
$log->addLogger($fileLogger);
$log->addLogger($fileLogger);
$log->logEvent('4213', $log::WARNING, 'Could not update freight information from web service.');
So in summary, all an interface does is in this case (and in pretty much all cases), is provide a guarantee to the class Log, that if an object implements the Logger interface, then it’s safe to call the log() method on it with the arguments: id, type, time and description.
Interfaces are very powerful and should, generally speaking, be used more frequently than class inheritance and abstraction. A lot of people make the mistake of using inheritance and abstraction where an interface should instead be used instead. Correct use of interfaces is a critical factor in creating flexible and modular systems.
I would suggest you should use a registry rather than singleton pattern. Singleton pattern will become apparent when required, such as session::getInstance() when this method calls session_start and you want the class to know whether it should be initialized or just return a reference to the existing instance.
Registry has advantages, mostly to make your application easier to manage and flexible in future. Here’s the code I’ve been using for a simple hash registry:
global JFXRegistry = array();
class JFX_Registry{
public static function register($key, $object){
global $JFXRegistry;
$JFXRegistry[$key] = $object;
}
public function ®istry($key){
global $JFXRegistry;
if(!isset($JFXRegistry[$key])){
if(class_exists($key, true)){
$object = new $key;
JFX::register($key, $object);
return $object;
}
}else{
return $JFXRegistry[$key];
}
$obj = null;
return $obj;
}
/**
* Display all objects in the registry
*
*/
public static function printRegistry(){
global $JFXRegistry;
foreach($JFXRegistry as $keyname=>$obj){
echo $keyname.' : '.get_class($obj).'<br />';
}
}
}// end class
Of course this is copy/pasted so you’ll want to rewrite it and you’ll probably use a static class property rather than a global array. Note the print registry function which is a good advantage to have when you’re debugging to see what objects you’ve got on hand…
Interesting approach, that’s certainly an option having the advantage to keep and pass multiple instances of a registry, lots of flexibility there. Personally I like to keep the code near the global scope while organised within classes so don’t have to go tracing through too many files for debugging, hence the static methods to set and get on a global scope class with no instance per-se. Programming is a particularly flexible topic in terms of providing ample freedom for the developer to make decisions which will bring curse or praise from others down the line
I mean to say, that’s an equally good option allspiritseve, but I wouldn’t recommend it, its just a preference…
Oh, I see a crucial difference now (shows that discussion is a good thing): passing registry into the object keeps dependencies down, otherwise the recipient class would require the registry class as a dependency… fwiw the project I ripped it from has the register/registry functions in the JFX class (a “God” class which is a no-no in modern OOP). Yeah this is old code and really needs a tidy-up but it shows that a registry might be more along the lines of what Antnee was looking for compared to the singleton pattern.
Thanks for all of the advice guys, it’s much appreciated.
That’s actually a good question. I knew I needed to recode it but trying to think of a good answer to that question did have me thinking for a while about whether I could update or continue to work with the current version. The honest truth is just that it’s not terribly easy to develop for and that’s down to mistakes that I made when I coded it. It’s certainly hard-coded to only work in MySQL (there’s no option to switch DB types at all) and since I wrote it a couple of years ago my PHP has come on leaps and bounds and I’m now a little embarrassed of the code. I would just feel happier redeveloping it and bringing it up to date, as well as using some new features (very interested in playing with namespaces for example).
Anyway, the rest of the conversation is very helpful, and hopefully others will still have things to contribute. I think I’m understanding much better but I also find that I need to go off and do a little more reading too as there are new things mentioned that I’m not clear on and I’d rather read up before I start asking silly questions. So, thank you again guys, and I’ll be back if there’s anything else that I didn’t understand.
Couple of points about this. Congratulations, it sounds like you’ve learned a lot of new things and spent your time well. Looking at your code and realizing a lot of areas where your code can be improved, may seem embarrassing but it tells you that you’ve grown. Especially if you’re running into problems related to items you now know how to fix, I would say that is your justification for recoding the CMS.
Just make sure to take a couple cracks at testing first. If you are recoding then everything you’ve done before is now a prolonged “test” for version 2 (or 3 or 4?) That’s great in that it gives you a lot of real world experience with how this module could be improved. Don’t skip on testing now, make sure that those ideas really work, and work the way you thought they would. Then you can push a new version that’s legitimately improved with cool new features and streamlined performance.
Cheers, appreciate that. I don’t think this is the topic to go in to details but I need to consider many things. My CMS is highly modular and works something like this:
[list=1][]Load pre-page components - These are modular and load for every page before anything else happens. The user authentication system is a component for example, as is the DB connection
[]Load page - May be straight from the DB (ie simple HTML) or may be a special page, or module, which does something particular, like a customer database etc
[*]Load post-page components - Like the pre-page components but these run after the main page. Few are used compared to pre-page components and originally I didn’t see why any would be needed, but they were[/list]
So, the way that I’ve always done this in the past was to just go to index.php, usually passing it a parameter via the URL (and eventually getting in to rewriting the URL) and that’s handled everything. What never occurred to me when I was writing these things was that it might be nice to just have a single include in the top of files that made them a part of the system and that page includes the components and modules via one short line, rather than the system including the page I want to view.
If I’ve explained that properly then it’ll most likely seem obvious to most of you, and I feel a bit daft for having never thought of it, but it’s something that I’d like to put in now, so we have the option of which one to use. That’s another reason why I want to rewrite it
Your probably right, feel free to throw up other posts on any other topics or specific questions you have. We’ll be around.
Yeah, welcome to application development. I like Steve McConnell’s assessment (Code Complete 2) - design is a wicked process that you only really learn by doing it first and then figuring out what you did wrong after.
Hence the popularity of long-term iterative development projects where you strive first to build something useful and then refine it as you figure out how you should have built it in the first place.
What you’re really talking about is the concept of Encapsulation. Rather than writing code to do something, you simply call something else to take care of it. Sometimes it’s a call to another file (in your case a .php file), but it can also be done by calling another class in code or another function in your class. The advantage is that it’s shorter, the disadvantage is that it can get complicated if you go too many layers deep. I usually follow Abstraction and then encapsulate a little extra in places that I know are going to be magnets for future change. Encapsulation makes it MUCH easier to read code because your code blocks get shorter, which is a big reason for doing it. Encapsulation also makes your code more understandable if you choose good semantic, descriptive names for the class / function / file / etc. This helps make your code self-documenting.
However, I’m guessing that you probably considered this because you’ve had trouble maintaining all of those includes as you’ve made changes to the CMS over time. That’s another big advantage of encapsulation: information hiding. You would rather that the pages can call up the functionality you need to apply to them without knowing “anything” about what that is exactly. They should all just call the include file and let it go. That means when you have changes to make you only need to make them in one place (the include file) not all 50,000 pages in your website. It’s called the DRY model of programming (Don’t Repeat Yourself) and encapsulation is one of the main tools for implementing it. If there’s piece of code written into application in several places that would make you hunt all over if you ever had to change it, determine what the abstraction is, encapsulate that piece of code, and then have all the locations call the file / class / function.
I have some new ideas that I’d be happy to share, and I have some good articles that I’ve set aside to read through before I go to far too. I’ve also finally started using versioning software (in my case Subversion because that’s what we use at work and I already have an understanding of it, whereas GIT (for example) I don’t know at all) which should make my development much simpler.
I’m looking forward to getting back in to this as (apart from at work) I’ve not done a lot of development for a while, and a lot of our work is based around an 11-year old iHTML system that’s tables-and-frames based and a horror to work with. Fortunately there’s been a few years of converting parts to PHP before I started there and I’ve pushed to move away from the nested tables in to CSS which is going well
Singletons are a bit of a controversial design pattern. They simply enforce global state for the object that implements it (and that’s why they’re naughty). They are however very useful in a pinch - but can introduce problems when unit testing.
As mentioned earlier, Registry (which is often implemented as a Singleton) is a better bet for keeping unique references to classes. A variation on this pattern is Monostate, which can be instantiated several times, but share common properties. If you change a property in one instance, that property changes in all instances. Again, can lead to problems if you’re not careful.
Interfaces are essentially a “contract” to enforce the an API in classes that use them. The coder can then use objects that implement the interface and know that method X will be available. This is really useful if you’re working in teams, but since you’re not, it’s probably not so important (as with the Singleton).
In this instance, you might want to do some research into Dependency Injection, which in a nutshell is giving an object it’s resources using an external method, i.e. setting it in the constructor or using a method:
I would disagree somewhat. If you need to create a large complex object that takes 2 minutes to instantiate, that’s a long time for any user to wait for a page to come up. If you can’t live without that object, and it can handle all the work your app needs to do, you should be using a singleton pattern to build that. They are slippery, however, especially in threaded environments.
I disagree, interfaces have nothing to do with team vs. solo development. To site one key advantage, interfaces allow you to write DRY code (Don’t Repeat Yourself) vs. WET code (Write Everything Twice). Let’s say I write web page 1, which feeds some user input variables to a user management class, which passes the variables on to a session manager, which passes the variables into another application layer where who only knows what happens to them. You write all the necessary code to pass these variables through to wherever they’re going to be worked on. You’re done. Phew!
Now you start to write web page 2, and 3 and 4… No WAY are you going to survive when it comes time to maintain this application using the current architecture. All these different but similar classes and all the virtually identical code necessary to make them work would kill you. Enter interfaces.
At some point you know you’re going to be using multiple classes that will share a particular responsibility; maybe you know that when you’re building the first class, but without a doubt you know it when you start to write class 2. Now you know it’s time for interfaces. Let’s say you have a corporate intranet that sends a “Happy Birthday” email to your employees on their birthday. It checks as part of an automated daily batch, to see if there are any employees with birthdays today and returns an employee object for each employee with birthdays today. It then passes the employee object to a function with this signature
Everything looks beautiful until the new head of Marketing gets his first email and comes into the weekly staff meeting raving about what a difference it made in a hard day and how we should be sending the same email to all of our customers. The President of course thinks this is brilliant and tells you to “take care of it”. Problem is, your function won’t work for Customer objects, it only works for Employee objects. Time to retool. We need to rewrite the function so that it no longer works on Employees but anything that has a birthday. Hence…
You function will likely need the age and email address of the birthdayee, so write the function with a couple of phantom functions for now. personWhoNeedsBirthdayEmail.getAge() to obtain the age and personWhoNeedsBirthdayEmail.getEmail() to obtain the email address. These probably are not the names in the employee class, so you’ll need to rename the functions to getAge() and getEmail(). (Note that if the original function names are applicable to customers, you can use those function names, but if you have getEmployeeAge() that’s not going to cut it.) Now you write those functions for the customer class. We’ve now written the code in each class that puts implementation to the “phantom” functions that we called in the emailBirthdayGreetings() function. We also need to formally implement the interface so that the application knows which classes implement which interfaces. Forgive my lousy PHP skills, but in C# you do it in the class declaration like this…
public class Employee : IHasBirthday, IAnotherInterface
Finally you need the actual interface that defines the contract. Look at what this really means. Your function emailBirthdayGreetings() is a beautiful flexible function that can do work for any class which implements IHasBirthday. That’s cool. However, it is calling two functions getAge() and getEmail(). Those are the functions which any IHasBirthday class needs to promise to have available, so the interface defines that contract, ie it puts that promise in writing.
public interface IHasBirthday
{
int getAge();
string getEmail();
}
Note: PHP is an interpreted language and I’ve written this with that idea in mind. For those of you using multiple languages, compiled languages reap additional major benefits from interfaces. For example, it’s standard in both C# and Java for the compiler to determine if a class which formally implements an interface actually implements the contract or not. It can also evaluate functions and class usages to be certain that they use the interface contracts correctly. In other words, your compiler does a lot of free debugging for you, which makes interfaces especially valuable in compiled languages.
Why “should”? Setting aside my suspicion that those types of objects are rare, I don’t see any reason why you couldn’t just instantiate it in a bootstrap file or front controller, and pass it wherever it is needed in the application. Or place it in a Registry. Or a Dependency Injection Container. In other words, there are a number of alternatives to your Singleton and your criteria does not indicate a specific one that “should” be implemented over the others.
Interesting. For one thing, I don’t think we need to be suspicious, I’ve never used the Singleton pattern once, so I’m quite comfortable with calling them rare. In your opinion then, is this a case of a design pattern looking for a problem? Or is there a particular use case where the singleton pattern would be the preferred solution.
Like any decision between patterns, there are tradeoffs involved. If you’re willing to search, Kyberfabrikken has some great posts on this subject.
In a nutshell, though, you are weighing complexity against how decoupled you want your code to be. A Singleton is simple, but has a lot of side effects. On the other end of the spectrum, a Dependency Injection Container is (can be?) complex, but is the most decoupled solution.
I can’t say what might lead you to decide Singleton is the right pattern, but there are definitely things that would rule it out. If you need to unit test, for example, Singleton is probably not an ideal choice.
It seems to me that if you have an object that takes two minutes to instantiate, you have bigger issues than Singleton versus anything else, this is especially true for objects in PHP. Also, if that object takes care of all the work your app needs to do, you’ve essentially created a god object.
That’s some complicated object…
As I said, it’s a useful pattern (Zend is riddled with it), but it’s anathema to Unit testing.
I can’t really comment on other languages, JS and PHP being my staples - but interfaces don’t allow/enable you to adhere to DRY principles - as you point out, they just enforce a contract on objects that implement them (They also enable you to enforce type based on interface rather than class.):
That inevitably helps in designing the API, but doesnt help you write DRY code any more than inheritance (or personal discipline). I believe that this “contract” becomes more meaningful when working in teams - the architect can define interfaces that lock the application together.