博客列表 >单例模式与工厂模式,面向接口编程 - 第九期线上班 20191208

单例模式与工厂模式,面向接口编程 - 第九期线上班 20191208

MArtian
MArtian原创
2019年12月08日 22:15:21905浏览

单例对象

// 单例模式管理class Demo1{
    //构造方法私有化
    private function __construct()
    {
    }
    // 目前只能在类中的内部将类实例化
    public static $instance = null;
    public static function getInstance(){
        // 实例化当前类,并返回实例/对象
        // 判断当前类是否已经被实例化了,如果没有就实例化,如果有就返回这个实例
        if (is_null(self::$instance)){
            self::$instance = new self();
        }
        return self::$instance;
    }

    // 禁用克隆魔术方法,防止类被复制,产生多个实例
    private function __clone()
    {
        // ...
    }}// new Demo1();  因为构造方法私有化,不能从外部访问,所以无法用new来创建Demo1实例$demo1_obj1 = Demo1::getInstance();$demo1_obj2 = Demo1::getInstance();echo var_dump($demo1_obj1 === $demo1_obj2); // 两个实例完全相等echo '<br>';var_dump($demo1_obj1,$demo1_obj2);  // 两个实例ID相同echo '<hr>';// 单例模型应用场景class Db{
    // 构造方法私有化
    private function __construct($contentParams)
    {
        $dsn = $contentParams[0];
        $user = $contentParams[1];
        $password = $contentParams[2];
        print_r($contentParams);

        echo '<hr>';
        self::$pdo = new \PDO($dsn, $user, $password);
    }
    public static $pdo = null;

    // 实例化当前类的方法
    public static function getInstance(...$contentParams)
    {
        // 实例化当前类,并返回实例/对象
        // 判断当前类是否已经被实例化了,如果没有就实例化,如果有就返回这个实例
        if (is_null(self::$pdo)){
            new self($contentParams);
        }
        return self::$pdo;
    }

    // 禁用克隆魔术方法,防止类被复制,产生多个实例
    private function __clone()
    {
        // ...
    }}$pdo = Db::getInstance('mysql:host=localhost;dbname=phpcn','root','123456');print_r($pdo->query('SELECT * FROM `wuxia`')->fetchAll());

工厂模式

namespace _Factory;class F1{
    public function __construct($arg1)
    {
        echo '创建对象成功,参数是:' . $arg1;
    }}class F2{
    public function __construct($arg1,$arg2)
    {
        echo '创建对象成功,参数是:' . $arg1 . $arg2;
    }}class F3{
    public function __construct($arg1,$arg2,$arg3)
    {
        echo '创建对象成功,参数是:' . $arg1 . $arg2 . $arg3;
    }}class Factory{
    // 静态方法接收类名与构造函数的参数
    public static function creat($className, ...$arguments){
        return new $className(...$arguments);
    }}//F1::class声明完整的类名,带有命名空间路径,不加::class找不到命名空间中的类,如果是全局类,要在类名前添加\转义,不用添加::classFactory::creat(F1::class,100);//echo F1::class; 含有完整路径的类名echo '<hr>';Factory::creat(F2::class,100,111);echo '<hr>';Factory::creat(F3::class,100,111,111);

MVC容器

class Client1{
    public function show($product,$maker){
        return $product->get($maker);
    }}//生成容器实例类$container = new Container();$container -> bind('product',function(){return new Product;});$container -> bind('maker',function(){return new Maker;});$product = $container -> make('product');$maker = $container -> make('maker');echo (new Client1())->show($product,$maker);

面向接口编程

namespace base;require __DIR__ . '/autoload.php';use base\inc2\Car;use base\inc2\Ship;use base\inc2\Plane;use base\inc2\Train;use base\inc2\iVehicle;class Travel3{
    private $vehicle;
    public function __construct(iVehicle $vehicle) // 声明接口,只要实现了接口方法的类都可以被调用
    {
        $this->vehicle = $vehicle;
    }
    public function travelMode(){
        return $this->vehicle->drive() . ':===去旅行';
    }}echo (new Travel3(new Car()))->travelMode().'<br>';echo (new Travel3(new Train()))->travelMode().'<br>';echo (new Travel3(new Plane()))->travelMode().'<br>';echo (new Travel3(new Ship()))->travelMode().'<br>';

总结

  1. 单例模式避免了对象被重复生成,适用于仅生成一次对象,类似与PDO连接,方法是首先将类中的构造函数私有化,不能通过外部访问,然后再禁用克隆模式,避免对象被重复生成,使用静态方法生成对象,在调用该方法时,判断该类是否被实例化,如果有,返回该类的实例,如果没有,创建该类的实例。

  2. 工厂模式可以一次生成多个对象实例。

  3. 面向接口编程,便于扩展,还可以避免代码耦合,在类的构造中声明接口类型,只要是实现接口的函数都可以被接收和调用。

  4. 在容器类中,我尝试了在创建类实例make方法中输入类的构造参数,需要在绑定bind方法的匿名函数中写接收,然后分别在类和类构造方法中使用变量接收,最终才会生成构造类实例。

未标题-1.png

声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议