BO
70 2
Asked
Updated
Viewed
4.4k times

Are there any benefits of using the factory design pattern? Is it considered a bad practice?

  • 0
    Like most things, factories have their benefits and drawbacks. Have you read up on them? Are there any particular problems you're facing that you think would benefit from implementing one? — Nightslyr
add a comment
0

1 Answer

  • Votes
  • Oldest
  • Latest
BO
70 2
Answered
Updated

For me the benefit of using the factory design pattern in my situation is that it allows me to to use a class with drivers (so to speak).

For instance, I have a database abstract class with drivers, a class that extends it, MySQLi (with possible add-on drivers like postgreSQL, SQLlite, and so on), and these drivers are in a different folder.

Or for mail, you could mail via SMTP or regular mail, and the way you would set it up would be different. You have an abstract class in main includes directory and the drivers in the mail/ folder.

The directory tree would look something like:

main/includes/database.php
main/includes/mail.php
main/includes/db/mysqli.php
main/includes/db/postgresql.php
main/includes/db/sqllite.php
main/includes/mail/smtp.php
main/includes/mail/mail.php
main/index.php

Then I use factory to set what I need.

$ret = simplexml_load_file(CONFIG_FILE);
$dbase = (string) $ret->dbase;
$db = factory::load($dbase, 'db');

That would load MySQLi.php in the db folder.

I also created a function in factory class/singleton where I only retrieve the path of the file:

$captcha_loc = factory::locate($captcha[$type], 'captcha');

And I also have an autoload function set-up in my factory singleton...

/**
 * public static function register()
 * 
 *      Registers the autoload function
**/

public static function register()
{
    spl_autoload_register(array(new self, 'autoload'));
}

/**
 * public static function autoload( string $class )
 *      @string $class - The name of the class (and the file [mostly]) loaded
 * 
 *      The autoload function
**/

public static function autoload($class)
{
    // Checking if we are doing it for twig or not
    if(substr($class, 0, 5) == 'Twig_')
    {
        // Setting the class to self
        self::$class = $class;

        // Setting the main
        self::$_main = './includes/';

        // Retrieving the directory structure in which the file is located in
        // (The classes are written with the directory structure (from the ./includes
        // folder) is in the class name. For instance a class named, Twig_Extension_Core
        // is located in ./includes/Twig/Extension/Core.php).
        $path = explode('_', $class);

        // The path to the file in which the class is located
        self::$_file = self::$_main . implode('/', $path) . '.php';

        // Checking if the file exists
        if(file_exists(self::$_file))
        {
            // If the file exists, we are returning the filepath
            return include_once(self::$_file);
        }

        // The file failed to be included... dying
        die(self::$_file . ' failed to be included!');
    }
    else
    {
        // Setting the class to self
        self::$class = $class;

        // Setting the main
        self::$_main = './includes/';

        // Our file path
        self::$_file = self::$_main . self::$class . '.php';

        // Checking if the file exists
        if(file_exists(self::$_file))
        {
            // If the file exists, we are returning the filepath
            return include_once(self::$_file);
        }

        // The file failed to be included... returning false
        die(self::$_file . ' failed to be included!');
    }
}

Not sure if I explained my reasoning well in using a factory, but I think it's working fine.

  • 0
    Your database idea has already been addressed by PDO. 😉 For your mailer idea, you may also want to look into the Strategy Pattern. With that, generally speaking (since design patterns are purposely half-baked) you'd have one mailer object that would act as a wrapper API to various implementations that can be selected at runtime (and perhaps chosen/generated via a factory). — Nightslyr
  • 0
    The thing with PDO is, I'm using MySQLi. I'm guessing it's a bit faster then PDO. Never heard of the strategy pattern, though I have thought about doing it that way, but for some reason I wanted to use an abstract class instead, rather then a wrapper (kind of) class that chooses the type of mailer/db to use (as per config file/setting etc). — Bogey
  • 0
    Any speed benefits of MySQLi over PDO are likely negligible. And you get the benefit of not having to reinvent the wheel, instead having battle-tested code at your disposal. Keep in mind, you can use a factory to determine the strategy your strategy object uses. You might not even need the wrapper if all you want is a consistent API. You can use either an interface or, like you want, abstract class for that. Just throwing out ideas/things for you to consider. 🙂 There's definitely more than one way to attack the problem, and none are necessarily the 'right' way. — Nightslyr
  • 0
    You're right, none are necessarily the 'right' way, but I'm hoping to find the best way. One thing about being self-taught is that you miss a lot of stuff when starting to learn programming so when you get to developing programs, even though you know the general idea of how to accomplish something, you don't know the different ways, pros/cons of them, and so on and so forth. — Bogey
add a comment
0