Heim  >  Artikel  >  Backend-Entwicklung  >  Mehrere gängige Entwicklungsmuster in PHP

Mehrere gängige Entwicklungsmuster in PHP

WBOY
WBOYnach vorne
2023-01-03 14:20:544452Durchsuche

Dieser Artikel vermittelt Ihnen relevantes Wissen über PHP und stellt hauptsächlich einige gängige Entwicklungsmodelle vor. Ich hoffe, dass er für alle hilfreich ist.

Mehrere gängige Entwicklungsmuster in PHP

Sechs Prinzipien von Entwurfsmustern

Offenes und geschlossenes Prinzip: Eine Softwareeinheit wie eine Klasse, ein Modul und eine Funktion sollte offen für Erweiterungen und geschlossen für Änderungen sein.

Richter-Substitutionsprinzip: Alle Stellen, die auf eine Basisklasse verweisen, müssen in der Lage sein, Objekte ihrer Unterklassen transparent zu verwenden.

Abhängigkeitsinversionsprinzip: Module auf hoher Ebene sollten nicht von Modulen auf niedriger Ebene abhängen, beide sollten sich auf ihre Abstraktionen verlassen. Abstraktionen sollten nicht von Details abhängen; Details sollten von Abstraktionen abhängen.

Prinzip der Einzelverantwortung: Es darf nicht mehr als einen Grund für Klassenwechsel geben. Laienhaft ausgedrückt ist eine Klasse nur für eine Verantwortung verantwortlich.

Prinzip der Schnittstellenisolation: Der Client sollte sich nicht auf Schnittstellen verlassen, die er nicht benötigt; die Abhängigkeit einer Klasse von einer anderen Klasse sollte auf der kleinsten Schnittstelle basieren.

Demeters Gesetz: Ein Objekt sollte das geringste Wissen über andere Objekte behalten.

1. Singleton-Modus:

Funktionen: Mit dem Singleton-Modus können Sie eine große Anzahl von Ressourcen vermeiden, die durch neue Vorgänge verbraucht werden.

Eine Singleton-Klasse kann nicht direkt instanziiert und erstellt werden, sondern nur von der Klasse instanziiert werden selbst. Um eine solche restriktive Wirkung zu erzielen, muss der Konstruktor daher als privat markiert werden, wodurch verhindert wird, dass die Klasse instanziiert wird.

Sie benötigen eine private statische Mitgliedsvariable, um die Klasseninstanz zu speichern und eine öffentliche statische Methode bereitzustellen, die auf die Instanz zugreifen kann.

Um zu verhindern, dass andere Singleton-Klasseninstanzen klonen, wird in PHP normalerweise eine leere private __clone()-Methode bereitgestellt.

  • $_instance muss als statische private Variable deklariert werden

  • Der Konstruktor und Destruktor müssen als privat deklariert werden, um zu verhindern, dass externe Programme neue Klassen erstellen und somit die Bedeutung des Singleton-Modus verlieren

  • getInstance( )-Methode muss festgelegt werden. Für die Öffentlichkeit muss diese Methode aufgerufen werden, um einen Verweis auf die Instanz zurückzugeben

  • :: Der Operator kann nur auf statische Variablen und statische Funktionen zugreifen. Neue Objekte verbrauchen Speicher. Nutzung Szenarien: Die am häufigsten verwendeten Orte Es handelt sich um eine Datenbankverbindung.

  • Nachdem das Singleton-Muster zum Generieren eines Objekts verwendet wurde, kann das Objekt von vielen anderen Objekten verwendet werden.

  • Die private __clone()-Methode verhindert das Klonen von Objekten

  • <?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. Factory-Modus

  • Factory-Modus, Factory-Methode oder Klasse generieren Objekte statt neu direkt im Code.
  • Verwenden Sie die Methode new, um eine Klasse zu instanziieren. Bei jeder Instanziierung müssen Sie nur die Methode in der Factory-Klasse aufrufen, um sie zu instanziieren.

  • Vorteile: Da eine Klasse an vielen Stellen instanziiert werden kann. Wenn sich der Klassenname oder die Parameter ändern, kann das Factory-Muster einfach und schnell einmal in der Methode unter der Factory-Klasse geändert werden, sodass nicht die instanziierten Objekte einzeln geändert werden müssen

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; 
}}

Angenommen, es handelt sich beispielsweise um Rechtecke und Kreise haben die gleiche Methode. Wenn wir also die von der Basisklasse bereitgestellte API zum Erstellen einer Instanz verwenden, können wir automatisch eine Instanz der entsprechenden Klasse erstellen, indem wir Parameter übergeben. Sie alle haben die Funktion, den Umfang und die Fläche zu ermitteln

3. Registrierungsmodus

Der Registrierungsmodus löst globale Freigabe- und Austauschobjekte. Das erstellte Objekt wird an ein global nutzbares Array gehängt. Bei Bedarf kann es direkt aus dem Array abgerufen werden. Registrieren Sie das Objekt im globalen Baum. Direkter Zugriff von überall.

<?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);
4. Strategiemuster

Strategiemuster kapselt einen bestimmten Satz von Verhaltensweisen und Algorithmen in Klassen ein, um sich an bestimmte spezifische Kontexte anzupassen.

Beispiel: Wenn es ein E-Commerce-Website-System gibt, müssen männliche und weibliche Benutzer zu unterschiedlichen Produktkategorien springen und auf allen Werbeflächen werden unterschiedliche Anzeigen geschaltet. In herkömmlichen Codes werden dem System verschiedene Wenn-Sonst-Urteile auf fest codierte Weise hinzugefügt. Wenn eines Tages ein Benutzer hinzugefügt wird, muss der Code neu geschrieben werden. Wenn Sie im Richtlinienmodus einen neuen Benutzertyp hinzufügen, müssen Sie nur eine Richtlinie hinzufügen. Alles andere erfordert einfach eine andere Strategie.

Deklarieren Sie zunächst die Schnittstellendatei der Strategie und legen Sie das enthaltene Verhalten der Strategie fest. Definieren Sie dann jede spezifische Strategieimplementierungsklasse.

UserStrategy.php

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

Zusammenfassung:

Mit der oben genannten Methode können Sie feststellen, dass bei der Anmeldung verschiedener Benutzer unterschiedliche Inhalte angezeigt werden, das Problem der harten Codierung während der Anzeige jedoch gelöst ist. Wenn Sie eine Strategie hinzufügen möchten, müssen Sie nur eine Strategieimplementierungsklasse hinzufügen, dann eine Beurteilung in der Eintragsdatei durchführen und diese Klasse übergeben. Entkopplung erreichen. Implementieren Sie die Abhängigkeitsinversion und die Kontrollinversion (um es zu verstehen). Über Schnittstellen besteht keine direkte Abhängigkeit zwischen Klassen. Bei Verwendung dieser Klasse wird dynamisch eine Implementierungsklasse der Schnittstelle übergeben. Wenn Sie eine Klasse ersetzen möchten, müssen Sie nur eine Implementierungsklasse bereitstellen, die die Schnittstelle implementiert. Der Ersatz kann durch Ändern einer Codezeile abgeschlossen werden.

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视频教程

Das obige ist der detaillierte Inhalt vonMehrere gängige Entwicklungsmuster in PHP. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:juejin.im. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen