arjan.top wrote:I still think singleton is the way to go, if you want to have add for example set() method, you will be always accessing the same object, if you create config file with new you can have multiple instances of config objects, so that can lead to bugs etc.
Singletons usually just introduce more complexity - it's yet another object to introduce.
Although two or more config objects don't make sense...I hardly think it would throw an exception if one were created. Using the single would also introduce a concrete dependency on the singleton.
Code: Select all
MyConfig::getInstance()->getData()
There is no benefit to using a singlton here I don't think. Granted it's easy enough to search & replace with a more dynamic implementaiton later, introducing the singleton object just adss clutter to the code. Start simple first and add these things as the need arises, don't just start hammering out design patterns because it's a documented best practice for a situation like this.
I say wait until the system requires the object remain at a single instance.
Let's say somewhere on one of my pages I instantiate the config object.. is it available inside of other classes? Or do I have to pass the config object to all of the other classes I will need? (seems messy) Another alternative would be to have all classes extend config.. but that seems even more messy.
Sorry, I'm just getting into learning the OO ways.
Here is where programmer discipline comes in...if your application is model 1 (multiple independent scripts) you need to take great care and make sure the config object is only created once at the start of every script. If you have a model 2 paradigm, you would likely create the object *once* inside the application entry point shortly before you instantiated your front controller.
This is why people tend to move towards model 2 - to avoid the nessecary disicpline in making sure the config object is created at the start of every script (and other reasons of centralized logic).
Here is a example:
Code: Select all
<?php // aboutus.php
include 'includes/config.php';
$obj = new MyObject($cfg); // Inject configuration object into MyObject() instance
$two = new MyTwoObject($cfg); // Inject configuration object again into another object
?>
Code: Select all
<?php // includes/config.php
$array = parse_ini_file('config.ini');
$config = new MyConfig($array);
?>
The latter example is an include which contains all your scripts common initialization code - config object, timezone, locale, etc
The first example is the actual script file which you invoke via the web browser. It creates 2 objects and injects the config object. I will show you how each of those objects would use the injected config object now:
Code: Select all
<?php
class MyObject{
$_config = null;
function __construct($config)
{
// Objects in PHP are passed by reference so this member is basically pointing back to the original config object
// but the dependency is no longer concrete, such as if we did something like this:
// $this->_config = new MyConfig('config.ini');
$this->_config = $config;
}
function executeQuery($keyword)
{
//
// Assume we store the user ID of a single blocked user inside the config object. We want the query to show all records
// except those of the blocked user (blog comments or similar). We use the injected config object and retreive the user ID
// store in a local (easier reading) and pass that along to the SQL query along with the single $keyword argument.
$userid = $this->_config->getUserId();
$res = mysql_query("SELECT * FROM table WHERE keyword LIKE $keyword AND userid = $userid");
}
}
Using the injection technique, you have removed the conrete dependency MyObject had on MyConfig and made it abstract. If you ever changed the name of the MyConfig class - say to some super config class called MySuperConfig, you need to only replace the single config object instantiation, not all the MyObject like classes that use the config class. Not only that but the configuration is left to the caller not the callee - this is typically much better design and makes for looser coupled classes - making them more reusable in the long run.