引言
PHP介绍
PHP是用C语言开发出来的一种语言,C语言是真正意义上跨平台的语言,这也注定PHP是跨平台的,PHP是可运行在Windows Server或Linux操作系统的服务器上的语言,它和Java以及C#一样,代码存储并运行在服务器端,它将浏览器端可执行的HTML以及脚本发送给浏览器执行,PHP相对Java和C#对于面向过程的封装更多,减少部分数据类型的支持。
设计模式的定义
设计模式(Design Pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。设计模式于己于他人于系统都是多赢的;设计模式使代码编制真正工程化;设计模式是软件工程的基石脉络,如同大厦的结构一样。
项目中合理的运用设计模式可以完美的解决很多问题,每种模式在现在中都有相应的原理来与之对应,每一个模式描述了一个在我们周围不断重复发生的问题,以及该问题的核心解决方案,这也是它能被广泛应用的原因
常见的面向对象设计模式大约有23种。
设计模式的优点
- 复用解决方案。设计模式本身就是对某一类问题的通用解决方案,是更高级别的复用,已经超出了代码复用.
- 确定通用术语。开发中的交流和协作都需要共同的词汇其础和对问题的共识. 当你有想表达却又表达不清楚的设计思路,即使表达出来也会被同事误解的时候,设计模式就显出沟通的优势了。
- 代码更易于修改与维护。因为设计模式都是久经考验的解决方案,它们的结构都是经过长期的发展形成的,善于应对变化,设计模式本身也是对变化点的封装。
- 模式有助于提高思考层次。学习模式后,就算不用模式中的方法,也会更好的采取更好的策略去解决问题。
参考:PHP设计模式——概述
UML
统一建模语言(Unified Modeling Language,UML),应当是编程工具库中的主要组成部分。是对操作、对象和用例进行图形编程的标准方式。
UML类图是一种结构图,用于描述一个系统的静态结构。类图以反映类结构和类之间关系为目的,用以描述软件系统的结构,是一种静态建模方法。类图中的类,与面向对象语言中的类的概念是对应的。
在UML类图中,常见的有以下几种关系:
- 继承/泛化(Generalization):用于描述父类与子类之间的关系。父类又称作基类,子类又称作派生类。通过
extends
实现,如:class Bus extends Car
- 实现(Realization),主要用来规定接口和实现类的关系。通过
implements
实现,如:class Car implements Vehicle
- 关联(Association)
- 聚合(Aggregation)
- 组合(Composition)
- 依赖(Dependency)
这六种类关系中,组合、聚合和关联的代码结构一样,可以从关系的强弱来理解,各类关系从强到弱依次是:继承→实现→组合→聚合→关联→依赖。(目前自己的理解)除了继承和实现,其他类关系较弱,一般是通过在一个类中调用其他类来实现。
参考:
- UML类图详解
- 详解UML图之类图
设计模式的六大原则
这六大原则任何面向对象的语言都应该遵守的,六大原则让代码具有易扩展性和高复用性。代码不一定严格按照某种设计模式,代码应符合这六大原则。
单一职责
定义:不要存在多于一个导致类变更的原因。通俗的说,即一个类只负责一项职责
问题:类T负责两个不同的职责:职责P1,职责P2。当由于职责P1需求发生改变而需要修改类T时,有可能会导致原本运行正常的职责P2功能发生故障,关系如下图:
改进:遵循单一职责原则。分别建立两个类T1、T2,使T1完成职责P1功能,T2完成职责P2功能。这样,当修改类T1时,不会使职责P2发生故障风险;同理,当修改T2时,也不会使职责P1发生故障风险。
遵循单一职责原的优点有:
- 可以降低类的复杂度,一个类只负责一项职责,逻辑简单;
- 提高类的可读性,提高系统的可维护性;
- 变更引起的风险降低,变更是必然的。
里氏代换原则
- 定义:所有引用基类的地方必须能透明地使用其子类的对象,也就是说子类可以扩展父类的功能,但不能改变父类原有的功能子类可以扩展父类的功能,但不能改变父类原有的功能。
依赖倒置原则
定义:
高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该依赖细节;细节应该依赖抽象。
此处理解起来是最困难的,一般会在项目框架的搭建的时候用到,例如,业务逻辑层相对于数据层是高层模块,因为业务逻辑层需要调用数据层去连接数据库,但是要做到可扩展高复用,尽量不要让业务逻辑层依赖数据层,可以在数据层抽象出一个接口,让业务逻辑层依赖于这个抽象接口。
优点:
- 低层模块尽量都要有抽象类或接口,或者两者都有。
- 变量的声明类型尽量是抽象类或接口。
- 使用继承时遵循里氏替换原则。
接口隔离原则
定义:客户端不应该依赖它不需要的接口;一个类对另一个类的依赖应该建立在最小的接口上。
注意点:
- 接口尽量小,但是要有限度。对接口进行细化可以提高程序设计灵活性 是不挣的事实,但是如果过小,则会造成接口数量过多,使设计复杂化。所以一定要适度。
- 为依赖接口的类定制服务,只暴露给调用的类它需要的方法,它不需要的方法则隐藏起来。只有专注地为一个模块提供定制服务,才能建立最小的依赖关系。
- 提高内聚,减少对外交互。使接口用最少的方法去完成最多的事情。
迪米特法则
定义: 一个对象应该对其他对象保持最少的了解。
问题:类与类之间的关系越密切,耦合度越大,当一个类发生改变时,对另一个类的影响也越大。简单的理解就是高内聚,一个类尽量减少对其他对象的依赖,并且这个类的方法和属性能用私有的就尽量私有化。
注意:
- 只与直接的朋友通信,不要和陌生人说话。
- 过分的使用该原则,将导致系统复杂度变大。所以在采用迪米特法则时要反复权衡,既做到结构清晰,又要高内聚低耦合。
开闭原则
- 定义:一个软件实体如类、模块和函数应该对扩展开放,对修改关闭。
当软件需求变化时,尽量通过扩展软件实体的行为来实现变化,而不是通过修改已有的代码来实现变化。
总结
- 用抽象构建框架,用实现扩展细节
- 抽象合理(需求变更 前瞻性和预见性),派生实现类
- 单一职责原则告诉我们实现类要职责单一;
- 里氏替换原则告诉我们不要破坏继承体系;
- 依赖倒置原则告诉我们要面向接口编程;
- 接口隔离原则告诉我们在设计接口的时候要精简单一;
- 迪米特法则告诉我们要降低耦合。
- 而开闭原则是总纲,他告诉我们要对扩展开放,对修改关闭。
使用现有工具创建和复制设计模式
PHP架构的目标
PEAR
PHP扩展与应用库(PHP Extension and Application Repository)
PEAR所起的作用可能稍落后于其他架构,不过PEAR仍然具有某些优秀的功能和以设计模式为中心的体系结构示例。
- PEAR Mail——如1.2.0b1版本中,Mail.php的第49行左右包含工厂类的一个实例;以及前发送和后发送的处理程序的观察者设计模式。
- PEAR MDB2 数据库抽象层——如2.5.0b2版本中,,存在工厂模式(mdb2.php的第377行左右)、单例模式(mdb2.php的第484行左右)和迭代器设计模式(iterator.php的第54行左右)。
Zend Framework
Zend Framework(简写ZF)是由 Zend 公司支持开发的完全基于 PHP5 的开源PHP开发框架,可用于开发 Web 程序和服务,ZF采用 MVC(Model–View-Controller) 架构模式来分离应用程序中不同的部分方便程序的开发和维护。
Doctrine
Doctrine是用于PHP的对象关系映射器(Object Relational Mapping,ORM),它可以通过PHP对象轻松访问所有的数据库,例如MYSQL。这个面向对象的库为为数据库抽象层提供一个接口。
设计模式
一般将面向对象设计模式分为三类:创建型、结构型、行为型三种。
创建型(5种)
创建对象时,不再由我们直接实例化对象;而是根据特定场景,由程序来确定创建对象的方式,从而保证更大的性能、更好的架构优势。
创建型模式主要有:
- 单例模式(常用)
- 工厂模式:简单工厂模式、工厂方法模式、抽象工厂模式(常用)(注:简单工厂模式不属于23种设计模式)
- 生成器模式
- 原型模式
结构型(7种)
用于帮助将多个对象组织成更大的结构。
结构型模式主要有:
- 适配器模式(常用)
- 装饰器模式
- 代理模式
- 门面模式(外观模式)
- 桥接模式
- 组合模式
- 亨元模式
行为型(11种)
用于帮助系统间各对象的通信,以及如何控制复杂系统中流程。
行为型模式主要有:
- 策略模式(常用)
- 观察者模式(常用)
- 模板模式
- 迭代器模式
- 职责链模式
- 命令模式
- 备忘录模式
- 状态模式
- 访问者模式
- 中介者模式
- 解释器模式
除此之外,还看到过 注册者模式
> 自己将注册者模式归类到结构型设计模式中,不确定是否正确。
参考:
- PHP设计模式(对于设计模式介绍的比较全面)
- 《PHP设计模式》 梁志敏 (偏实例讲解,理论概括较少)
- 《大话设计模式》 程杰
- 设计模式培训.pdf
- 23种设计模式全解析