工厂模式(简单工厂、工厂方法、抽象工厂)(PHP)

工厂模式

工厂模式是封装对象的创建,用于解耦对象的创建和使用。工厂模式的实现分为三种:简单工厂、工厂方法和抽象工厂。
在《设计模式》一书中,简单工厂模式被看作是工厂方法模式的一种特例,所以工厂模式只被分为工厂方法和抽象工厂两类,都属于创建型模式。

简单工厂:是将不同的创建逻辑放到一个工厂类中,使用 if-else 或 map 的实现方式由工厂类根据参数判断返回要实例化的类。

//被创建的对象
interface IWork {
    public function perform()  ;
}
class Shopping implements IWork {
    public function perform() {
        echo 'Shopping~~~ ' ;
    }
}
class Meal implements IWork {
    public function perform() {
        echo 'Meal~~~' ;
    }
}
class Cleaning implements IWork {
    public function perform() {
        echo 'Cleaning~~~' ;
    }
}
//使用简单工厂的方式去获取创建对象
class WorkFactory {
    public static function createObj($type) {
        if ($type == 'shopping') {
            return new Shopping() ;
        } elseif ($type == 'Meal' ) {
            return new Meal() ;
        } elseif ($type == 'Cleaning' ) {
            return new Cleaning() ;
        }
    }
}
//使用工厂类创建对象
$object = WorkFactory::createObj('shopping')  ;
$object->perform() ;
$object = WorkFactory::createObj('Cleaning')  ;
$object->perform() ;

工厂方法:是将不同创建逻辑放到不同工厂类中,这样需要新增实现的时候,增加一个类即可。工厂方法模式比简单工厂模式更加符合开闭原则。
在实现中,可以先用一个工厂类的工厂(if-else / map 逻辑这个类中)来得到对应的工厂类,再用这个工厂类来创建对象。

//被创建的对象
interface IWork {
    public function perform()  ;
}
class Shopping implements IWork {
    public function perform() {
        echo 'Shopping~~~ ' ;
    }
}
class Meal implements IWork {
    public function perform() {
        echo 'Meal~~~' ;
    }
}
class Cleaning implements IWork {
    public function perform() {
        echo 'Cleaning~~~' ;
    }
}
//工厂类,将对象的创建放到不同的工厂类中
interface IFactory {
    public function createObj() ;
}
class ShoopingFactory implements IFactory {
    public function createObj() {
        return new Shopping() ;
    }
}
class MealFactory implements IFactory {
    public function createObj() {
        return new Meal() ;
    }
}
class CleaningFactory implements IFactory {
    public function createObj() {
        return new Cleaning() ;
    }
}
//工厂类的工厂
class WorkFactory {
    public static function createObj($type) {
        if ($type == 'shopping') {
            $factory = new ShoopingFactory() ;
        } elseif ($type == 'Meal' ) {
            $factory = new MealFactory() ;
        } elseif ($type == 'Cleaning' ) {
            $factory = CleaningFactory() ;
        }
        return $factory->createObj() ;
    }
}
//使用工厂类的工厂创建对象
$demo = WorkFactory::createObj('shopping');
$demo->perform() ;
$demo = WorkFactory::createObj('Meal');
$demo->perform() ;

什么时候使用简单工厂,什么时候使用工厂方法模式?
将部分代码块剥离封装为独立的函数或者类,是为了剥离后代码更加清晰,更加可读和可维护,所以如果代码块本身不复杂,就没有必要去剥离封装。
基于这个思想,当每个对象的创建逻辑都比较简单的时候,推荐使用简单工厂模式,将多个对象的创建逻辑放到一个工厂类中。
当对象的创建逻辑比较复杂,需要组合其他对象或者有各种初始化操作的时候,为了避免设计一个过于庞大的简单工厂类,推荐使用工厂方法,将复杂的创建逻辑拆分到各自的工厂类中。

抽象工厂:提供一个接口,用于创建多个相关或依赖的对象,让一个工厂负责创建多个不同类型的对象。可以有效的减少工厂类的个数。
抽象工厂模式的缺点在于创建对象类的扩展,假如在需要加入新的创建对象类,那么几乎所有的工厂类都需要进行修改。

//被创建的对象(一组)
interface IWork {
    public function perform()  ;
}
class Shopping implements IWork {
    public function perform() {
        echo 'Shopping~~~ ' ;
    }
}
class Meal implements IWork {
    public function perform() {
        echo 'Meal~~~' ;
    }
}
class Cleaning implements IWork {
    public function perform() {
        echo 'Cleaning~~~' ;
    }
}
//被创建的对象(二组)
interface IPay {
    public function spending()  ;
}
class ShoppingPay implements IPay {
    public function spending() {
        echo 'ShoppingPay~~~ ' ;
    }
}
class MealPay implements IPay {
    public function spending() {
        echo 'MealPay~~~' ;
    }
}
class CleaningPay implements IPay {
    public function spending() {
        echo 'CleaningPay~~~' ;
    }
}
//创建抽象类用来获取工厂类
abstract class AbstractFactory {
    public abstract function createWorkObj() ;
    public abstract function createPayObj() ;
}
class ShoopingFactory extends AbstractFactory {
    public function createWorkObj() {
        return new Shopping() ;
    }
    public function createPayObj() {
        return new ShoppingPay() ;
    }
}
class MealFactory extends AbstractFactory {
    public function createWorkObj() {
        return new Meal() ;
    }
    public function createPayObj() {
        return new MealPay() ;
    }
}
class CleaningFactory extends AbstractFactory {
    public function createWorkObj() {
        return new Cleaning() ;
    }
    public function createPayObj() {
        return new CleaningPay() ;
    }
}
//工厂类的工厂
class Factory {
    public static function loadFactory($type,$fType='work') {
        if ($type == 'Shopping') {
            $factory = new ShoopingFactory() ;
        } elseif ($type == 'Meal' ) {
            $factory = new MealFactory() ;
        } elseif ($type == 'Cleaning' ) {
            $factory = new CleaningFactory() ;
        }
        //也可以根据需要继续拆分为不同的工厂类
        if ($fType == 'work') {
            return $factory->createWorkObj() ;
        } else {
            return $factory->createPayObj() ;
        }
    }
}

$object = Factory::loadFactory('Shopping') ;
$object->perform() ;

$object = Factory::loadFactory('Shopping','pay') ;
$object->spending() ;

学习过程中,觉得看起来很懵或者感觉看懂了又没太看懂的时候,代码敲一遍,大概就明白了~~~ 反正我是这样的~~

你可能感兴趣的:(工厂模式(简单工厂、工厂方法、抽象工厂)(PHP))