이 글은 주로 PHP에서 프록시 패턴을 구현하는 방법을 소개합니다. 특정 참조 값이 있으므로 이를 공유합니다. 필요한 친구가 참조할 수 있습니다.
프록시 패턴:
프록시를 사용하여 객체를 제공합니다. 프록시 객체는 원본 객체에 대한 참조를 제어합니다. 프록시 패턴은 영어로 Proxy 또는 Surrogate라고 합니다.
모델 동기:
경우에 따라 클라이언트가 객체를 직접 참조할 수 없는 경우가 있습니다. "프록시". 간접 참조를 구현하는 제3자입니다. 프록시 객체는 클라이언트와 대상 객체 사이에서 중개 역할을 할 수 있으며, 클라이언트가 볼 수 없는 콘텐츠와 서비스를 제거하거나 클라이언트가 필요로 하는 추가적인 서비스를 프록시 객체를 통해 추가할 수 있다.
실제 객체의 작동을 실현하기 위해 새 객체(예: 작은 그림 및 원격 프록시 객체)를 도입하거나 새 객체를 실제 객체 대신 사용함으로써 이 구현 메커니즘은 프록시 모드를 도입합니다. 프록시 객체에서 객체에 간접적으로 접근하는 것이 프록시 패턴의 패턴 동기입니다.
프록시 모드에는 다음 역할이 포함됩니다.
추상 주체 역할(Subject): RealSubject가 사용되는 모든 곳에서 Proxy를 사용할 수 있도록 RealSubject와 Proxy의 공개 인터페이스를 정의합니다.
실제 주체 역할(RealSubject): Proxy가 나타내는 실제 엔터티를 정의합니다.
프록시 객체(Proxy): 프록시가 엔터티에 접근할 수 있도록 참조를 저장하고, 엔터티(RealSubject) 대신 프록시를 사용할 수 있도록 RealSubject 인터페이스와 동일한 인터페이스를 제공합니다.
UML 다이어그램:
코드 구현:
<?php header("Content-type:text/html;Charset=utf-8");//定义RealSubject和Proxy共同具备的东西 interface Subject{ function say(); function run(); } class RealSubject implements Subject{ private $name; function __construct($name){ $this->name = $name; } function say(){ echo $this->name."在吃饭<br>"; } function run(){ echo $this->name."在跑步<br>"; } } class Proxy implements Subject{ private $realSubject = null; function __construct(RealSubject $realSubject = null){ if(empty($realSubject)){ $this->realSubject = new RealSubject(); }else{ $this->realSubject = $realSubject; } } function say(){ $this->realSubject->say(); } function run(){ $this->realSubject->run(); } }//测试 $subject = new RealSubject("张三"); $proxy = new Proxy($subject);$proxy->say(); $proxy->run(); /*张三在吃饭 张三在跑步*/ ?>
장점:
프록시 모드는 호출자와 호출 수신자를 조정하여 시스템 결합을 어느 정도 줄일 수 있습니다.
원격 프록시를 사용하면 클라이언트가 원격 시스템의 개체에 액세스할 수 있습니다. 원격 시스템은 더 나은 컴퓨팅 성능과 처리 속도를 가지며 클라이언트 요청에 빠르게 응답하고 처리할 수 있습니다.
작은 개체를 사용하여 큰 개체를 표현함으로써 가상 에이전트는 시스템 리소스 소비를 줄이고 시스템을 최적화하며 실행 속도를 높일 수 있습니다.
보호 에이전트는 실제 개체에 대한 접근을 제어할 수 있습니다.
단점:
클라이언트와 실제 주제 사이에 프록시 개체가 추가되므로 일부 유형의 프록시 모드로 인해 요청 처리 속도가 느려질 수 있습니다.
프록시 패턴을 구현하려면 추가 작업이 필요하며 일부 프록시 패턴의 구현은 매우 복잡합니다.
적용 가능한 시나리오:
프록시 모드를 사용하는 목적에 따라 일반적인 프록시 모드에는 다음과 같은 유형이 있습니다.
1. 원격 프록시: 다른 주소 공간에 위치한 개체에 대해 로컬 프록시 개체를 제공합니다. 이 차이는 주소 공간입니다. 동일한 호스트에 있을 수도 있고 다른 호스트에 있을 수도 있습니다. 원격 에이전트는 Ambassador라고도 합니다.
2. 가상 프록시: 많은 양의 리소스를 소비하는 개체를 생성해야 하는 경우 먼저 이를 표현하기 위해 상대적으로 적은 양의 리소스를 소비하는 개체를 생성합니다. 실제 개체는 필요할 때만 생성됩니다.
3. Copy-on-Write 에이전트: 클라이언트가 정말로 필요할 때만 실행될 때까지 복사(복제) 작업을 지연시키는 일종의 가상 에이전트입니다. 일반적으로 객체의 심층 복제는 비용이 많이 드는 작업입니다. Copy-on-Write 프록시는 이 작업을 지연시킬 수 있으며 객체는 사용될 때만 복제됩니다.
4. 보호(보호 또는 액세스) 에이전트: 개체에 대한 액세스를 제어하고 사용자마다 다양한 수준의 사용 권한을 제공할 수 있습니다.
5. 캐시 에이전트: 특정 대상 작업의 결과를 여러 클라이언트가 공유할 수 있도록 임시 저장 공간을 제공합니다.
6. 방화벽 프록시: 악의적인 사용자로부터 대상을 보호합니다.
7. 동기화 에이전트: 여러 사용자가 충돌 없이 동시에 개체를 사용할 수 있도록 합니다.
8. 스마트 참조 에이전트: 객체가 참조되면 해당 객체가 호출된 횟수를 기록하는 등 몇 가지 추가 작업을 제공합니다.
几种常用的代理模式:
1、图片代理:一个很常见的代理模式的应用实例就是对大图浏览的控制。
用户通过浏览器访问网页时先不加载真实的大图,而是通过代理对象的方法来进行处理,在代理对象的方法中,先使用一个线程向客户端浏览器加载一个小图片,然后在后台使用另一个线程来调用大图片的加载方法将大图片加载到客户端。当需要浏览大图片时,再将大图片在新网页中显示。如果用户在浏览大图时加载工作还没有完成,可以再启动一个线程来显示相应的提示信息。通过代理技术结合多线程编程将真实图片的加载放到后台来操作,不影响前台图片的浏览。
2、远程代理:远程代理可以将网络的细节隐藏起来,使得客户端不必考虑网络的存在。客户完全可以认为被代理的远程业务对象是局域的而不是远程的,而远程代理对象承担了大部分的网络通信工作。
3、虚拟代理:当一个对象的加载十分耗费资源的时候,虚拟代理的优势就非常明显地体现出来了。虚拟代理模式是一种内存节省技术,那些占用大量内存或处理复杂的对象将推迟到使用它的时候才创建。
在应用程序启动的时候,可以用代理对象代替真实对象初始化,节省了内存的占用,并大大加速了系统的启动时间。
4、动态代理:动态代理是一种较为高级的代理模式,它的典型应用就是Spring AOP。
在传统的代理模式中,客户端通过Proxy调用RealSubject类的request()方法,同时还在代理类中封装了其他方法(如preRequest()和postRequest()),可以处理一些其他问题。
如果按照这种方法使用代理模式,那么真实主题角色必须是事先已经存在的,并将其作为代理对象的内部成员属性。如果一个真实主题角色必须对应一个代理主题角色,这将导致系统中的类个数急剧增加,因此需要想办法减少系统中类的个数,此外,如何在事先不知道真实主题角色的情况下使用代理主题角色,这都是动态代理需要解决的问题。
另一个例子:
github地址:https://github.com/ZQCard/design_pattern
/** * 在代理模式中,我们创建具有现有对象的对象,以便向外界提供功能接口。 * 1、Windows 里面的快捷方式。 * 2、猪八戒去找高翠兰结果是孙悟空变的,可以这样理解:把高翠兰的外貌抽象出来,高翠兰本人和孙悟空都实现了这个接口, * 猪八戒访问高翠兰的时候看不出来这个是孙悟空,所以说孙悟空是高翠兰代理类。 * 3、买火车票不一定在火车站买,也可以去代售点。 * 4、一张支票或银行存单是账户中资金的代理。支票在市场交易中用来代替现金,并提供对签发人账号上资金的控制。 *优点: * 1、职责清晰。 2、高扩展性。 3、智能化。 * 缺点: * 1、由于在客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢。 * 2、实现代理模式需要额外的工作,有些代理模式的实现非常复杂。 * 例子:从服务器读取一张图片的时候,第一次从硬盘读取,将资源对象代理,第二次读取的时候就使用代理对象去读取。 */
(1)Image.class.php(接口)
<?php namespace Proxy;interface Image { public function display(); }
(2)RealImage.class.php
<?php namespace Proxy;class RealImage implements Image { private $fileName; public function __construct($fileName) { $this->fileName = $fileName; $this->loadFromDisk($fileName); } public function display() { print_r("Displaying ". $this->fileName); echo '<pre/>'; } private function loadFromDisk($fileName) { print_r("Loading ". $fileName); echo '<pre/>'; } }
(3)ProxyImage.class.php(代理类)
<?php namespace Proxy;class ProxyImage implements Image { private $realImage; private $fileName; public function __construct($fileName) { $this->fileName = $fileName; } public function display() { if ($this->realImage == null){ $this->realImage = new RealImage($this->fileName); } return $this->realImage->display(); } }
(4)proxy.php
<? ( = ('\\','/', .".class.php" = ProxyImage('a.jpg'->
以上就是本文的全部内容,希望对大家的学习有所帮助,更多相关内容请关注PHP中文网!
相关推荐:
위 내용은 PHP에서 프록시 모드를 구현하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!