框架篇:9.设计模式
PHP DIY系列–一起手写一个api框架
框架的开发基本结束了,这一节我们来探讨一下设计模式。
谈设计模式,首先要来简单聊聊面向对象。
面向对象
面向对象程序设计(Object-Oriented Programming, OOP)是一种程序设计范型,同时也是一种程序开发方法。它将对象作为程序的基本单元,将程序和数据封装其中,以提高软件的重用性、灵活性和可扩展性。它和面向过程、函数式编程被称为编程语言中的三大范式。
概念知识
- 面向对象的核心思想是对象、封装、可重用性、可扩展性。
- 面向对象三要素:封装、继承和多态。
- 面向对象设计的五大原则:单一职责原则、接口隔离原则、开放封闭原则、替换原则、依赖倒置原则。
关于这些概念的更详细解释,我推荐大家阅读《PHP核心技术与最佳实践》这本书关于关于面向对象的部分。
设计模式
上述所述的面向对象知识,尤其是面向对象设计的五大原则,是诸多设计模式的基础。
设计模式有很多,我们可以简单列出来:
- 有强调实例化过程的创建型设计模式
- 抽象工厂
- 生成器
- 工厂方法
- 原型
- 单例
- 又有组合对象和类构成更大结构的结构型设计模式
- 适配器模式
- 桥接模式
- 组合模式
- 装饰器模式
- 外观模式
- 享元模式
- 代理模式
- 还有行为型设计模式
- 职责链模式
- 命令模式
- 解释器模式
- 迭代器模式
- 中介者模式
- 备忘录模式
- 观察者模式
- 状态模式
- 策略模式
- 模板授权模式
- 访问者模式
说到这里你有没有蒙圈?
其实我们无需一下子去了解那么多设计模式,在实际开发过程中我们可能也是混合使用设计模式的。我们不妨可以就框架里用到的几个典型的设计模式做一些分析。
单例模式
是否还记得我们使用Redis代替Session那一节,我们就用到了单例模式。
我们来简化一下代码:
class RedisSession
{
private $Redis;
private function getRedisInstance()
{
if (empty($this->Redis)) {
$Redis = new \Redis();
$Redis->connect($this->_config['host'], $this->_config['port'], $this->_config['timeout']);
if (!$this->_config['auth']) {
$Redis->auth($this->_config['auth']);
}
$this->Redis = $Redis;
}
return $this->Redis;
}
}
一般我们还会在类里面加入一个魔术方法__clone,防止实例创建后被clone
单例模式有显而易见的优点:提高可重用性,减少开销。框架里使用Redis时都可以使用此方法来获取Redis,也减少Redis的连接数和多次连接时间。
策略模式
还记得依赖注入那一节么,我们举例的那个Travel就是一个很好的策略模式Demo:
interface Travel
{
public function travelAlgorithm();
}
/**
*具体策略类(ConcreteStrategy)
*1:乘坐飞机
*/
class AirPlanelStrategy implements Travel
{
public function travelAlgorithm()
{
echo"travelbyAirPlain\r\n";
}
}
/**
*具体策略类(ConcreteStrategy)
*2:乘坐火车
*/
class TrainStrategy implements Travel
{
public function travelAlgorithm()
{
echo"travelbyTrain\r\n";
}
}
/**
*
*环境类(Context):
*用一个ConcreteStrategy对象来配置。
*维护一个对Travel对象的引用。可定义一个接口来让Strategy访问它的数据。
*算法解决类,以提供客户选择使用何种解决方案:
*/
class PersonContext
{
private $strategy = null;
public function __construct(Travel $travel)
{
$this->strategy=$travel;
}
/**
*旅行
*/
public function travel()
{
return$this->strategy->travelAlgorithm();
}
}
// 乘坐火车旅行
$person = new PersonContext(new TrainStrategy());
$person->travel();
// 改乘飞机
$person =PersonContext(new AirPlanelStrategy());
$person->travel();
策略模式降低了代码耦合度,可以使得我们下层代码依赖上层,替换下层代码即可简单实现功能的替换。
工厂方法
我们在路由解析创建控制器那里使用了工厂方法,只不过与路由解析代码糅合在一起,我们简化一下:
class Factory
{
public function createController($controllerName)
{
$controllerName = rtrim($controllerName,'\\').'Controller';
if (!class_exists($controllerName)) {
throw new NotFoundException("未找到控制器");
}
return new $controllerName;
}
···
}
工厂方法是很常见的一种设计模式,像Model经常能用到。
框架篇:9.设计模式
https://blog.puresai.com/2020/02/16/phpframe12/