Maison  >  Article  >  développement back-end  >  Plusieurs modèles de développement courants en PHP

Plusieurs modèles de développement courants en PHP

WBOY
WBOYavant
2023-01-03 14:20:544387parcourir

Cet article vous apporte des connaissances pertinentes sur PHP, qui présentent principalement plusieurs modèles de développement courants. Examinons-les ensemble. J'espère qu'il sera utile à tout le monde.

Plusieurs modèles de développement courants en PHP

Six principes des modèles de conception

Principe ouvert et fermé : une entité logicielle telle qu'une classe, un module et une fonction doit être ouverte à l'extension et fermée à la modification.

Principe de substitution de Richter : tous les endroits qui font référence à une classe de base doivent pouvoir utiliser de manière transparente les objets de ses sous-classes.

Principe d'inversion de dépendance : les modules de haut niveau ne doivent pas dépendre de modules de bas niveau, les deux doivent s'appuyer sur leurs abstractions ; les abstractions ne doivent pas dépendre des détails ; les détails doivent reposer sur des abstractions.

Principe de responsabilité unique : ne pas avoir plus d'une raison pour changer de classe. En termes simples, une classe n'est responsable que d'une seule responsabilité.

Principe d'isolation des interfaces : le client ne doit pas s'appuyer sur des interfaces dont il n'a pas besoin ; la dépendance d'une classe à l'égard d'une autre classe doit être basée sur la plus petite interface.

Loi de Déméter : Un objet doit garder le moins de connaissances sur les autres objets.

1. Mode Singleton :

Caractéristiques : En utilisant le mode singleton, vous pouvez éviter un grand nombre de ressources consommées par de nouvelles opérations

Une classe singleton ne peut pas être directement instanciée et créée, mais ne peut être instanciée que par la classe. lui-même. Par conséquent, pour obtenir un tel effet restrictif, le constructeur doit être marqué comme privé, empêchant ainsi l'instanciation de la classe.

Vous avez besoin d'une variable membre statique privée pour enregistrer l'instance de classe et exposer une méthode statique publique qui peut accéder à l'instance.

En PHP, afin d'empêcher d'autres personnes de cloner des instances de classe singleton, une méthode privée __clone() vide est généralement fournie à cet effet.

  • $_instance doit être déclaré comme variable privée statique

  • Le constructeur et le destructeur doivent être déclarés comme privés pour empêcher les programmes externes de créer de nouvelles classes et ainsi perdre le sens du mode singleton

  • getInstance( ) doit être définie Pour le public, cette méthode doit être appelée pour renvoyer une référence à l'instance

  •  : : L'opérateur ne peut accéder qu'aux variables statiques et aux fonctions statiques

  • les nouveaux objets consommeront de la mémoire

  • Utilisation scénarios : les endroits les plus couramment utilisés Il s'agit d'une connexion à une base de données.

  • Après avoir utilisé le modèle singleton pour générer un objet, l'objet peut être utilisé par de nombreux autres objets.

  • La méthode privée __clone() empêche le clonage d'objets

<?php

class Singleton{

//私有属性,用于保存实例

private static $instance;

//构造方法私有化,防止外部创建实例

private function __construct(){}//公有方法,用于获取实例
public static function getInstance(){
    //判断实例有无创建,没有的话创建实例并返回,有的话直接返回
    if(!(self::$instance instanceof self)){
        self::$instance = new self();
    }
    return self::$instance;
}
//克隆方法私有化,防止复制实例
private function __clone(){}}

2. Mode usine

Le mode usine, les méthodes ou classes d'usine génèrent des objets au lieu de nouveaux directement dans le code.

Utilisez la méthode new pour instancier une classe. Chaque fois que vous l'instancier, il vous suffit d'appeler la méthode dans la classe d'usine pour l'instancier.

Avantages : Puisqu'une classe peut être instanciée à de nombreux endroits. Lorsque le nom de la classe ou les paramètres changent, le modèle d'usine peut être facilement et rapidement modifié une fois dans la méthode sous la classe d'usine, évitant ainsi d'avoir à modifier les objets instanciés un par un

Test1.php

<?php

class Test1

{

static function test()

{

echo FILE;

}

}Factory.php

<?php

class Factory

{

/**

*如果某个类在很多的文件中都new ClassName(),那么万一这个类的名字

*发生变更或者参数发生变化,如果不使用工厂模式,就需要修改每一个PHP

*代码,使用了工厂模式之后,只需要修改工厂类或者方法就可以了。

*/

static function createDatabase()

{

$test = new Test1();

return $test;

}

}

Test.php

<?php

spl_autoload_register(&#39;autoload1&#39;);

$test = Factory::createDatabase();

$test->test();function autoload1($class)
{
    $dir = __DIR__; 
    $requireFile = $dir."\".$class.".php"; 
    require $requireFile; 
}}
Test1.php

<?php

class Test1

{

protected static tt)

{

echo "对象已经创建<br>";

return self::tt = new Test1();

echo "创建对象<br>";

return self::$tt;

}

}function echoHello()
{
    echo "Hello<br>"; 
}}
Test.php

<?php

spl_autoload_register(&#39;autoload1&#39;);

$test = Test1::getInstance();

$test->echoHello();

$test = Test1::getInstance();

$test->echoHello();

$test = Test1::getInstance();

$test->echoHello();

$test = Test1::getInstance();

$test->echoHello();function autoload1($class)
{ 
    $dir = __DIR__; 
    $requireFile = $dir."\".$class.".php"; 
    require $requireFile; 
}}

Par exemple, supposons des rectangles et les cercles ont la même méthode, donc lorsque nous utilisons l'API fournie par la classe de base pour créer une instance, nous pouvons créer automatiquement une instance de la classe correspondante en passant des paramètres. Ils ont tous pour fonction d'obtenir le périmètre et la surface

<?php

interface InterfaceShape

{

function getArea();

function getCircumference();

}/**
• 矩形

*/

class Rectangle implements InterfaceShape

{

private $width;

private $height;
public function __construct($width, $height)

{

$this->width = $width;

$this->height = $height;

}
public function getArea()

{

return $this->width* $this->height;

}
public function getCircumference()

{

return 2 * $this->width + 2 * $this->height;

}

}/**
• 圆形

*/

class Circle implements InterfaceShape

{

private $radius;
function __construct($radius)

{

$this->radius = $radius;

}
public function getArea()

{

return M_PI * pow($this->radius, 2);

}
public function getCircumference()

{

return 2 * M_PI * $this->radius;

}

}/**
• 形状工厂类

*/

class FactoryShape

{

public static function create()

{

switch (func_num_args()) {

case1:

return newCircle(func_get_arg(0));

case2:

return newRectangle(func_get_arg(0), func_get_arg(1));

default:

# code...

break;

}

}

}rect);

echo "<br>";// object(Circle)#2 (1) { ["radius":"Circle":private]=> int(4) }
circle);
.

3. Mode d'enregistrement

Le mode d'enregistrement résout le partage et l'échange global d'objets. L'objet créé est accroché à un tableau utilisable globalement. Si nécessaire, il peut être obtenu directement à partir du tableau. Enregistrez l'objet dans l'arborescence globale. Allez directement visiter n'importe où.

<?php

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::$objects[$alias]);//移除某个注册到树上的对象。
}}

4. Modèle de stratégie

Le modèle de stratégie encapsule un ensemble spécifique de comportements et d'algorithmes dans des classes pour s'adapter à certains contextes spécifiques.
Par exemple : s'il existe un système de site Web de commerce électronique, les utilisateurs masculins et féminins doivent accéder à différentes catégories de produits, et tous les espaces publicitaires affichent des publicités différentes. Dans les codes traditionnels, divers jugements if else sont ajoutés au système de manière codée en dur. Si un jour un utilisateur est ajouté, le code devra être réécrit. En utilisant le mode politique, si vous ajoutez un nouveau type d’utilisateur, il vous suffit d’ajouter une politique. Tout le reste nécessite simplement une stratégie différente.
Déclarez d'abord le fichier d'interface de la stratégie et stipulez le comportement inclus de la stratégie. Ensuite, définissez chaque classe de mise en œuvre de stratégie spécifique.
UserStrategy.php

<?php

/*• 声明策略文件的接口,约定策略包含的行为

*/interface UserStrategy {

function showAd();

function showCategory();

}FemaleUser.php

<?phprequire_once &#39;Loader.php&#39;;
class FemaleUser implements UserStrategy {

function showAd() {

echo "2016冬季女装";

}function showCategory(){
     echo "女装"; 
}}
MaleUser.php

<?phprequire_once &#39;Loader.php&#39;;
class MaleUser implements UserStrategy {

function showAd(){

echo "IPhone6s";

}function showCategory(){ 
    echo "电子产品"; 
}}
Page.php//执行文件
<?php
require_once &#39;Loader.php&#39;;
class Page {

protected $strategy;function index(){ 
    echo "AD";
    $this->strategy->showAd(); 
    echo "<br>"; 
    echo "Category"; 

    $this->strategy->showCategory(); 
    echo "<br>"; 
} 

function setStrategy(UserStrategy $strategy){ 
    $this->strategy = $strategy; 
}}
$page = new Page();
if(isset($_GET['male'])){

$strategy = new MaleUser();

}else {

$strategy = new FemaleUser();

}strategy);

$page->index();

Résumé :

Grâce à la méthode ci-dessus, vous pouvez constater que différents contenus s'affichent lorsque différents utilisateurs se connectent, mais le problème du codage en dur pendant l'affichage est résolu. Si vous souhaitez ajouter une stratégie, il vous suffit d'ajouter une classe de mise en œuvre de stratégie, puis d'effectuer un jugement dans le fichier d'entrée et de passer dans cette classe. Réaliser le découplage. Implémenter l'inversion de dépendance et l'inversion de contrôle (à comprendre via les interfaces, il n'y a pas de dépendance directe entre les classes) ; Lors de l'utilisation de cette classe, une classe d'implémentation de l'interface est transmise dynamiquement. Si vous souhaitez remplacer une classe, il vous suffit de fournir une classe d'implémentation qui implémente l'interface, et le remplacement peut être effectué en modifiant une ligne de code.

5.观察者模式

观察者模式(Observer),当一个对象状态发生变化时,依赖它的对象全部会收到通知,并自动更新(一个对象通过提供方法允许另一个对象即观察者 注册自己)使本身变得可观察。当可观察的对象更改时,它会将消息发送到已注册的观察者)
场景1:一个事件发生后,要执行一连串更新操作。传统的编程方式,就是在事件的代码之后直接加入处理的逻辑。当更新的逻辑增多之后,代码会变得难以维护。这种方式是耦合的,侵入式的,增加新的逻辑需要修改事件的主体代码。

场景2: 用户登录,需要写日志,送积分,参与活动等;使用消息队列,把用户和日志,积分,活动之间解耦合

观察者模式实现了低耦合,非侵入式的通知与更新机制。

<?php
/*

观察者接口

*/

interface InterfaceObserver

{

function onListen($sender, $args);

function getObserverName();

}// 可被观察者接口

interface InterfaceObservable

{

function addObserver(observer_name);

}// 观察者抽象类

abstract class Observer implements InterfaceObserver

{

protected $observer_name;function getObserverName()

{

return $this->observer_name;

}function onListen($sender, $args)

{}

}// 可被观察类

abstract class Observable implements InterfaceObservable

{

protected $observers = array();public function addObserver(observerinstanceofInterfaceObserver)

{

$this->observers[] = $observer;

}

}public function removeObserver(this->observersas $index => observer->getObserverName() === this->observers, $index, 1);

return;

}

}

}

}// 模拟一个可以被观察的类

class A extends Observable

{

public function addListener(this->observersas $observer)

{
this, $listener);

}

}

}// 模拟一个观察者类

class B extends Observer

{

protected $observer_name = 'B';public function onListen($sender, sender);

echo "<br>";

var_dump($args);

echo "<br>";

}

}// 模拟另外一个观察者类

class C extends Observer

{

protected $observer_name = 'C';public function onListen($sender, sender);

echo "<br>";

var_dump($args);

echo "<br>";

}

}a->addObserver(new B());

$a->addObserver(new C());// 可以看到观察到的信息

$a->addListener('D');// 移除观察者

$a->removeObserver('B');// 打印的信息:

// object(A)#1 (1) { ["observers":protected]=> array(2) { [0]=> object(B)#2 (1) { ["observer_name":protected]=> string(1) "B" } [1]=> object(C)#3 (1) { ["observer_name":protected]=> string(1) "C" } } }

// string(1) "D"

// object(A)#1 (1) { ["observers":protected]=> array(2) { [0]=> object(B)#2 (1) { ["observer_name":protected]=> string(1) "B" } [1]=> object(C)#3 (1) { ["observer_name":protected]=> string(1) "C" } } }

// string(1) "D"

6.装饰器模式

装饰器模式, 根据运行时不同的情景动态地为某个对象调用前后添加不同的行
一个类提供了一项功能,如果要在修改并添加额外的功能,传统的编程模式,需要写一个子类继承它,并重写实现类的方法,使用装饰器模式,仅需要在运行时添加一个装饰器对象即可实现,可以实现最大额灵活性

场景:

1.symfony 控制器中beforepost afterpost 中post提交前和提交后,对数据处理

2.当某一功能或方法draw,要满足不同的功能需求时,可以使用装饰器模式

/**
• 输出一个字符串
• 装饰器动态添加功能
• Class EchoText

*/

class EchoText

{

protected $decorator = [];
public function Index()

{

//调用装饰器前置操作

$this->beforeEcho();

echo "你好,我是装饰器。";

//调用装饰器后置操作

$this->afterEcho();

}
//增加装饰器

public function addDecorator(Decorator $decorator)

{

$this->decorator[] = $decorator;

}
//执行装饰器前置操作 先进先出原则

protected function beforeEcho()

{

foreach ($this->decorator as $decorator)

$decorator->before();

}
//执行装饰器后置操作 先进后出原则

protected function afterEcho()

{
this->decorator);

foreach ($tmp as $decorator)

$decorator->after();

}

}/**
• 装饰器接口
• Class Decorator

*/

interface Decorator

{

public function before();
public function after();

}/**
• 颜色装饰器实现
• Class ColorDecorator

*/

class ColorDecorator implements Decorator

{

protected $color;
public function __construct($color)

{

$this->color = $color;

}
public function before()

{

echo "<dis style=&#39;color: {$this->color}'>";

}
public function after()

{

echo "</div>";

}

}/**
• 字体大小装饰器实现
• Class SizeDecorator

*/

class SizeDecorator implements Decorator

{

protected $size;
public function __construct($size)

{

$this->size = $size;

}
public function before()

{

echo "<dis style=&#39;font-size: {$this->size}px'>";

}
public function after()

{

echo "</div>";

}

}//实例化输出类
echo->addDecorator(new ColorDecorator('red'));

//增加装饰器
echo->Index();

//输出<dis style=&#39;color: red&#39;><dis style=&#39;font-size: 22px&#39;>你好,我是装饰器。</div></div>

7.适配器模式

将一个类的接口转换成客户希望的另一个接口,适配器模式使得原本的由于接口不兼容而不能一起工作的那些类可以一起工作。
场景:老代码接口不适应新的接口需求,或者代码很多很乱不便于继续修改,或者使用第三方类库。例如:php连接数据库的方法:mysql,,mysqli,pdo,可以用适配器统一

//老的代码

class User {private $name;      

function __construct($name) {      
    $this->name = $name;      
}      

public function getName() {      
    return $this->name;      
}}
//新代码,开放平台标准接口

interface UserInterface {

function getUserName();

}class UserInfo implements UserInterface {
protected $user;      

function __construct($user) {      

    $this->user = $user;      

}      

public function getUserName() {      

    return $this->user->getName();      

}}

$olduser = new User('张三');

echo $olduser->getName()."n";olduser);

echo $newuser->getUserName()."n";

推荐学习:《PHP视频教程

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!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer