美文网首页
工厂模式(简单工厂、工厂方法、抽象工厂)(PHP)

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

作者: 嗼念 | 来源:发表于2021-10-26 19:26 被阅读0次

    工厂模式

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

    简单工厂:是将不同的创建逻辑放到一个工厂类中,使用 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)

          本文链接:https://www.haomeiwen.com/subject/nocnoltx.html