设计模式及面向对象高级特性(上)

简介: 今日目标能够掌握面向对象的高级特性能够具备设计纯面向对象框架和系统的能力能够遵循PSR-0规范开发一个基础框架能够掌握单例模式能够掌握工厂模式能够掌握注册树模式

今日目标


  • 能够掌握面向对象的高级特性
  • 能够具备设计纯面向对象框架和系统的能力
  • 能够遵循PSR-0规范开发一个基础框架
  • 能够掌握单例模式
  • 能够掌握工厂模式
  • 能够掌握注册树模式


一、什么是设计模式?


1.概念

设计模式(英语 design pattern)是对面向对象设计中反复出现的问题的解决方案。

2.举例

如果我们把面向对象编程当成一本武功秘籍,设计模式就是其中的每一招每一式,如果我们可以把设计模式式活学活用,那在面向对象编程方面那一定是一个非常厉害的高手了!


二、开发环境准备


一、编辑器的选址


1.下载PHPStorm


2.选择编程字体


  • 必须选择等宽字体
  • 常见的等宽变成自提包括Courier Nes,Consolas
  • 个人推荐大家使用Soure Code Pro,是由Adobe公司专为程序员设计,免费开源

默认字体展示出来的效果:

设置等宽字体:

设置玩字体展示出来的效果:


三、命名空间与类自动载入


一、 命名空间的介绍


概念

namespace即“命名空间”,也称“名称空间” 。各种语言使用的一种代码组织的形式 通过名称空间来分类,区别不同的代码功能

基本介绍

命名空间是用来组织和重用代码的。如同名字一样的意思,NameSpace(名字空间),之所以出来这样一个东西,是因为人类可用的单词数太少,并且不同的人写的程序不可能所有的变量都没有重名现象,对于库来说,这个问题尤其严重,如果两个人写的库文件中出现同名的变量或函数(不可避免),使用起来就有问题了。为了解决这个问题,引入了名字空间这个概念,通过使用 namespace xxx;你所使用的库函数或变量就是在该名字空间中定义的,这样一来就不会引起不必要的冲突了。


2.命名空间的使用


==a)不使用命名空间,案例演示==

运行报错(无法重新声明方法)

==b)使用命名空间案例演示==

正常运行(输出当前的文件名称)


3.Phpstorm在控制台中输出运行结果


参考链接:blog.csdn.net/weixin_3718…

1、先打开菜单Run->Edit Configurations选项

2、然后在打开的窗口中点击左上角的+号

3、在打开的菜单中选择PHP Script

4、在打开的界面中找到Configuration->File

5、选择你要在控制台运行的文件

6、填入工作目录的路径(可填可不填),完成配置后点击右下角的OK

7、回到主界面,点击菜单Run->Run


二、类自动载入


1.概念

在编写面向对象(OOP) 程序时,很多开发者为每个类新建一个 PHP 文件。 这会带来一个烦恼:每个脚本的开头,都需要包含(include)一个长长的列表(每个类都有个文件)。

spl_autoload_register() 函数可以注册任意数量的自动加载器,当使用尚未被定义的类(class)和接口(interface)时自动去加载。通过注册自动加载器,脚本引擎在 PHP 出错失败前有了最后一个机会加载所需的类。

==Note==

尽管 __autoload() 函数也能自动加载类和接口,但更建议使用 spl_autoload_register() 函数。 spl_autoload_register() 提供了一种更加灵活的方式来实现类的自动加载(同一个应用中,可以支持任意数量的加载器,比如第三方库中的)。因此,不再建议使用 __autoload() 函数,在以后的版本中它可能被弃用。

参考链接:www.php.net/manual/zh/f…


三、开发一个PRS-0的基础框架


1.PRS-0规范
  • 命名空间必须与绝对路径一致
  • 类名首字母必须大写
  • 除入口文件外,其他".php"必须只有一个类


2.开发符合PSR-0规范的基础框架
  • 全部使用命名空间
  • 所有PHP文件必须自动载入,不能有include/require


3.进行开发框架

进行带领同学们共同封装一个基础框架

进行测试框架

入口文件自动加载所有的类文件


五、PHP面向对象高级特性


一、SPL库的使用(PHP标准库)


参考链接:www.php.net/spl

==SPL库的使用(PHP标准库)==

  • SplStack、SplQueue、SplHeap、SplFixedArray等数据结构
  • ArrayItertor、AppendIterator、Countable、ArrayObject
  • SPL提供的函数


1.栈操作

概念:SplStack类通过使用一个双向链表来提供栈的主要功能。

特性:先进后出

$stack = new SplStack();
$stack->push("data1\n");
$stack->push("data2\n");
echo $stack->pop();
echo $stack->pop();
复制代码


2.队列操作

概念:SplQueue 类通过使用一个双向链表来提供队列的主要功能。

特性:先进先出

$queue = new SplQueue();
$queue->enqueue("data1\n");
$queue->enqueue("data2\n");
echo $queue->dequeue();
echo $queue->dequeue();
复制代码


3.最小堆

概念:SplMinHeap类提供堆的主要功能,将最小值保持在顶部。

$heap = new SplMinHeap();
$heap->insert("data1\n");
$heap->insert("data2\n");
echo $heap->extract();
echo $heap->extract();


4.最小长度的数组  固定尺寸数组

概念:SplFixedArray类提供了数组的主要功能。SplFixedArray与普通PHP数组之间的主要区别在于,必须手动调整SplFixedArray的大小,并且只允许范围内的整数作为索引。优点是它比标准阵列使用更少的内存。

$array = new SplFixedArray(10);
$array[0] = 123;
$array[9] = 1234;
var_dump($array);
复制代码


二、PHP链式操作的实现


1.如何实现数据库链式操作

==$db->where()->limit()->order();==


2.实现代码

文件:Vendor/Database.php

<?php
namespace Vendor;
class Database
{
    function where($where)
    {
        return $this; //链式操作的核心就是返回当前对象
    }
    function order($order)
    {
        return $this;
    }
    function limit($limit)
    {
        return $this;
    }
}
复制代码


文件:index.php


//不是链式操作
//$db = new Vendor\Database();
//$db->where("id=1");
//$db->where("name=1");
//$db->where("id desc");
//$db->limit(10);
//链式操作
$db->where("id=1")->where("name=2")->order("id desc")->limit(10);
复制代码


三、PHP魔术方法的使用


1.常见的魔术方法
  • __get/__set
  • __call/__callStatic
  • __toString
  • __invoke


2.魔术方法的实现

==__get/__set==

  • __set 当对对象不存在的属性进行赋值时会进行调用该方法
  • __get 当读取一个对象不存在的属性时会调用该方法


index.php文件

//$obj = new Vendor\Obj();
//调用对象不存在的属性时
//$obj->title = 'hello';
//echo $obj->title;
复制代码


Vendor/Obj.php文件

protected $array = [];
    //当对对象不存在的属性进行赋值时会进行调用该方法
    function __set($key, $value)
    {
        var_dump(__METHOD__);
        $this->array[$key] = $value;
    }
    //当读取一个对象不存在的属性时会调用该方法
    function __get($key)
    {
        var_dump(__METHOD__);
        return $this->array[$key];
    }
复制代码


==__call/__callStatic==

  • __call 当调用对象中不存在的方法时自动调用
  • __callStatic  当调用对象中不存在的静态方法时自动调用


index.php文件

//调用对象不存在的方法时
//echo $obj->test('hello',123);
//调用对象不存在的静态方法时
//echo $obj::test('hello',123);
复制代码


Vendor/Obj.php文件

//当调用一个不存在的方法是会自动调用
    function __call($name, $arguments)
    {
        // TODO: Implement __call() method.
        var_dump($name,$arguments);
        return "magic function\n";
    }
    //当调用不存在的静态方法时会自动调用
    public static function __callStatic($name, $arguments)
    {
        // TODO: Implement __callStatic() method.
        var_dump($name,$arguments);
        return "magic static function\n";
    }
复制代码


==__toString==

当把对象当成字符串使用时,会自动调用该方法

index.php文件

//将对象转成成字符串,会自动调用该方法
//echo $obj;
复制代码


Vendor/Obj.php文件

//将对象转成成字符串,会自动回调该方法
    public function __toString()
    {
        // TODO: Implement __toString() method.
        //返回一个字符串
        return __CLASS__;
    }
复制代码


==__invoke==

index.php文件

echo $obj('test1');
复制代码


Vendor/Obj.php文件

//把对象当成一个函数去用,会调用该方法
    public function __invoke($params)
    {
        var_dump($params);
        // TODO: Implement __invoke() method.
        return 'invoke';
    }
复制代码


四、三种基础设计模式


一、基础设计模式简介


  • 工厂模式(工厂方法或者类生成对象,而不是代码中直接new)
  • 单例模式(使某个类的对象仅允许创建一个)
  • 注册模式(全局共享和交换对象)


二、[php]工厂模式


1. 概念

工厂模式是我们最常用的实例化对象模式,是用工厂方法代替new操作的一种模式。

2.那么何为工厂模式?

 从名字来看,似乎看不出什么端倪。工厂模式,和生产有关?还是和生产流程有关?难道还和工厂领导有关?和领导秘书有关?秘书...     好了不卖关子了,所谓工厂模式还真和生产有关。生产什么呢?生产出来的是一个实例对象。通过什么设备生产?通过一个工厂类生产。怎么生产呢?工厂类调用自身静态方法来生产对象实例。

 工厂模式有一个关键的构造,根据一般原则命名为Factory的静态方法,然而这只是一种原则,虽然工厂方法可以任意命名这个静态还可以接受任意数据的参数,必须返回一个对象。

3. 为什么要用工厂模式?

很多没接触过工厂模式的人会不禁问,为啥我要费那么大的劲儿去构造工厂类去创建对象呢?不去套用那些易维护,可扩展之类的话,我们可以考虑这样 一个简单的问题。如果项目中,我们通过一个类创建对象。在快完成或者已经完成,要扩展功能的时候,发现原来的类类名不是很合适或者发现类需要添加构造函数 参数才能实现功能扩展。我靠!我都通过这个类创建了一大堆对象实例了啊,难道我还要一个一个去改不成?我们现在才感受到了“高内聚低耦合”的博大精深。没 问题,工厂方法可以解决这个问题。

==如果类名发生变化,或者方法的参数发生变化,需要修改所有引入该类的文件,不易于维护,紧耦合。我们要解决这个问题,所以要使用工厂方法。==

==工厂模式更多的是解决后期拓展(大部分是文件命名修改后)的问题。==

3.工厂模式如何实现?

相对于单例模式,上面我们提供了足够的信息,工厂类,工厂类里面的静态方法。静态方法里面new一下需要创建的对象实例就搞定了。当然至于考虑 上面的第二个问题,根据工厂类静态方法的参数,我们简单做个判断就好了。管你用if..else..还是switch..case..,能快速高效完成判 断该创建哪个类的工作就好了。最后,一定要记得,工厂类静态方法返回一个对象。不是两个,更不是三个。

index.php文件


//工厂模式
//$db = new Vendor\Database();
//$db = Vendor\Factory::createDatabase();
//var_dump($db);
复制代码


Vendor/Factory.php文件

<?php
namespace Vendor;
class Factory
{
    static function createDatabase()
    {
        //统一进行实例化数据库连接
        $db = new Database();
        return $db;
    }
}
复制代码


==总结:工厂模式是其设计模式惯用的基础模式,其它高级的设计模式都是依赖于工厂 模式==


相关文章
|
4月前
|
设计模式 数据库连接 PHP
PHP编程中的面向对象与设计模式
在PHP编程世界中,掌握面向对象编程(OOP)和设计模式是提升代码质量和开发效率的关键。本文将深入浅出地介绍如何在PHP中应用OOP原则和设计模式,以及这些实践如何影响项目架构和维护性。通过实际案例,我们将探索如何利用这些概念来构建更健壮、可扩展的应用程序。
|
3月前
|
设计模式 存储 算法
PHP中的设计模式:策略模式的深入解析与应用在软件开发的浩瀚海洋中,PHP以其独特的魅力和强大的功能吸引了无数开发者。作为一门历史悠久且广泛应用的编程语言,PHP不仅拥有丰富的内置函数和扩展库,还支持面向对象编程(OOP),为开发者提供了灵活而强大的工具集。在PHP的众多特性中,设计模式的应用尤为引人注目,它们如同精雕细琢的宝石,镶嵌在代码的肌理之中,让程序更加优雅、高效且易于维护。今天,我们就来深入探讨PHP中使用频率颇高的一种设计模式——策略模式。
本文旨在深入探讨PHP中的策略模式,从定义到实现,再到应用场景,全面剖析其在PHP编程中的应用价值。策略模式作为一种行为型设计模式,允许在运行时根据不同情况选择不同的算法或行为,极大地提高了代码的灵活性和可维护性。通过实例分析,本文将展示如何在PHP项目中有效利用策略模式来解决实际问题,并提升代码质量。
|
5月前
|
设计模式 并行计算 安全
Java面试题:如何使用设计模式优化多线程环境下的资源管理?Java内存模型与并发工具类的协同工作,描述ForkJoinPool的工作机制,并解释其在并行计算中的优势。如何根据任务特性调整线程池参数
Java面试题:如何使用设计模式优化多线程环境下的资源管理?Java内存模型与并发工具类的协同工作,描述ForkJoinPool的工作机制,并解释其在并行计算中的优势。如何根据任务特性调整线程池参数
52 0
|
7月前
|
设计模式 算法 架构师
【搞懂设计模式】设计模式与面向对象原则
【搞懂设计模式】设计模式与面向对象原则
79 1
|
6月前
|
设计模式 存储 Java
JavaSE——面向对象高级二(2/4)-final关键字、常量、抽象类(认识抽象类、抽象类的好处、应用场景-模板方法设计模式)
JavaSE——面向对象高级二(2/4)-final关键字、常量、抽象类(认识抽象类、抽象类的好处、应用场景-模板方法设计模式)
33 0
|
7月前
|
设计模式 Java 编译器
Java 设计模式最佳实践:一、从面向对象到函数式编程
Java 设计模式最佳实践:一、从面向对象到函数式编程
110 0
|
设计模式 算法 关系型数据库
设计模式——设计模式简介、分类及面向对象设计原则
23 种设计模式中有些模式今天已经不流行了,有些模型已经被语言机制替代了,有些模式你可能常常会忘记,但这些都不重要,重要的是设计原则,因为有了这些设计原则,你有可能发明自己的模式,你也可以理解未来千千万万其他领域的模式。
108 1
|
设计模式 算法 C#
28【WinForm】C#实现商场收银软件,从面向过程到面向对象,设计模式的应用
实现商场收银系统从简单的面向过程到面向对象的演变。
177 0
|
设计模式 SQL 开发框架
【Java设计模式 面向对象设计思想】六 再谈MVC贫血模式与DDD领域驱动开发
【Java设计模式 面向对象设计思想】六 再谈MVC贫血模式与DDD领域驱动开发
321 1
|
设计模式 Java
【Java设计模式 面向对象设计思想】五 多用组合少用继承编程
【Java设计模式 面向对象设计思想】五 多用组合少用继承编程
247 0
【Java设计模式 面向对象设计思想】五 多用组合少用继承编程