Jump to content

Static Methods vs. Singleton vs. Dependency/constructor Injection


adam_bray

Recommended Posts

I'm looking for some clarification here from different viewpoints to understand real world applications.

In a previous thread, I suggested to someone that they read up on singleton methods to restrict class duplication (oops!), I was quickly (and rightfully) shot down. I did this after having read through blog posts that also suggested singleton design to stop multiple MySQL connections. At the time I didn't consider that could be useful to some people.. fair enough.

Thankfully I don't use singleton methods within my own code, but I do use static methods for most things. Reading through numerous blog posts, tutorials, etc.., it seems like static methods can also be considered anti-design and is something to avoid.

So now it seems I'm at a point where I need to rewrite my existing framework & CMS, probably using dependency injection within my classes. I understand how this works, and why it makes sense.

What I'm struggling with is understanding how to use dependency injection within a (personal) CMS application.

For example - 

  • I have a config.ini file
  • I have a class that reads the .ini file, stores the variables, and provides me methods to access them
  • I have a content class that selects the relevant page/component from the DB (db & config dependency), then displays it via my template engine.
  • Within the included view files I call component classes (articles, contact, etc..), each of these require a connection to the DB, which has a config dependency.

Here's some code to explain it better -
index.php

<?php
$settings = '/config/config.ini';

$config = new Config($settings);

$db = new Database($config);

$content = new Content( $db ); // Config may also be passed for content config - keeping it simple for example
print $content->loadPage($_GET['page']); // This would now include the code below
?>

Let's say that this then loads the article index (through $content->loadPage()). The view would look something like this -
article_index.php

<?php
// Duplicated code
$settings = '/config/config.ini';

$config = new Config($settings);

$db = new Database($config);

// Article code
$articles = new Articles_Model($db);
return $articles->getArticles(0,15);
?>

Now my problem is that I'm duplicating the config and db class calls for no reason.

Is the sollution to store these within a registry class? But then I'm creating globals, which again seems anti-design.

Or is the problem how I load the active page?

Any insights would be much appreciated.

Link to comment
Share on other sites

"Anti-design" does not mean something is bad. It means it's easy to abuse the design towards a bad end. Registries, singletons, static members, being anti-design means that you should think about how you are using them, not that you have to avoid them entirely.

 

I could go for any of:

a) A registry of the values, as you do need to propagate values across multiple locations

b) A singleton for the various objects, but only if there are never multiple configuration files, configuration objects, or database connections

c) Dependency injection by way of variables: have loadPage() set values, maybe looking like

print $content->loadPage($_GET['page'], array('db' => $db));
and then you'll have $db (or $this->db or whatever) set for you. This actually shares a lot in common with (a). Edited by requinix
Link to comment
Share on other sites

None of your examples includes a DI. Here's a rewrite of your index.php with DI:

 

$di = include 'includes/di.php';

$di['content']->loadPage($_GET['page']);
And your article_index.php

 

$di = include 'includes/di.php';

$di['articles']->getArticles(0, 15);
The includes/di.php could look something like:

 

// download from http://pimple.sensiolabs.org/
$container = new Pimple();

$container['config_filepath'] = 'config/config.ini';

$container['config'] = function($c) {
    return new Config($c['config_filepath']);
};

$container['db'] = function($c) {
  return new Database($c['config']);
};

$container['content'] = function($c) {
  return new Content($c['db']);
};

$container['articles'] = function($c) {
  return new Articles_Model($c['db']);
};

return $container;
For all your autoloading you may want to consider composer Edited by ignace
Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.