dimanche 3 janvier 2016

Reflection API in Factory pattern

Usually we use Factory method to deal with the problem of creating objects without having to specify the exact class of the object that will be created.

Lets say we have 5 different implementations of some logger. Here is pseudo code how that would be implemented with traditional Factory method:

class LoggerFactoryMethod extends AbstractFactoryMethod {
function makeLogger($param) {
    $logger = NULL;
    switch ($param) {
        case "mysql":
            $logger = new MysqlLogger;
        break;      
        case "mongo":
            $logger = new MongoLogger;
        break;      
        case "txt":
            $logger = new TxtLogger;
        break;
        case "redis":
            $logger = new RedisLogger;
        break;
        case "memcached":
            $logger = new MemcachedLogger;
        break;
        default:
            $logger = new TxtLogger;
        break;    
    }     
    return $logger;
}

This works fine, but having many if/else (or switch/code) conditions is not so cool. Let say tomorrow we want to add one more implementation. We will need to modify this code and to add new case condition.

Instead, using Reflection API is more elegant and doesn't need significant change for new implementation. The same example using Reflection API would be :

class LoggerFactoryMethod extends AbstractFactoryMethod {
function makeLogger($param) {
    $allowed_implementations = array('mysql','mongo', 'txt', 'redis' , 'memcached');
    $class = new ReflectionClass($param);

    if (!in_array($param, $allowed_implementations) || !($class->IsInstantiable())){
        return null;
    }

    return $class->newInstance();
}

Are there any disadvantages using Reflection API instead traditional Factory pattern (using if/else conditions) ? Is it good practice to use it ?

Aucun commentaire:

Enregistrer un commentaire