面向对象六大原则及单例模式

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了面向对象六大原则及单例模式相关的知识,希望对你有一定的参考价值。

参考技术A 单一职责原则 (SRP) 是指就一个类而言,应该仅有一个引起它变化的原因

开闭原则 (OCP) 是指软件中的对象对于修改应该是封闭的,对于扩展应该是开放的。

里氏替换原则是指所有引用基类的地方必须能透明地使用其子类的对象

依赖倒置原则是用于解耦的一种方式,主要有以下几个关键点:

接口隔离原则是指类间的关系应该建立在最小的接口上

迪米特原则是指一个对象应该对其它对象有最少的了解

所谓单例也就是说在一个类在系统中只存在一个实例,并且可以自行实例化向系统提供这个实例

适用于某个类有且仅有一个对象的场景,避免创建多个对象消耗过多的资源。

面向对象知识点续及单例模式

1、命名空间

命名空间的作用是避免了项目越来越大出现的命名冲突和混乱的问题

命名空间一般与文件的目录相对应,第一个命名空间前面不能有任何代码

在不同空间之间不可以直接调用其它元素,需要使用命名空间的语法:

<?php
namespace Article;

class Comment { }

namespace MessageBoard;

class Comment { }

//调用当前空间(MessageBoard)的Comment类
$comment = new Comment();

//调用Article空间的Comment类
$article_comment = new \\Article\\Comment();
?>
可以看到,在MessageBoard空间中调用article空间里的Comment类时,使用了一种像文件路径的语法: \\空间名\\元素名,除了类之外,对函数和常量的用法是一样的

2、自动加载

最早的php项目都是通过手工include或者require来载入依赖的文件的,当项目变大时,一个文件要依赖很多个php类,就需要写几十行require或者include语句,这会导致管理很不方便,也会导致一些错误。比如某个类删除了,但是require这个文件的语句没有去掉,会报一个致命错误。这时候可以采用类自动载入的方式处理这种类依赖关系。

<?php
spl_autoload_register(function ($class_name) {
    require_once $class_name . \'.php\';
});

$obj  = new MyClass1();
$obj2 = new MyClass2();
?>

 之前用的是__autoload() 函数,已经被废弃

 

3、链式查询

现在大多数框架都支持链式查询,其原理很简单:每个链式操作方法最后都返回当前对象

以下是示例文件:

 //database.php
function where($where)
    {
        return $this;
    }

    function order($order)
    {
        return $this;
    }

    function limit($limit)
    {
        return $this;
    }

这样便可持续调用了下一个方法了。

$db=new IMooc\\Database();
$db->where("id>20")->order(\'create_time desc\')->limit(10);

 

4、魔术方法

4.1、__get、__set方法,将对象的属性进行接管

一般来说,总是把类的属性定义为private,这更符合现实的逻辑

但是在类外调用一个未定义或者私有的属性会报错,便可以通过__get、__set方法获取和赋值其属性

$object=new IMooc\\Object();
$object->name=\'zhangsan\';
echo $object->name;
<?php
namespace IMooc;

class Object
{

    private $name=\'lisi\';
    function __set($key, $value)
    {
        $this->$key = $value;
    }

    function __get($key)
    {
        return $this->$key;
    }
}

 

4.2、__call、__callStatic ,控制类的方法

方法不存在时自动调用,可在报错时使用,保证代码的健壮性

 

5、单例模式

有些类只需要实例化一次,像数据库连接类,实例化多次的话会浪费资源,这时候就会用到单例模式

简单的来说是“三私一公”:

构造方法私有化后就不能从外部实例化类了,但是怎么实例化呢?

就要用到静态方法了,将其公有化,便可在外部实例化类了,

在方法里判断对象是否为空,如果为空就实例化,存在就直接将它返回,这样便实现了只实例化一次了

<?php
namespace IMooc;

class Database
{
   //私有化内部实例化的对象
    private static $instance = null;
   //私有化构造方法,禁止外部实例化
    private function __construct(){}
    //私有化__clone,防止被克隆
    private function __clone(){}
    // 公有静态实例方法
    public static function getInstance(){
       if(!empty(self::$instance)){
           return self::$instance;
       }else{
           self::$instance=new Database();
           return self::$instance;
       }
    }
}

$obj1=Database::getInstance();
$obj2=Database::getInstance();
$obj3=Database::getInstance();
var_dump($obj1,$obj2,$obj3);
echo $obj1==$obj2?1:0;
echo "<br>";
echo $obj1==$obj3?1:0;

 

打印结果如下:

 

 

 

 

 

 

以上是关于面向对象六大原则及单例模式的主要内容,如果未能解决你的问题,请参考以下文章

0608pm单例模式and面向对象的六大原则

面向对象知识点续及单例模式

面向对象高级C(元类补充及单例模式(待补充))

面向接口及单例工厂随笔

C++:静态成员及单例模式

[设计模式][面向对象]单例模式