PHP 常见的设计模式
设计模式是在特定场景下解决软件设计问题的通用可重用解决方案。在PHP编程中,合理使用设计模式可以帮助开发者创建出更加灵活、可扩展和易于维护的应用程序。本文将介绍几种常见的PHP设计模式,并提供简单易懂的例子来帮助理解这些概念。
一、单例模式
介绍
单例模式是一种确保一个类只有一个实例存在,并提供全局访问点的设计模式。这种模式对于需要频繁实例化然后销毁的对象来说非常有用,比如数据库连接对象。
- 定义一个私有的静态变量用来存储唯一实例。
- 将构造函数设为私有,防止外部通过new关键字直接创建该类的新实例。
- 提供一个公共的静态方法作为获取这个单一实例的全局访问点。
- 在静态方法内检查实例是否已经创建,如果没有,则创建;如果已存在,则返回已有实例。
php深色版本1class Singleton {
2 private static $instance = null;
3
4 private function __construct() {}
5
6 public static function getInstance() {
7 if (self::$instance == null) {
8 self::$instance = new Singleton();
9 }
10 return self::$instance;
11 }
12
13 // 防止克隆实例
14 private function __clone() {}
15
16 // 防止反序列化时重新创建新对象
17 private function __wakeup() {}
18}
二、工厂模式
介绍
工厂模式是一种创建型模式,它提供了创建对象的最佳方式。在工厂模式中,当创建逻辑被封装在子类中且客户端无需知道实际创建的类是哪一个时,可以使用此模式来处理对象的创建过程。
- 定义一个用于创建对象的接口。
- 实现具体的工厂类,根据传入参数决定应该实例化哪个具体的产品类。
- 每个具体产品类都实现同一抽象产品接口或继承自共同基类。
- 客户端代码通过工厂接口请求产品,而不需要关心实际生产的是哪种类型的产品。
php深色版本1interface Product {
2 public function useProduct();
3}
4
5class ConcreteProductA implements Product {
6 public function useProduct() {
7 echo "Using Product A";
8 }
9}
10
11class ConcreteProductB implements Product {
12 public function useProduct() {
13 echo "Using Product B";
14 }
15}
16
17class Factory {
18 public static function createProduct($type) {
19 switch ($type) {
20 case 'A':
21 return new ConcreteProductA();
22 case 'B':
23 return new ConcreteProductB();
24 default:
25 throw new InvalidArgumentException('Invalid product type.');
26 }
27 }
28}
三、观察者模式
介绍
观察者模式定义了对象间的一种一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。这有助于建立松耦合的关系,使得系统更加灵活。
- 定义一个Subject(主题)接口,包含添加、删除以及通知观察者的方法。
- 创建ConcreteSubject类实现Subject接口,并维护一个Observer列表。
- 定义Observer接口,声明update方法,让所有观察者都能接收到来自主题的通知。
- 实现具体的观察者类,它们实现了Observer接口。
- 当主题状态发生变化时,调用notify方法遍历所有注册过的观察者执行其update方法。
php深色版本1interface Observer {
2 public function update($message);
3}
4
5interface Subject {
6 public function attach(Observer $observer);
7 public function detach(Observer $observer);
8 public function notify($message);
9}
10
11class ConcreteSubject implements Subject {
12 private $observers = [];
13
14 public function attach(Observer $observer) {
15 $this->observers[] = $observer;
16 }
17
18 public function detach(Observer $observer) {
19 $this->observers = array_filter($this->observers, function($o) use ($observer) {
20 return !($o === $observer);
21 });
22 }
23
24 public function notify($message) {
25 foreach ($this->observers as $observer) {
26 $observer->update($message);
27 }
28 }
29}
30
31class ConcreteObserver implements Observer {
32 private $name;
33
34 public function __construct($name) {
35 $this->name = $name;
36 }
37
38 public function update($message) {
39 echo "$this->name received: $message\n";
40 }
41}
四、策略模式
介绍
策略模式允许定义一系列算法,并将每个算法封装起来,使它们可以互相替换。策略模式让算法的变化独立于使用算法的客户。
- 定义Strategy接口,其中包含了一个或多个算法方法。
- 创建实现了Strategy接口的具体策略类。
- 定义Context类,用来持有当前使用的策略对象,并提供设置新策略的方法。
- Context类中的业务方法会委托给内部持有的策略对象来执行相应的行为。
- 客户端可以选择不同的策略传递给Context,从而改变其行为。
php深色版本1interface Strategy {
2 public function execute();
3}
4
5class ConcreteStrategyA implements Strategy {
6 public function execute() {
7 echo "Executing strategy A\n";
8 }
9}
10
11class ConcreteStrategyB implements Strategy {
12 public function execute() {
13 echo "Executing strategy B\n";
14 }
15}
16
17class Context {
18 private $strategy;
19
20 public function setStrategy(Strategy $strategy) {
21 $this->strategy = $strategy;
22 }
23
24 public function executeStrategy() {
25 if ($this->strategy !== null) {
26 $this->strategy->execute();
27 } else {
28 throw new Exception("No strategy set.");
29 }
30 }
31}
五、装饰器模式
介绍
装饰器模式允许动态地向一个单独的对象添加新的功能,而不需要修改其结构。这是通过创建一个新的类来包装原有的类来实现的。
- 定义Component接口,规定了基础组件的行为。
- 创建ConcreteComponent类实现Component接口,代表最简单的组件。
- 定义Decorator类也实现Component接口,持有一个Component类型的成员变量,并实现同样的接口方法。
- 创建ConcreteDecorator类继承自Decorator,在执行原有操作的基础上增加额外的功能。
- 客户端可以通过组合多个装饰器来构建具有复杂行为的对象。
php深色版本1interface Component {
2 public function operation();
3}
4
5class ConcreteComponent implements Component {
6 public function operation() {
7 echo "Doing something in ConcreteComponent.\n";
8 }
9}
10
11abstract class Decorator implements Component {
12 protected $component;
13
14 public function __construct(Component $component) {
15 $this->component = $component;
16 }
17
18 abstract public function operation();
19}
20
21class ConcreteDecoratorA extends Decorator {
22 public function operation() {
23 echo "Adding functionality by ConcreteDecoratorA before.\n";
24 $this->component->operation();
25 echo "Adding functionality by ConcreteDecoratorA after.\n";
26 }
27}
28
29class ConcreteDecoratorB extends Decorator {
30 public function operation() {
31 echo "Adding functionality by ConcreteDecoratorB before.\n";
32 $this->component->operation();
33 echo "Adding functionality by ConcreteDecoratorB after.\n";
34 }
35}
六、适配器模式
介绍
适配器模式的作用是将一个类的接口转换为客户期望的另一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以协同工作。
- 确定目标接口(Target),即客户端所期待的服务接口。
- 识别需要适配的Adaptee类,它包含了有用的功能但是接口与Target不匹配。
- 创建Adapter类,实现Target接口,并且拥有一个Adaptee类型的成员变量。
- Adapter类转发请求给内部的Adaptee对象,同时可能对请求进行一些调整以符合Target的要求。
- 客户端代码只需要按照Target接口的方式来调用,而不用关心背后的实际实现细节。
php深色版本1interface Target {
2 public function request();
3}
4
5class Adaptee {
6 public function specificRequest() {
7 echo "Specific request from Adaptee.";
8 }
9}
10
11class Adapter implements Target {
12 private $adaptee;
13
14 public function __construct(Adaptee $adaptee) {
15 $this->adaptee = $adaptee;
16 }
17
18 public function request() {
19 $this->adaptee->specificRequest();
20 }
21}
以上就是关于PHP中几种常见设计模式的简要介绍及示例。正确地理解和应用这些模式能够极大地提高程序的质量和开发效率。希望本教程能对你有所帮助!