PHP单例设计模式与工厂设计模式

PHP单例设计模式与工厂设计模式

单例设计模式

概念

一个类只能创建一个实例对象,不管用什么方法都无法创建第2个对象, 比如,数据库类

单例设计模式的要求(三私一公)

一私:私有的静态的保存对象的属性
一私:私有的构造方法,阻止类外new对象
一私:私有的克隆方法,阻止类外clone对象
一公:公共的静态的创建对象的方法

单例设计模式的核心代码

<?php
//单例设计模式的核心代码
class Db
{
    //私有的静态的保存对象的属性
    private static $obj = null;

    //私有的构造方法:阻止类外new 对象
    private function __construct()
    {
    }

    //私有的克隆方法:阻止类外clone对象
    private function __clone()
    {
        // TODO: Implement __clone() method.
    }

    //公共的静态的创建对象的方法
    public static function getInstace()
    {
        //判断当前对象是否存在
        if(!self::$obj instanceof self) //instance 判断一个对象是不是某个类的对象
        {
            //如果对象不存在,创建并保存它
            self::$obj = new self();
        }

        //返回对象
        return self::$obj;
    }
}
//创建数据库类的对象
$db1 = Db::getInstace();
$db2 = Db::getInstace();
var_dump($db1,$db2);

单例设计模式的实例:数据库类 Db.class.php

<?php
//单例设计模式的核心代码
//数据库模块
class Db
{
    //私有的静态的保存对象的属性
    private static $obj = null;

    //私有的数据库配置信息
    private $db_host;   //主机名
    private $db_user;   //用户名
    private $db_pass;   //密码
    private $db_name;   //数据库名
    private $charset;   //字符集
    private $link;      //连接对象

    //私有的构造方法:阻止类外new 对象
    private function __construct($config=array())
    {
        $this->db_host = $config['db_host'];
        $this->db_user = $config['db_user'];
        $this->db_pass = $config['db_pass'];
        $this->db_name = $config['db_name'];
        $this->charset = $config['charset'];

        $this->connectDb();//连接数据库
        $this->selectDb();//选择数据库
        $this->setCharset();//设置字符集
    }

    //私有的克隆方法:阻止类外clone对象
    private function __clone()
    {
        // TODO: Implement __clone() method.
    }

    //公共的静态的创建对象的方法
    public static function getInstace($config)
    {
        //判断当前对象是否存在
        if(!self::$obj instanceof self) //instance 判断一个对象是不是某个类的对象
        {
            //如果对象不存在,创建并保存它
            self::$obj = new self($config);
        }

        //返回对象
        return self::$obj;
    }
    //私有的链接MySQL服务器方法
    private function connectDb()
    {
        if (!$this->link = @mysqli_connect($this->db_host,$this->db_user,$this->db_pass))
        {
            echo "连接数据库失败";
            die();
        }
    }

    //私有的选择数据库的方法
    private function selectDb()
    {
        if(!mysqli_select_db($this->link,$this->db_name))
        {
            echo "选择数据库{$this->db_name}失败!";
            die();
        }
    }

    //私有的设置字符集
    private function setCharset()
    {
        mysqli_set_charset($this->link,$this->charset);
    }

    //公共的执行SQL语句的方法:insert update delete set drop
    //执行成功返回true,执行失败返回false
    public function exec($sql)
    {
        //例如:update student set salary = salary+500 where id=5

        //将sql语句转化成全小写
        $sql = strtolower($sql);

        //判断是不是select语句
        if(substr($sql,0,6)=='select')
        {
            echo "不能执行select语句";
            die();
        }

        //返回执行结果,为bool值
        return mysqli_query($this->link,$sql);
    }

    //私有的执行sql语句的方法:select
    //执行成功返回结果集对象,失败返回false
    private function query($sql)
    {
        //例如 select *from student
        //将sql语句转化成全小写
        $sql = strtolower($sql);

        //判断是不是select语句
        if(substr($sql,0,6)!='select')
        {
            echo "不能执行非select语句";
            die();
        }

        //返回执行结果集对象,后续数据取出,处理,送给前端
        return mysqli_query($this->link,$sql);
    }

    //公共的获取单行数据的方法
    public function fetchOne($sql,$type=3)
    {
        //执行Sql语句,并返回结果集对象
        $result = $this->query($sql);

        //定义返回数组类型的常量
        $types = array(
            1 => MYSQLI_NUM,
            2 => MYSQLI_BOTH,
            3 => MYSQLI_ASSOC,
        );

        //返回一维数组
        return mysqli_fetch_array($result,$types[$type]);
    }

    //公共的获取多行数据的方法
    public function fetchAll($sql,$type=3)
    {
        //执行sql语句,并返回结果集对象
        $result = $this->query($sql);

        //定义返回数组类型的常量
        $types = array(
            1 => MYSQLI_NUM,
            2 => MYSQLI_BOTH,
            3 => MYSQLI_ASSOC,
        );

        //返回二维数组
        return mysqli_fetch_all($result,$types[$type]);
    }

    //获取记录数
    public function rowCount($sql)
    {
        //执行sql语句,返回结果几对象
        $result = $this->query($sql);

        //返回记录数
        return mysqli_num_rows($result);
    }


    //公共的析构方法
    public function __destruct()
    {
        // TODO: Implement __destruct() method.
        mysqli_close($this->link);//断开mysql连接
    }
}
$arr = array(
    'db_host'=>'localhost',
    'db_user'=>'root',
    'db_pass'=>'135262',
    'db_name'=>'php_test',
    'charset'=>'utf8'
);

工厂设计模式

概念

根据不同的类名参数,返回不同类的对象
工厂模式,就是生产各种不同类的对象
工厂模式:改变了在类外使用new关键字创建对象的方式,改成了在工厂类中创建
        类的对象
在类的外部我们无法控制类的行为,但在类内部自己可以控制类的行为

工厂设计模式的要求

一般情况下,定义一个工厂类
工厂类中的方法,应该就是公共的静态的方法
该方法功能:就是根据传递的不同参数,去创建不同的类实例

工厂设计模式的核心代码

Shape.class.php

<?php
//定义形状接口
interface Shape
{
    //绘制方法
    public function draw();
}

Rectangle.class.php

<?php
//定义矩形类,并实现形状接口
class Rectangle implements Shape
{
    //重写draw()方法
    public function draw()
    {
        // TODO: Implement draw() method.
        echo "正在绘制矩形";
    }
}

Circle.class.php

<?php
class Circle implements Shape
{
    //重写draw()方法
    public function draw()
    {
        // TODO: Implement draw() method.
        echo "正在绘制圆形";
    }
}

Line.class.php

<?php
//定义线型类,并实现形状接口
class Line implements Shape
{
    //重写draw()方法
    public function draw()
    {
        // TODO: Implement draw() method.
        echo "正在绘制线条";
    }
}

Factory.class.php

<?php
//定义形状工厂类:生产不同形状对象的工厂

class Factory
{
    //公共的静态的创建不同类对象的方法
    public static function getInstance($className)
    {
        //根据传递的不同类名参数,返回不同类对象
        switch ($className)
        {
            case "Rectangle":
                return new Rectangle();
                break;
            case "Circle":
                return new Circle();
                break;
            case "Line":
                return new Line();
                break;
            default:
                return null;
        }
    }
}

app.php

<?php
//类的自动加载
spl_autoload_register(function ($className){
    //构建类文件的路径
    $filename = "$className.class.php";
    //如果类文件存在,则包含
    if (file_exists($filename)) require_once ($filename);
});

//创建矩形对象
$rectangle = Factory::getInstance("Rectangle");
$rectangle->draw();

总结

单例模式会阻止其他对象实例化其自己的单例对象的副本,从而确保所有对象都访问唯一实例,
	可以有效限制实例化对象
单例设计模式比较适用于类似数据库类这种具有统一性行为的类
工厂模式相对于后期扩展来说比较容易,也就是有更好的维护性和扩展性
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值