每天一记之php原型模式
每日一记之php原型模式
原型模式是指通过现有的实例通过拷贝得到新的实例。
在程序的设计中,有的时候我们去实例化某个对象需要做太多的初始化工作,非常耗时的时候,我们可以考虑采用原型模式来得到新的实例。
其实在php中我们很容易通过clone关键字去实现对象的复制。另外通过魔术方法__clone()指定在clone的时候需要进行的操作。这个其实就是原型模式的实现方式了。当然,有时候为了让代码看起来比较优雅,比较完善。我们可以自己去写相关的实现方式,当然也需要用到clone关键字。
<?phpinterface Cloneable{ public function copy();}class Task implements Cloneable{ public $name; public $startTime; public function __construct($name){ //这里实例化Task需要做很多工作 $this->name = $name; $this->startTime = time(); } public function copy(){ return clone $this; }}
在这里我们可以创建一个task
$task1 = new Task("Task1");
现在我们已经有了一个Task的实例了,我们要得到一个新的task实例就可以通过clone的方法
$task2 = $task1->copy();
可是现在这样我们打印$task1和$task2的startTime,两者是一样的,而我们又希望clone出来的对象时间应该是当前时间,怎么做呢?所以我们就得去写__clone方法,该方法在一个对象尝试进行clone的时候会自动调用。改良后的代码如下
class Task implements Cloneable{ public $name; public $startTime; public function __construct($name){ //这里实例化Task需要做很多工作 $this->name = $name; $this->startTime = time(); } public function __clone(){ //在克隆的时候把startTime设为当前时间 $this->startTime = time(); //克隆的时候需要执行的操作 } public function copy(){ return clone $this; }}
这样克隆出来的对象的startTime就更正为当前时间了。
当然了,这只是一个简单的原型模式,在实际的克隆中,又分为浅克隆和深克隆。
浅克隆: 即对象在调用clone方法时只克隆基本的数据类型,而如果对象中包含其他对象的引用时,则copy其他对象的引用
深克隆:即除了克隆基本的数据类型外,引用的类型的数据也一并克隆。
举个例子,现在我的task类里面有一个其他对象的引用,比如Parent。相关代码如下:
class TaskParent{ public $name; public function __construct($name){ $this->name = $name; }}class Task implements Cloneable{ public $name; public $startTime; public $parent; public function __construct($name){ //这里实例化Task需要做很多工作 $this->name = $name; $this->startTime = time(); //这里直接new一个parent $this->parent = new TaskParent("do some work"); } public function __clone(){ //在克隆的时候把startTime设为当前时间 $this->startTime = time(); //克隆的时候需要执行的操作 } public function copy(){ return clone $this; }}
在上面的代码里,我们新定义了一个TaskParent的类,然后Task持有该对象的一个引用,客户端代码:
$task1 = new Task("Task1");echo $task1->parent->name."\r\n";//clone一个对象$task2 = $task1->copy();echo $task2->parent->name."\r\n";//将task1的parent的name设为另外的值$task1->parent->name = "do another work";//打印task2的parent的值echo $task2->parent->name;
class Task implements Cloneable{ public $name; public $startTime; public $parent; public function __construct($name){ //这里实例化Task需要做很多工作 $this->name = $name; $this->startTime = time(); //这里直接new一个parent $this->parent = new TaskParent("do some work"); } public function __clone(){ //在克隆的时候把startTime设为当前时间 $this->startTime = time(); //克隆parent $this->parent = clone $this->parent; //克隆的时候需要执行的操作 } public function copy(){ return clone $this; }}
我们在__clone方法里面对parent也进行了一次克隆,所以现在打印刚才的代码就没有问题了。这就是深克隆。
在真实的编码环境中,可能一个对象持有很多其他的对象的引用,而其他对象对象又持有很多的引用。由于引用的不确定性,我们一开始的时候就应该注意,到底哪些对象需要深克隆,那些对象不需要。
如果想实现快速的深克隆,网上一哥们提供了一个简单的方法代码如下:
class Task implements Cloneable{ public $name; public $startTime; public $parent; public function __construct($name){ //这里实例化Task需要做很多工作 $this->name = $name; $this->startTime = time(); //这里直接new一个parent $this->parent = new TaskParent("do some work"); } public function __clone(){ //在克隆的时候把startTime设为当前时间 $this->startTime = time(); //克隆parent $this->parent = clone $this->parent; //克隆的时候需要执行的操作 } public function copy(){ //return clone $this; //这里不使用clone关键字,而是使用序列化和反序列化来进行 return unserialize(serialize($this)); }}
上述代码中通过serialize和unserialize来得到新的实例,经测试,完全是深克隆。关于serialize和unserialize的效率以及具体讲解将在以后补充上

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

熱門話題

近期不少的win11用戶們反映關機的時候提示taskhostwindow任務宿主正在執行關閉任務,那麼這是怎麼回事?使用者可以進入到本機登錄編輯程式下的Desktop資料夾,然後在右邊的視窗中選擇AutoEndTasks來進行設定就可以了。以下就讓本站來為用戶們來仔細的介紹一下關機出現這個問題的解決方法吧。 windows11關機提示taskhostwindow任務宿主正在執行關閉任務的解決方法1、使用組合鍵win鍵+r鍵,輸入“regedit”,回車,如下圖所示。 2、尋找[HKEY

每年Apple發布新的iOS和macOS大版本之前,用戶都可以提前幾個月下載測試版搶先體驗一番。由於大眾和開發人員都使用該軟體,蘋果公司為兩者推出了developer和public版即開發者測試版的公共測試版。 iOS的developer版和public版有什麼差別呢?從字面上的意思來說,developer版是開發者測試版,public版是公共測試版。 developer版和public版面向的物件不同。 developer版是蘋果公司給開發者測試使用的,需要蘋果開發者帳號才能收到下載併升級,是

php提交表单通过后,弹出的对话框怎样在当前页弹出php提交表单通过后,弹出的对话框怎样在当前页弹出而不是在空白页弹出?想实现这样的效果:而不是空白页弹出:------解决方案--------------------如果你的验证用PHP在后端,那么就用Ajax;仅供参考:HTML code

在物件導向程式設計中,繼承允許我們創建繼承現有類別的屬性和方法的新類別。這個強大的概念可以在我們的程式中實現程式碼重複使用、模組化和可擴展性。在深入研究存取父類別屬性之前,讓我們先了解一下

Javapublic存取權限修飾符允許函數從任何位置訪問,用於聲明公共API、定義跨包或類別共享的工具和實用程式。具體用法如下:語法:public返回值類型函數名稱(參數列表){...}場景:需要從任何地方存取的函數、公共API中的方法、共享的工具或實用程序

Task在C#中是用來表示非同步操作的對象,它位於System.Threading.Tasks命名空間。 Task提供了用於處理並發、非同步操作的高階API,從而可以更輕鬆地在.NET應用程式中編寫非同步程式碼。

php拿不到name是因為當表單元素的name和id的值不一樣的時候,瀏覽器是不能識別的,其解決方法:1、檢查部分錶單元素和框架元素是否用了name;2、檢查只能賦ID不能賦name的元素;3、針對多重選取框checkbox,可使用「join(',', $__POST['name'])」組成資料。

C#Task用法,需要具體程式碼範例概述:Task是C#中一個非常常用的類型,它代表了一個可執行的操作,可以非同步地執行並傳回結果。在處理非同步操作、並行處理和提高應用程式效能方面,Task發揮著重要的作用。本文將介紹Task的基本用法,並提供一些具體的程式碼範例。建立並使用一個Task在C#中,可以使用Task類別來建立和使用一個非同步任務。下面是一個創建並使用Ta
