# 代理模式 In plain words 通俗易懂 > Using the proxy pattern, a class represents the functionality of another class. > 使用代理模式,一个类表示另一个类的功能。 Wikipedia says 维基百科说 > A proxy, in its most general form, is a class functioning as an interface to something else. A proxy is a wrapper or agent object that is being called by the client to access the real serving object behind the scenes. Use of the proxy can simply be forwarding to the real object, or can provide additional logic. In the proxy extra functionality can be provided, for example caching when operations on the real object are resource intensive, or checking preconditions before operations on the real object are invoked. > 代理,在其最一般的形式中,是一个充当其他事物的接口的类。代理是客户端调用的包装器或代理对象,用于在后台访问真实的服务对象。使用 proxy 可以简单地转发到真实对象,也可以提供额外的 logic。在代理中可以提供额外的功能,例如,当对真实对象的操作是资源密集型时进行缓存,或者在调用对真实对象的操作之前检查前提条件。 **Programmatic Example 编程示例** Taking our security door example from above. Firstly we have the door interface and an implementation of door 以上面的安全门为例。首先,我们有 door 接口和 door 的实现 ```php interface Door { public function open(); public function close(); } class LabDoor implements Door { public function open() { echo "Opening lab door"; } public function close() { echo "Closing the lab door"; } } ``` Then we have a proxy to secure any doors that we want 然后我们有一个代理来保护我们想要的任何门 ```php class SecuredDoor implements Door { protected $door; public function __construct(Door $door) { $this->door = $door; } public function open($password) { if ($this->authenticate($password)) { $this->door->open(); } else { echo "Big no! It ain't possible."; } } public function authenticate($password) { return $password === '$ecr@t'; } public function close() { $this->door->close(); } } ``` And here is how it can be used 以下是它的使用 ```php $door = new SecuredDoor(new LabDoor()); $door->open('invalid'); // Big no! It ain't possible. $door->open('$ecr@t'); // Opening lab door $door->close(); // Closing lab door ``` **优点:降低耦合度** **缺点:实现代理的过程较为复杂,可能导致处理速度变慢** # 职责链模式 In plain words 通俗易懂 > It helps building a chain of objects. Request enters from one end and keeps going from object to object till it finds the suitable handler. > 它有助于构建对象链。请求从一端进入,并不断从一个对象转到另一个对象,直到找到合适的处理程序。 **Programmatic Example 编程示例** Translating our account example above. First of all we have a base account having the logic for chaining the accounts together and some accounts 翻译上面的账户示例。首先,我们有一个 base 账户,它具有将账户链接在一起的逻辑,还有一些账户 ```php abstract class Account { protected $successor; protected $balance; public function setNext(Account $account) { $this->successor = $account; } public function pay(float $amountToPay) { if ($this->canPay($amountToPay)) { echo sprintf('Paid %s using %s' . PHP_EOL, $amountToPay, get_called_class()); } elseif ($this->successor) { echo sprintf('Cannot pay using %s. Proceeding ..' . PHP_EOL, get_called_class()); $this->successor->pay($amountToPay); } else { throw new Exception('None of the accounts have enough balance'); } } public function canPay($amount): bool { return $this->balance >= $amount; } } class Bank extends Account { protected $balance; public function __construct(float $balance) { $this->balance = $balance; } } class Paypal extends Account { protected $balance; public function __construct(float $balance) { $this->balance = $balance; } } class Bitcoin extends Account { protected $balance; public function __construct(float $balance) { $this->balance = $balance; } } ``` Now let's prepare the chain using the links defined above (i.e. Bank, Paypal, Bitcoin) 现在让我们使用上面定义的链接(即 Bank、PayPal、Bitcoin)准备链 ```php // Let's prepare a chain like below // $bank->$paypal->$bitcoin // // First priority bank // If bank can't pay then paypal // If paypal can't pay then bit coin $bank = new Bank(100); // Bank with balance 100 $paypal = new Paypal(200); // Paypal with balance 200 $bitcoin = new Bitcoin(300); // Bitcoin with balance 300 $bank->setNext($paypal); $paypal->setNext($bitcoin); // Let's try to pay using the first priority i.e. bank $bank->pay(259); // Output will be // ============== // Cannot pay using bank. Proceeding .. // Cannot pay using paypal. Proceeding ..: // Paid 259 using Bitcoin! ```