PHP中常見的開發(fā)模式有哪些及怎么實現(xiàn)

這篇文章主要介紹“PHP中常見的開發(fā)模式有哪些及怎么實現(xiàn)”的相關(guān)知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“PHP中常見的開發(fā)模式有哪些及怎么實現(xiàn)”文章能幫助大家解決問題。

為茶陵等地區(qū)用戶提供了全套網(wǎng)頁設計制作服務,及茶陵網(wǎng)站建設行業(yè)解決方案。主營業(yè)務為成都網(wǎng)站設計、網(wǎng)站建設、茶陵網(wǎng)站設計,以傳統(tǒng)方式定制建設網(wǎng)站,并提供域名空間備案等一條龍服務,秉承以專業(yè)、用心的態(tài)度為用戶提供真誠的服務。我們深信只要達到每一位用戶的要求,就會得到認可,從而選擇與我們長期合作。這樣,我們也可以走得更遠!

設計模式六大原則

開放封閉原則:一個軟件實體如類、模塊和函數(shù)應該對擴展開放,對修改關(guān)閉。

里氏替換原則:所有引用基類的地方必須能透明地使用其子類的對象.

依賴倒置原則:高層模塊不應該依賴低層模塊,二者都應該依賴其抽象;抽象不應該依賴細節(jié);細節(jié)應該依賴抽象。

單一職責原則:不要存在多于一個導致類變更的原因。通俗的說,即一個類只負責一項職責。

接口隔離原則:客戶端不應該依賴它不需要的接口;一個類對另一個類的依賴應該建立在最小的接口上。

迪米特法則:一個對象應該對其他對象保持最少的了解。

1.單例模式:

特點: 使用單例模式, 則可以避免大量的new 操作消耗的資源

單例類不能直接實例化創(chuàng)建,而是只能由類本身實例化。因此,要獲得這樣的限制效果,構(gòu)造函數(shù)必須標記為private,從而防止類被實例化。

需要一個私有靜態(tài)成員變量來保存類實例和公開一個能訪問到實例的公開靜態(tài)方法。

在PHP中,為了防止他人對單例類實例克隆,通常還為其提供一個空的私有__clone()方法。

  • $_instance必須聲明為靜態(tài)的私有變量

  • 構(gòu)造函數(shù)和析構(gòu)函數(shù)必須聲明為私有,防止外部程序new 類從而失去單例模式的意義

  • getInstance()方法必須設置為公有的,必須調(diào)用此方法 以返回實例的一個引用

  • ::操作符只能訪問靜態(tài)變量和靜態(tài)函數(shù)

  • new對象都會消耗內(nèi)存

  • 使用場景:最常用的地方是數(shù)據(jù)庫連接。

  • 使用單例模式生成一個對象后, 該對象可以被其它眾多對象所使用。

  • 私有的__clone()方法防止克隆對象

<?php

class Singleton{

//私有屬性,用于保存實例

private static $instance;

//構(gòu)造方法私有化,防止外部創(chuàng)建實例

private function __construct(){}//公有方法,用于獲取實例
public static function getInstance(){
    //判斷實例有無創(chuàng)建,沒有的話創(chuàng)建實例并返回,有的話直接返回
    if(!(self::$instance instanceof self)){
        self::$instance = new self();
    }
    return self::$instance;
}
//克隆方法私有化,防止復制實例
private function __clone(){}}

2.工廠模式

工廠模式,工廠方法或者類生成對象,而不是在代碼中直接new。

使用方法 new實例化類,每次實例化只需調(diào)用工廠類中的方法實例化即可。

優(yōu)點:由于一個類可能會在很多地方被實例化。當類名或參數(shù)發(fā)生變化時,工廠模式可簡單快捷的在工廠類下的方法中一次性修改,避免了一個個的去修改實例化的對象

Test1.php

<?php

class Test1

{

static function test()

{

echo FILE;

}

}Factory.php

<?php

class Factory

{

/**

*如果某個類在很多的文件中都new ClassName(),那么萬一這個類的名字

*發(fā)生變更或者參數(shù)發(fā)生變化,如果不使用工廠模式,就需要修改每一個PHP

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

*/

static function createDatabase()

{

$test = new Test1();

return $test;

}

}

Test.php

<?php

spl_autoload_register('autoload1');

$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 "對象已經(jīng)創(chuàng)建<br>";

return self::tt = new Test1();

echo "創(chuàng)建對象<br>";

return self::$tt;

}

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

<?php

spl_autoload_register('autoload1');

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

舉個例子,假設矩形、圓都有同樣的一個方法,那么我們用基類提供的API來創(chuàng)建實例時,通過傳參數(shù)來自動創(chuàng)建對應的類的實例,他們都有獲取周長和面積的功能

<?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.注冊模式

注冊模式,解決全局共享和交換對象。已經(jīng)創(chuàng)建好的對象,掛在到某個全局可以使用的數(shù)組上,在需要使用的時候,直接從該數(shù)組上獲取即可。將對象注冊到全局的樹上。任何地方直接去訪問。

<?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.策略模式

策略模式,將一組特定的行為和算法封裝成類,以適應某些特定的上下文環(huán)境。
eg:假如有一個電商網(wǎng)站系統(tǒng),針對男性女性用戶要各自跳轉(zhuǎn)到不同的商品類目,并且所有的廣告位展示不同的廣告。在傳統(tǒng)的代碼中,都是在系統(tǒng)中加入各種if else的判斷,硬編碼的方式。如果有一天增加了一種用戶,就需要改寫代碼。使用策略模式,如果新增加一種用戶類型,只需要增加一種策略就可以。其他所有的地方只需要使用不同的策略就可以。
首先聲明策略的接口文件,約定了策略的包含的行為。然后,定義各個具體的策略實現(xiàn)類。
UserStrategy.php

<?php

/*? 聲明策略文件的接口,約定策略包含的行為

*/interface UserStrategy {

function showAd();

function showCategory();

}FemaleUser.php

<?phprequire_once 'Loader.php';
class FemaleUser implements UserStrategy {

function showAd() {

echo "2016冬季女裝";

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

<?phprequire_once 'Loader.php';
class MaleUser implements UserStrategy {

function showAd(){

echo "IPhone6s";

}function showCategory(){ 
    echo "電子產(chǎn)品"; 
}}
Page.php//執(zhí)行文件
<?php
require_once 'Loader.php';
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();

總結(jié):

通過以上方式,可以發(fā)現(xiàn),在不同用戶登錄時顯示不同的內(nèi)容,但是解決了在顯示時的硬編碼的問題。如果要增加一種策略,只需要增加一種策略實現(xiàn)類,然后在入口文件中執(zhí)行判斷,傳入這個類即可。實現(xiàn)了解耦。 實現(xiàn)依賴倒置和控制反轉(zhuǎn) (有待理解); 通過接口的方式,使得類和類之間不直接依賴。在使用該類的時候,才動態(tài)的傳入該接口的一個實現(xiàn)類。如果要替換某個類,只需要提供一個實現(xiàn)了該接口的實現(xiàn)類,通過修改一行代碼即可完成替換。

5.觀察者模式

觀察者模式(Observer),當一個對象狀態(tài)發(fā)生變化時,依賴它的對象全部會收到通知,并自動更新(一個對象通過提供方法允許另一個對象即觀察者 注冊自己)使本身變得可觀察。當可觀察的對象更改時,它會將消息發(fā)送到已注冊的觀察者)
場景1:一個事件發(fā)生后,要執(zhí)行一連串更新操作。傳統(tǒng)的編程方式,就是在事件的代碼之后直接加入處理的邏輯。當更新的邏輯增多之后,代碼會變得難以維護。這種方式是耦合的,侵入式的,增加新的邏輯需要修改事件的主體代碼。

場景2: 用戶登錄,需要寫日志,送積分,參與活動等;使用消息隊列,把用戶和日志,積分,活動之間解耦合

觀察者模式實現(xiàn)了低耦合,非侵入式的通知與更新機制。

<?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.裝飾器模式

裝飾器模式, 根據(jù)運行時不同的情景動態(tài)地為某個對象調(diào)用前后添加不同的行
一個類提供了一項功能,如果要在修改并添加額外的功能,傳統(tǒng)的編程模式,需要寫一個子類繼承它,并重寫實現(xiàn)類的方法,使用裝飾器模式,僅需要在運行時添加一個裝飾器對象即可實現(xiàn),可以實現(xiàn)最大額靈活性

場景:

1.symfony 控制器中beforepost afterpost 中post提交前和提交后,對數(shù)據(jù)處理

2.當某一功能或方法draw,要滿足不同的功能需求時,可以使用裝飾器模式

/**
? 輸出一個字符串
? 裝飾器動態(tài)添加功能
? Class EchoText

*/

class EchoText

{

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

{

//調(diào)用裝飾器前置操作

$this->beforeEcho();

echo "你好,我是裝飾器。";

//調(diào)用裝飾器后置操作

$this->afterEcho();

}
//增加裝飾器

public function addDecorator(Decorator $decorator)

{

$this->decorator[] = $decorator;

}
//執(zhí)行裝飾器前置操作 先進先出原則

protected function beforeEcho()

{

foreach ($this->decorator as $decorator)

$decorator->before();

}
//執(zhí)行裝飾器后置操作 先進后出原則

protected function afterEcho()

{
this->decorator);

foreach ($tmp as $decorator)

$decorator->after();

}

}/**
? 裝飾器接口
? Class Decorator

*/

interface Decorator

{

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

}/**
? 顏色裝飾器實現(xiàn)
? Class ColorDecorator

*/

class ColorDecorator implements Decorator

{

protected $color;
public function __construct($color)

{

$this->color = $color;

}
public function before()

{

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

}
public function after()

{

echo "</div>";

}

}/**
? 字體大小裝飾器實現(xiàn)
? Class SizeDecorator

*/

class SizeDecorator implements Decorator

{

protected $size;
public function __construct($size)

{

$this->size = $size;

}
public function before()

{

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

}
public function after()

{

echo "</div>";

}

}//實例化輸出類
echo->addDecorator(new ColorDecorator('red'));

//增加裝飾器
echo->Index();

//輸出<dis style='color: red'><dis style='font-size: 22px'>你好,我是裝飾器。</div></div>

7.適配器模式

將一個類的接口轉(zhuǎn)換成客戶希望的另一個接口,適配器模式使得原本的由于接口不兼容而不能一起工作的那些類可以一起工作。
場景:老代碼接口不適應新的接口需求,或者代碼很多很亂不便于繼續(xù)修改,或者使用第三方類庫。例如:php連接數(shù)據(jù)庫的方法:MySQL,,mysqli,pdo,可以用適配器統(tǒng)一

//老的代碼

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

關(guān)于“PHP中常見的開發(fā)模式有哪些及怎么實現(xiàn)”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識,可以關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,小編每天都會為大家更新不同的知識點。

當前文章:PHP中常見的開發(fā)模式有哪些及怎么實現(xiàn)
分享路徑:http://muchs.cn/article2/iehdic.html

成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站導航、電子商務、網(wǎng)站排名、標簽優(yōu)化、企業(yè)網(wǎng)站制作

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

網(wǎng)站托管運營