백엔드 개발 PHP 튜토리얼 每天一记之php原型模式

每天一记之php原型模式

Jun 13, 2016 am 11:38 AM
name parent public task

每日一记之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;
로그인 후 복사
上面的代码最后一句话将打印 do another work,也就是说我们更改task1的parent影响到了task2。这就是典型的浅克隆,如果想实现深克隆,则可以进行如下改装

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的效率以及具体讲解将在以后补充上


본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

인기 기사

R.E.P.O. 에너지 결정과 그들이하는 일 (노란색 크리스탈)
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 최고의 그래픽 설정
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 아무도들을 수없는 경우 오디오를 수정하는 방법
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25 : Myrise에서 모든 것을 잠금 해제하는 방법
4 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

Windows 11 종료 프롬프트 작업 호스트 창 작업 호스트가 종료 작업 솔루션을 실행 중입니다. Windows 11 종료 프롬프트 작업 호스트 창 작업 호스트가 종료 작업 솔루션을 실행 중입니다. Feb 12, 2024 pm 12:40 PM

최근 많은 Win11 사용자가 종료할 때 taskhostwindow 작업 호스트가 종료 작업을 실행하고 있다는 메시지가 표시된다고 보고했습니다. 무슨 일이 일어나고 있는 걸까요? 사용자는 로컬 레지스트리 편집기 아래 Desktop 폴더에 들어간 후 오른쪽 창에서 AutoEndTasks를 선택하여 설정할 수 있습니다. 이 사이트를 종료할 때 이 문제에 대한 해결책을 사용자에게 주의 깊게 소개하십시오. Windows 11 종료에서는 taskhostwindow 작업 호스트가 종료 작업을 실행 중이라는 메시지가 표시됩니다. 해결 방법 1. 아래 그림과 같이 win 키 + r 키 조합을 사용하여 "regedit"를 입력하고 Enter 키를 누릅니다. 2. [HKEY]를 검색하세요

iOS 개발자 버전과 공개 버전의 차이점은 무엇인가요? iOS 개발자 버전과 공개 버전의 차이점은 무엇인가요? Mar 01, 2024 pm 12:55 PM

매년 Apple이 iOS 및 macOS의 새로운 주요 버전을 출시하기 전에 사용자는 몇 달 전에 베타 버전을 다운로드하여 먼저 경험할 수 있습니다. 소프트웨어는 대중과 개발자 모두가 사용하기 때문에 Apple은 개발자 베타 버전의 공개 베타 버전인 개발자 버전과 공개 버전을 모두 출시했습니다. iOS 개발자 버전과 공개 버전의 차이점은 무엇인가요? 말 그대로 개발자 버전은 개발자 베타 버전이고, 퍼블릭 버전은 퍼블릭 베타 버전이다. 개발자 버전과 공개 버전은 서로 다른 대상을 대상으로 합니다. 개발자 버전은 개발자가 테스트하기 위해 Apple에서 사용합니다. 다운로드하고 업그레이드하려면 Apple 개발자 계정이 필요합니다.

php提交表单通过后,弹出的对话框怎样在当前页弹出,该如何解决 php提交表单通过后,弹出的对话框怎样在当前页弹出,该如何解决 Jun 13, 2016 am 10:23 AM

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

Python에서 상위 클래스 속성에 액세스하는 방법은 무엇입니까? Python에서 상위 클래스 속성에 액세스하는 방법은 무엇입니까? Aug 26, 2023 am 10:17 AM

객체 지향 프로그래밍에서 상속을 사용하면 기존 클래스의 속성과 메서드를 상속하는 새 클래스를 만들 수 있습니다. 이 강력한 개념은 프로그램의 코드 재사용, 모듈성 및 확장성을 가능하게 합니다. 상위 클래스 속성에 액세스하기 전에 먼저 살펴보겠습니다.

Java 함수 접근 한정자 공개 사용 가이드 Java 함수 접근 한정자 공개 사용 가이드 Apr 26, 2024 am 08:39 AM

Java 공용 액세스 수정자를 사용하면 어디에서나 함수에 액세스할 수 있으며 공용 API를 선언하고 패키지 또는 클래스 간에 공유되는 도구 및 유틸리티를 정의하는 데 사용됩니다. 구체적인 사용법은 다음과 같습니다. 구문: 공용 반환 값 유형 함수 이름(매개변수 목록) {...} 시나리오: 어디서나 액세스해야 하는 함수, 공용 API의 메서드, 공유 도구 또는 유틸리티

C#Task에 대한 자세한 설명 C#Task에 대한 자세한 설명 Mar 14, 2024 am 09:54 AM

Task는 C#에서 비동기 작업을 나타내는 데 사용되는 개체이며 System.Threading.Tasks 네임스페이스에 있습니다. Task는 동시 비동기 작업을 처리하기 위한 고급 API를 제공하므로 .NET 애플리케이션에서 비동기 코드를 더 쉽게 작성할 수 있습니다.

PHP가 이름을 얻을 수 없으면 어떻게 해야 합니까? PHP가 이름을 얻을 수 없으면 어떻게 해야 합니까? Nov 24, 2022 am 09:56 AM

양식 요소의 이름과 ID 값이 다르면 브라우저가 이를 인식할 수 없기 때문에 PHP는 이름을 얻을 수 없습니다. 해결 방법: 1. 일부 양식 요소와 프레임 요소가 이름을 사용하는지 확인하십시오. 2. 이름을 사용할 수 있는 요소만 확인하십시오. ID는 할당되지만 이름은 할당되지 않습니다. 3. 다중 선택 상자 확인란의 경우 "join(',', $__POST['name'])"을 사용하여 데이터를 구성할 수 있습니다.

C# 작업 사용 C# 작업 사용 Feb 19, 2024 pm 12:16 PM

C#Task를 사용하려면 특정 코드 예제에 대한 개요가 필요합니다. Task는 C#에서 매우 일반적으로 사용되는 형식으로, 비동기적으로 실행되고 결과를 반환할 수 있는 실행 가능한 작업을 나타냅니다. 작업은 비동기 작업 처리, 병렬 처리 및 애플리케이션 성능 향상에 중요한 역할을 합니다. 이 문서에서는 Task의 기본 사용법을 소개하고 몇 가지 구체적인 코드 예제를 제공합니다. 작업 만들기 및 사용 C#에서는 Task 클래스를 사용하여 비동기 작업을 만들고 사용할 수 있습니다. Ta를 생성하고 사용하는 방법은 다음과 같습니다.

See all articles