Modèles de conception utilisés dans Laravel : mode usine, mode singleton, mode arbre d'enregistrement, mode adaptateur, mode stratégie, mode de mappage d'objets de données, mode observateur, mode prototype, mode décorateur, mode itérateur, mode proxy, etc.
L'environnement d'exploitation de ce tutoriel : système Windows 7, version Laravel 6, ordinateur Dell G3.
Cet article vous présente certains modèles de conception couramment utilisés dans Laravel. Vous les utilisez, mais vous ne les connaissez peut-être pas. . .
1 : Modèle d'usine
Par exemple : Auth::user()
Auth::user()
此处Auth
这个类就是工厂中的方法,Auth
是注册树中的别名。
好处:
类似于函数的封装,使对象有一个统一的生成(实例化)入口。当我们对象所对应的类的类名发生变化的时候,我们只需要改一下工厂类类里面的实例化方法即可。
2:单例模式
好处:
对象不可外部实例化并且只能实例化一次,节省资源。
实现方式:
private static $ins = null; //设置私有的属性 private function __construct() {} //使外部无法new这个类 public static function getIns() { //暴露给外部的调用方法 if(self::$ins instanceof self) { return self::$ins; } else { self::$ins = new self(); return self::$ins; } }
声明一个类的私有或者保护的静态变量,构造方法声明为私有(不允许外部进行new操作),如果不存在则实例化它,然后返回,如果存在则直接返回。
3:注册树模式
使用:
config/app
里的aliases
数组便是一个注册树
好处:
注册树模式就是使用数组结构来存取对象,工厂方法只需要调用一次(可以放到系统环境初始化这样的地方),以后需要调用该对象的时候直接从注册树上面取出来即可,不需要再调用工厂方法和单例模式。
实现方法:
class Register { protected static $objects function set($alias,$object) { //将对象映射到全局树上 self::$objects[$alias]=$object; } static function get($name) { //获取对象 return self::$objects[$name]; } function _unset($alias) { //从全局树移除对象 unset(self::$onjects[$alias]); } }
$alias
表示别名,自己设定
在工厂模式中添加
Register::set(‘db1’,$db);
其他任何地方调用只需要调用注册器读取即可
Register::$objects[‘db1’];
4:适配器模式
将不同工具的不同函数接口封装成统一的API,方便调用。如:mysql
,mysqli
,PDO
。
实现:在接口类里面申明统一的方法体,再让不同的类去实现这个接口,和重写其抽象方法。
interface Database { function connect($host,$user,$password,$dbname); function query($sql); function close(); }
然后再去用不同的工具函数去实现相同的接口。
5:策略模式
好处:
将一组特定的行为和算法封装成类,以适应某些特定的上下文环境,将逻辑判断和具体实现分离,实现了硬编码到解耦,并可实现IOC、依赖倒置、反转控制。
实现:
1.定义一个策略接口文件(UserStrategy.php
),定义策略接口,声明策略
2.定义具体类(FemaleUserStrategy.php
,MaleUserStrategy.php
),实现策略接口,重写策略方法
class Page { protected $strategy; function index() { if($request->get('female')) { $strategy=new FemaleUserStrategy(); } else { $strategy=new MaleUserStrategy(); } $this->strategy->method(); } public function __construct(UserStrategy $strategy) { $this->strategy=$strategy; } }
6:数据对象映射模式
好处:将对象和数据存储映射起来,对一个对象的操作会映射为对数据存储的操作,这也是ORM的实现机制。
class Model { public $id; public $name; public $email; …… function __construct($id) { //构造函数,调用class时自动执行,用来初始化。 //查询逻辑 } function __destruct() { //析构函数,当class调用完成后自动执行,用它来销毁实例,释放资源。 //增删改逻辑 } }
7:观察者模式
使用:
触发类Event
<?php namespace App\Events; abstract class Event { //逻辑代码 }
监听类EventListener
Auth
cette classe est la méthode dans l'usine, Auth
est un alias dans l'arborescence d'enregistrement.
Avantages :
Semblable à la fonction d'encapsulation, elle permet aux objets d'avoir une entrée de génération (instanciation) unifiée. Lorsque le nom de la classe correspondant à notre objet change, il suffit de changer la méthode d'instanciation dans la classe usine.
2 : Mode SingletonAvantages :
Les objets ne peuvent pas être instanciés en externe et ne peuvent être instanciés qu'une seule fois, économisant ainsi des ressources. Méthode d'implémentation :<?php namespace App\Listeners; use App\Events\SomeEvent; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Contracts\Queue\ShouldQueue; class EventListener { /** * Create the event listener. * * @return void */ public function __construct() { // } /** * Handle the event. * * @param SomeEvent $event * @return void */ public function handle(SomeEvent $event) { // } }Déclarez une variable statique privée ou protégée d'une classe, déclarez le constructeur comme privé (les nouvelles opérations externes ne sont pas autorisées), si elle n'existe pas, instanciez-la, puis retournez, si elle existe, revenir directement. 🎜🎜🎜🎜3 : Mode arbre d'enregistrement 🎜🎜🎜🎜🎜Utilisation : 🎜🎜🎜 Le tableau
alias
dans config/app
est un arbre d'enregistrement🎜🎜🎜Avantages : 🎜 🎜🎜Le mode arbre d'enregistrement utilise une structure de tableau pour accéder aux objets. La méthode factory ne doit être appelée qu'une seule fois (elle peut être placée dans un endroit tel que l'initialisation de l'environnement système). peut être extrait directement de l'arborescence d'enregistrement. Il n'est pas nécessaire d'appeler des méthodes d'usine et des modèles singleton. 🎜🎜🎜Méthode d'implémentation : 🎜🎜$Object = new Object(); $object_1 = clone $Object; $object_2 = clone $Object;🎜
$alias
représente l'alias, définissez-le vous-même 🎜🎜Ajouter en mode usine 🎜🎜Register::set('db1',$db);
🎜🎜Tout autre appel de lieu n'a besoin que d'appeler le registre pour lire🎜🎜Register::$objects['db1'];
🎜🎜🎜🎜4 : Mode adaptateur🎜🎜🎜 🎜 Encapsulez différentes interfaces de fonctions de différents outils dans une API unifiée pour faciliter les appels. Tels que : mysql
, mysqli
, PDO
. 🎜🎜Implémentation : déclarez un corps de méthode unifié dans la classe d'interface, puis laissez différentes classes implémenter cette interface et réécrire ses méthodes abstraites. 🎜class Method2 extends Method { function doSomething() { echo "<div style='color:red'>" parent::doSomething(); echo "</div>"; } } interfa Decorator { //定义装饰器接口 function beforeAction(); function afterAction(); //more decoratorMethod…… } class SomeClass { protected $decorators = []; function addDecorator(Decorator $decorator) { $this->decorators[] = $decorator; } function beforeMethod() { foreach ($this->decorators as $row) { $row->beforeAction(); } } function afterMethod() { $decorators = array_reverse($this->decorators); //做一个反转 foreach ($this->decorators as $row) { $row->afterAction(); } } function action() { $this->beforeMethod(); //method; $this->afterMethod(); } } class OneDecorator implements Decorator { protected $datas; function __construct($datas = 'request') { $this->datas = $datas; } function beforeAction() { echo "<div style='color:{$this->datas};'>"; } function afterAction() { echo "</div>"; } } $Object = new \SomeClass(); $Object->addDecorator(new \OneDecorator('blue')); //Add other decorator... $Object->action();🎜Utilisez ensuite différentes fonctions d'outils pour implémenter la même interface. 🎜🎜🎜🎜5 : Modèle de stratégie 🎜🎜🎜🎜Avantages : 🎜🎜Encapsuler un ensemble spécifique de comportements et d'algorithmes dans des classes pour s'adapter à certains contextes spécifiques, séparer les jugements logiques des implémentations spécifiques et implémenter le codage en dur dans le découplage et activer l'IOC , l'inversion des dépendances et le contrôle de l'inversion. 🎜🎜Mise en œuvre :🎜🎜1. Définissez un fichier d'interface de stratégie (
UserStrategy.php
), définissez l'interface de stratégie et déclarez la stratégie🎜🎜2. Définissez une classe spécifique (FemaleUserStrategy.php).
, MaleUserStrategy.php
), implémente l'interface de stratégie et remplace la méthode de stratégie🎜Object::all() Iterator extends Traversable { //PHP内置迭代器接口 /* 方法 */ abstract public mixed current (void) abstract public scalar key (void) abstract public void next (void) abstract public void rewind (void) abstract public boolean valid (void) } class ObjectAll implements \Iterator { protected $ids; //所有对象的id protected $index; //迭代器的当前位置 protected $data = array(); //保存从数据库取到的所有对象 function __construct() { //取出所有的id,$ids } function current() { //获取当前的元素的数据,第三个调用 $id = $this->ids[$this->index]['id']; return Object::find($id); } function next() { //获取下一个元素,第四个调用 $this->index ++; } function valid() { //验证当前元素是否还有下一个元素(查询当前是否有数据),第二个调用 return $this->index < count($this->$ids); } function rewind() { //当迭代器执行到末尾时,重置迭代器到整个集合的开头,最先调用 $this->index = 0; } function key() { //获取当前的索引,最后调用 return $this->index; } } $objects = new \ObjectAll(); foreach ($objects as $row) { dump($row->field); //增删改查操作 }🎜🎜🎜6 : Mode de mappage d'objets de données🎜🎜🎜🎜Avantages : Cartographie d'objets et de stockage de données, cartographie Les opérations d'un objet sont mappées aux opérations sur le stockage de données, qui est également le mécanisme de mise en œuvre d'ORM. 🎜
interface DBproxy { function getInfo($id); function setInfo($id, $value); } class Proxy implements DBproxy { function get() { //DB::('slave'); query } function set() { //DB::('master'); query } } $proxy = new Proxy(); $proxy->get($id); $proxy->set($id, $value);🎜🎜🎜7 : Mode observateur 🎜🎜🎜🎜Utilisation : 🎜🎜Classe de déclenchement
Event
🎜rrreee🎜Classe d'écoute EventListener
🎜rrreee🎜Avantages : 🎜🎜Be a When l'état d'un objet change, tous les objets qui en dépendent recevront des notifications et se mettront automatiquement à jour, obtenant ainsi un mécanisme de notification et de mise à jour à faible couplage et non intrusif. 🎜🎜🎜🎜8 : Le mode prototype 🎜🎜🎜🎜 est similaire au mode usine et est utilisé pour créer des objets. La différence est que le mode prototype crée d'abord un objet prototype puis crée un nouvel objet en clonant l'objet prototype. le mode prototype convient à La création d'objets volumineux ne nécessite qu'une copie en mémoire. 🎜rrreee🎜🎜🎜9 : Decorator Pattern 🎜🎜🎜🎜 Pour modifier ou ajouter la fonctionnalité d'une classe, la manière traditionnelle est d'écrire une sous-classe pour en hériter et réimplémenter les méthodes de la classe. Le modèle décorateur n'a besoin que d'ajouter un objet décorateur au moment de l'exécution pour ajouter ou modifier dynamiquement les fonctionnalités d'une classe. 🎜🎜Méthode traditionnelle :🎜class Method2 extends Method { function doSomething() { echo "<div style='color:red'>" parent::doSomething(); echo "</div>"; } } interfa Decorator { //定义装饰器接口 function beforeAction(); function afterAction(); //more decoratorMethod…… } class SomeClass { protected $decorators = []; function addDecorator(Decorator $decorator) { $this->decorators[] = $decorator; } function beforeMethod() { foreach ($this->decorators as $row) { $row->beforeAction(); } } function afterMethod() { $decorators = array_reverse($this->decorators); //做一个反转 foreach ($this->decorators as $row) { $row->afterAction(); } } function action() { $this->beforeMethod(); //method; $this->afterMethod(); } } class OneDecorator implements Decorator { protected $datas; function __construct($datas = 'request') { $this->datas = $datas; } function beforeAction() { echo "<div style='color:{$this->datas};'>"; } function afterAction() { echo "</div>"; } } $Object = new \SomeClass(); $Object->addDecorator(new \OneDecorator('blue')); //Add other decorator... $Object->action();
10:迭代器模式
在不需要了解内部实现的前提下,遍历一个聚合对象的内部元素,相对于传统编程方式它可以遍历元素所需的操作。
例如:
Object::all() Iterator extends Traversable { //PHP内置迭代器接口 /* 方法 */ abstract public mixed current (void) abstract public scalar key (void) abstract public void next (void) abstract public void rewind (void) abstract public boolean valid (void) } class ObjectAll implements \Iterator { protected $ids; //所有对象的id protected $index; //迭代器的当前位置 protected $data = array(); //保存从数据库取到的所有对象 function __construct() { //取出所有的id,$ids } function current() { //获取当前的元素的数据,第三个调用 $id = $this->ids[$this->index]['id']; return Object::find($id); } function next() { //获取下一个元素,第四个调用 $this->index ++; } function valid() { //验证当前元素是否还有下一个元素(查询当前是否有数据),第二个调用 return $this->index < count($this->$ids); } function rewind() { //当迭代器执行到末尾时,重置迭代器到整个集合的开头,最先调用 $this->index = 0; } function key() { //获取当前的索引,最后调用 return $this->index; } } $objects = new \ObjectAll(); foreach ($objects as $row) { dump($row->field); //增删改查操作 }
11:代理模式
在客户端与实体之间建立一个代理对象,客户端对实体进行操作全部委派给代理对象,隐藏实体的具体实现细节(slave
读库与master
写库分离)。代理对象还可以与业务代码分离,部署到另外的服务器,业务代码中通过PRC
来委派任务。
interface DBproxy { function getInfo($id); function setInfo($id, $value); } class Proxy implements DBproxy { function get() { //DB::('slave'); query } function set() { //DB::('master'); query } } $proxy = new Proxy(); $proxy->get($id); $proxy->set($id, $value);
相关推荐:最新的五个Laravel视频教程
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!