欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

PHP設計模式(四)原型模式Prototype實例詳解【創(chuàng)建型】

 更新時間:2020年05月02日 10:35:03   作者:規(guī)速  
這篇文章主要介紹了PHP設計模式:原型模式Prototype,結(jié)合實例形式詳細分析了PHP原型模式Prototype的基本概念、功能、原理、實現(xiàn)方法與操作注意事項,需要的朋友可以參考下

本文實例講述了PHP設計模式:原型模式Prototype。分享給大家供大家參考,具體如下:

1.   概述

我們都知道,創(chuàng)建型模式一般是用來創(chuàng)建一個新的對象,然后我們使用這個對象完成一些對象的操作,我們通過原型模式可以快速的創(chuàng)建一個對象而不需要提供專門的new()操作就可以快速完成對象的創(chuàng)建,這無疑是一種非常有效的方式,快速的創(chuàng)建一個新的對象。

例子1:孫悟空拔下一嘬猴毛,輕輕一吹就會變出好多的孫悟空來。

例子2:寄個快遞

下面是一個郵寄快遞的場景:
“給我寄個快遞?!鳖櫩驼f。
“寄往什么地方?寄給……?”你問。
“和上次差不多一樣,只是郵寄給另外一個地址,這里是郵寄地址……”顧客一邊說一邊把寫有郵寄地址的紙條給你。
“好!”你愉快地答應,因為你保存了用戶的以前郵寄信息,只要復制這些數(shù)據(jù),然后通過簡單的修改就可以快速地創(chuàng)建新的快遞數(shù)據(jù)了。

2. 問題

當對象的構(gòu)造函數(shù)非常復雜,在生成新對象的時候非常耗時間、耗資源的情況?我們是怎么來創(chuàng)建呢?

3. 解決方案

       通過復制(克隆、拷貝)一個指定類型的對象來創(chuàng)建更多同類型的對象。這個指定的對象可被稱為“原型”對象,也就是通過復制原型對象來得到更多同類型的對象。即原型設計模式。在php的很多模板庫,都用到clone。如smarty等。

4. 適用性

原型模式的主要思想是基于現(xiàn)有的對象克隆一個新的對象出來,一般是有對象的內(nèi)部提供克隆的方法,通過該方法返回一個對象的副本,這種創(chuàng)建對象的方式,相比我們之前說的幾類創(chuàng)建型模式還是有區(qū)別的,之前的講述的工廠模式與抽象工廠都是通過工廠封裝具體的new操作的過程,返回一個新的對象,有的時候我們通過這樣的創(chuàng)建工廠創(chuàng)建對象不值得,特別是以下的幾個場景的時候,可能使用原型模式更簡單也效率更高。

• 1)當一個系統(tǒng)應該獨立于它的產(chǎn)品創(chuàng)建、構(gòu)成和表示時,要使用 Prototype模式

• 2)當要實例化的類是在運行時刻指定時,例如,通過動態(tài)裝載;

• 3)為了避免創(chuàng)建一個與產(chǎn)品類層次平行的工廠類層次時

• 4)當一個類的實例只能有幾個不同狀態(tài)組合中的一種時。建立相應數(shù)目的原型并克隆它們可能比每次用合適的狀態(tài)手工實例化該類更方便一些。(也就是當我們在處理一些對象比較簡單,并且對象之間的區(qū)別很小,可能只是很固定的幾個屬性不同的時候,可能我們使用原型模式更合適)。

5. 結(jié)構(gòu)

     原型模式結(jié)構(gòu)如下頁上圖所示:

6. 組成

客戶(Client)角色:使用原型對象的客戶程序
抽象原型(Prototype)角色:規(guī)定了具體原型對象必須實現(xiàn)的接口(如果要提供深拷貝,則必須具有實現(xiàn)clone的規(guī)定)
具體原型(ConcretePrototype):從抽象原型派生而來,是客戶程序使用的對象,即被復制的對象。此角色需要實現(xiàn)抽象原型角色所要求的接口。

7. 效果

Prototype模式有許多和Abstract Factory模式 和 Builder模式一樣的效果:它對客戶隱藏了具體的產(chǎn)品類,因此減少了客戶知道的名字的數(shù)目。此外,這些模式使客戶無需改變即可使用與特定應用相關(guān)的類。

下面列出Prototype模式的另外一些優(yōu)點。

1 ) 運行時刻增加和刪除產(chǎn)品: Prototype允許只通過客戶注冊原型實例就可以將一個新的具體產(chǎn)品類并入系統(tǒng)。它比其他創(chuàng)建型模式更為靈活,因為客戶可以在運行時刻建立和刪除原型。
2 ) 改變值以指定新對象: 高度動態(tài)的系統(tǒng)允許你通過對象復合定義新的行為—例如,通過為一個對象變量指定值—并且不定義新的類。你通過實例化已有類并且將這些實例注冊為客戶對象的原型,就可以有效定義新類別的對象。客戶可以將職責代理給原型,從而表現(xiàn)出新的行為。這種設計使得用戶無需編程即可定義新“類” 。實際上,克隆一個原型類似于實例化一個類。Prototype模式可以極大的減少系統(tǒng)所需要的類的數(shù)目。
3) 改變結(jié)構(gòu)以指定新對象:許多應用由部件和子部件來創(chuàng)建對象。
4) 減少子類的構(gòu)造 Factory Method 經(jīng)常產(chǎn)生一個與產(chǎn)品類層次平行的 Creator類層次。Prototype模式使得你克隆一個原型而不是請求一個工廠方法去產(chǎn)生一個新的對象。因此你根本不需要Creator類層次。這一優(yōu)點主要適用于像 C + +這樣不將類作為一級類對象的語言。像Smalltalk和Objective C這樣的語言從中獲益較少,因為你總是可以用一個類對象作為生成者。在這些語言中,類對象已經(jīng)起到原型一樣的作用了。
5) 用類動態(tài)配置應用 一些運行時刻環(huán)境允許你動態(tài)將類裝載到應用中。在像 C + +這樣的語言中,Prototype模式是利用這種功能的關(guān)鍵。一個希望創(chuàng)建動態(tài)載入類的實例的應用不能靜態(tài)引用類的構(gòu)造器。而應該由運行環(huán)境在載入時自動創(chuàng)建每個類的實例,并用原型管理器來注冊這個實例(參見實現(xiàn)一節(jié)) 。這樣應用就可以向原型管理器請求新裝載的類的實例,這些類原本并沒有和程序相連接。 E T + +應用框架[ W G M 8 8 ]有一個運行系統(tǒng)就是使用這一方案的。

Prototype的主要缺陷是每一個Prototype的子類都必須實現(xiàn)clone操作,這可能很困難。
例如,當所考慮的類已經(jīng)存在時就難以新增 clone操作。當內(nèi)部包括一些不支持拷貝或有循環(huán)引用的對象時,實現(xiàn)克隆可能也會很困難的。

8. 實現(xiàn)

<?php
/**
 * 原型模式 
 */
 
/**
 * 抽象原型角色
 */
interface Prototype {
  public function copy();
}
 
/**
 * 具體原型角色
 */
class ConcretePrototype implements Prototype{
 
  private $_name;
 
  public function __construct($name) {
    $this->_name = $name;
  }
 
  public function setName($name) {
    $this->_name = $name;
  }
 
  public function getName() {
    return $this->_name;
  }
 
  public function copy() {
    /** 深拷貝 */
    return clone $this;  
    /** 淺拷貝 */
    //return $this;  
  }
}
 
class Client {
 
   /**
   * Main program.
   */
  public static function main() {
    $object1 = new ConcretePrototype(11);
    $object_copy = $object1->copy();
 
    var_dump($object1->getName());
    echo '<br />';
    var_dump($object_copy->getName());
    echo '<br />';
 
    $object1->setName(22);
    var_dump($object1->getName());
    echo '<br />';
    var_dump($object_copy->getName());
    echo '<br />';
  }
}
Client::main();
?>

9. 淺拷貝和深拷貝

原型模式的原理圖:

淺拷貝

被拷貝對象的所有變量都含有與原對象相同的值,而且對其他對象的引用仍然是指向原來的對象。即淺拷貝只負責當前對象實例,對引用的對象不做拷貝。

淺復制后的對象和對象副本的情況:

深拷貝

被拷貝對象的所有的變量都含有與原來對象相同的值,除了那些引用其他對象的變量。那些引用其他對象的變量將指向一個被拷貝的新對象,而不再是原有那些被引用對象。即 深拷貝把要拷貝的對象所引用的對象也都拷貝了一次,而這種對被引用到的對象拷貝叫做間接拷貝。

深復制的對象和對象副本的情況:

深拷貝要深入到多少層,是一個不確定的問題。

在決定以深拷貝的方式拷貝一個對象的時候,必須決定對間接拷貝的對象是采取淺拷貝還是深拷貝還是繼續(xù)采用深拷貝。

因此,在采取深拷貝時,需要決定多深才算深。此外,在深拷貝的過程中,很可能會出現(xiàn)循環(huán)引用的問題。

10. 帶Prototype Manager的原型模式

     原型模式的第二種形式是帶原型管理器的原型模式,其UML圖如下:

       原型管理器(Prototype Manager)角色:創(chuàng)建具體原型類的對象,并記錄每一個被創(chuàng)建的對象。

       下面這個例子演示了在原型管理器中存儲用戶預先定義的顏色原型,客戶通過原型管理器克隆顏色對象。

<?php
/**
 * abstract Prototype
 *
 */
abstract class ColorPrototype
{
 //Methods
 abstract function copy();
}
 
/**
 * Concrete Prototype
 *
 */
class Color extends ColorPrototype{
 //Fields
 private $red;
 private $green;
 private $blue;
 //Constructors
 function __construct( $red, $green, $red) {
  $this->red = $red;
  $this->green = $green;
  $this->blue = $red;
 }
 /**
  * set red
  *
  * @param unknown_type $red
  */
 public function setRed($red) {
  $this->red = $red;
 }
 
 /**
  * get red
  *
  */
 public function getRed(){
  return $this->red;
 }
 /**
  *set Green
  *
  * @param $green
  */
 public function setGreen($green) {
  $this->green = $green;
 }
 /**
  * get Green
  *
  * @return unknown
  */
 public function getGreen() {
  return $this->green ;
 }
 /**
  *set Blue
  *
  * @param $Blue
   */
 public function setBlue($Blue) {
  $this->blue = $Blue;
 }
 /**
  * get Blue
  *
  * @return unknown
  */
 public function getBlue() {
  return $this->blue ;
 }
 
 /**
 * Enter description here...
 *
 * @return unknown
 */
 function copy(){
 return clone $this;
 }
 
 function display() {
 echo $this->red , ',', $this->green, ',', $this->blue ,'<br>';
 }
}
/**
 * Enter description here...
 *
 */
class ColorManager
{
 // Fields
 static $colors = array();
 // Indexers
 public static function add($name, $value){
 self::$colors[$name] = $value;
 }
 
 public static function getCopy($name) {
 return  self::$colors[$name]->copy();
 }
}
/**
 *Client
 *
 */
class Client
{
 public static function Main()
 {
 //原型:白色
 ColorManager::add("white", new Color( 255, 0, 0 ));
 
 //紅色可以由原型白色對象得到,只是重新修改白色: r
 $red = ColorManager::getCopy('white');
 $red->setRed(255);
 $red->display();
 
 //綠色可以由原型白色對象得到,只是重新修改白色: g
 $green = ColorManager::getCopy('white');
 $green->setGreen(255);
 $green->display();
 
 //綠色可以由原型白色對象得到,只是重新修改白色: b
 $Blue = ColorManager::getCopy('white');
 $Blue->setBlue(255);
 $Blue->display();
 }
}
ini_set('display_errors', 'On');
error_reporting(E_ALL & ~ E_DEPRECATED);
Client::Main();
?>

更多關(guān)于PHP相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《php面向?qū)ο蟪绦蛟O計入門教程》、《PHP數(shù)組(Array)操作技巧大全》、《PHP基本語法入門教程》、《PHP運算與運算符用法總結(jié)》、《php字符串(string)用法總結(jié)》、《php+mysql數(shù)據(jù)庫操作入門教程》及《php常見數(shù)據(jù)庫操作技巧匯總

希望本文所述對大家PHP程序設計有所幫助。

相關(guān)文章

  • PHP通過pem文件校驗簽名異常問題解決

    PHP通過pem文件校驗簽名異常問題解決

    在對接第三方支付過程中,支付成功異步回調(diào)時,校驗簽名,一直無法通過,最后經(jīng)過排查,是引用秘鑰文件時,報錯了,本文給大家分享PHP通過pem文件校驗簽名異常問題解決方法,需要的朋友可以參考下
    2023-09-09
  • 詳解php日期查詢和fastadmin的日期查詢

    詳解php日期查詢和fastadmin的日期查詢

    要在PHP中查詢數(shù)據(jù)庫中當前月份的數(shù)據(jù),需要使用SQL查詢語句來篩選出符合條件的數(shù)據(jù),這篇文章主要介紹了php查詢數(shù)據(jù)(日期查詢)和fastadmin的日期查詢,需要的朋友可以參考下
    2023-08-08
  • laravel Validator ajax返回錯誤信息的方法

    laravel Validator ajax返回錯誤信息的方法

    今天小編就為大家分享一篇laravel Validator ajax返回錯誤信息的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-09-09
  • 總結(jié)PHP如何獲取當前主機、域名、網(wǎng)址、路徑、端口和參數(shù)等

    總結(jié)PHP如何獲取當前主機、域名、網(wǎng)址、路徑、端口和參數(shù)等

    這篇文章給大家分享了利用php如何獲取當前域名或主機地址、網(wǎng)頁地址、網(wǎng)址參數(shù)、用戶代理、完整的url、包含端口號的完整url以及只取路徑等信息,有需要的朋友們可以參考借鑒。
    2016-09-09
  • php 使用mpdf實現(xiàn)指定字段配置字體樣式的方法

    php 使用mpdf實現(xiàn)指定字段配置字體樣式的方法

    前兩天在做一個pdf導出功能,使用的插件是kartik-v/yii2-mpdf,此插件使用的是mpdf。接下來通過本文給大家介紹php 使用mpdf實現(xiàn)指定字段配置字體樣式的方法,需要的朋友可以參考下
    2019-07-07
  • PHP安裝threads多線程擴展基礎教程

    PHP安裝threads多線程擴展基礎教程

    php5.3或以上,且為線程安全版本。apache和php使用的編譯器必須一致,通過phpinfo()查看Thread Safety為enabled則為線程安全版,通過phpinfo()查看Compiler項可以知道使用的編譯器,本文給大家介紹PHP安裝threads多線程擴展基礎教程,需要的朋友參考下
    2015-11-11
  • php安裝擴展mysqli的實現(xiàn)步驟及報錯解決辦法

    php安裝擴展mysqli的實現(xiàn)步驟及報錯解決辦法

    這篇文章主要介紹了 php安裝擴展mysqli的實現(xiàn)步驟及報錯解決辦法的相關(guān)資料,希望通過本文能幫助到大家,需要的朋友可以參考下
    2017-09-09
  • PHP 面向?qū)ο蟪绦蛟O計(oop)學習筆記 (四) - 異常處理類Exception

    PHP 面向?qū)ο蟪绦蛟O計(oop)學習筆記 (四) - 異常處理類Exception

    異常經(jīng)常被用來處理一些在程序正常執(zhí)行中遇到的各種類型的錯誤。比如做數(shù)據(jù)庫鏈接時,你就要處理數(shù)據(jù)庫連接失敗的情況。使用異??梢蕴岣呶覀兂绦虻娜蒎e特性,從而使我們的應用程序更加的穩(wěn)定和健壯。
    2014-06-06
  • php多功能圖片處理類分享(php圖片縮放類)

    php多功能圖片處理類分享(php圖片縮放類)

    本文提供的php類用于完成圖片縮放,水印添加,當水印圖超過目標圖片尺寸時,水印圖能自動適應目標圖片而縮小,當水印圖超過目標圖片尺寸時,水印圖能自動適應目標圖片而縮小,需要的朋友可以參考下
    2014-03-03
  • php數(shù)組中包含中文的排序方法

    php數(shù)組中包含中文的排序方法

    這篇文章主要介紹了php數(shù)組中包含中文的排序方法,需要的朋友可以參考下
    2014-06-06

最新評論