post-image

Proxy Pattern bảo vệ tài nguyên

Tổng quan

1. Proxy Pattern là gì?

Proxy Pattern là một Design Pattern thuộc nhóm Structural Design Pattern liên quan đến cấu trúc và kết cấu các đối tượng trong lập trình hướng đối tượng. Proxy Pattern tạo ra một lớp trung gian giữa client/controller và các class bên trong. Để đơn giản hơn bạn có thể nghĩ đến khái niệm HTTP proxy trong mạng máy tính, nó là một gateway giữa trình duyệt (client) và máy chủ (subject). HTTP proxy giúp nâng cao trải nghiệm người dùng, tăng tốc với lưu đệm các dữ liệu, loại bỏ các trang quảng cáo, giới hạn các vùng thông tin được xem… Proxy Pattern cũng có chung một mục đích như với HTTP proxy.

Tần suất sử dụng 4/5: Proxy Pattern được dùng khá nhiều trong lập trình hướng đối tượng.

Proxy Pattern có nhiều điểm tương đồng với Facade Pattern và Decorator Pattern, áp dụng Proxy Pattern giúp đơn giản hóa, tối ưu và nâng cao các chủ thể hiện tại. Tuy nhiên nếu dùng ở mức đơn giản hóa và nâng cao chủ thể thì Facade và Decorator nên được dùng hơn. Proxy Pattern chủ yếu tập trung vào tối ưu hóa, đó là việc sử dụng lazy loading – tải các tài nguyên chỉ khi sử dụng chúng. ## 2. Proxy Pattern UML

Proxy Pattern UML Chú ý, trong Proxy Pattern, RealSubject class và Proxy class phải được implement cùng một interface hoặc được mở rộng từ cùng một abstract class. Sử dụng Proxy Pattern giúp cho:

  • Tối ưu hóa ứng dụng thông qua lazy loading, chỉ tải các tài nguyên khi chúng được yêu cầu.
  • Làm cho việc implement trở lên rõ ràng và dễ bảo trì.

3. Ví dụ áp dụng Proxy Pattern

Ví dụ 1:

abstract class ReadFileAbstract { protected $fileName; protected $contents; public function getFileName() { return $this->fileName; } public function setFileName($fileName) { $this->fileName = $fileName; } public function getContents() { return $this->contents; } } class ReadFile extends ReadFileAbstract { const DOCUMENTS_PATH = "/home/simon"; public function __construct($fileName) { $this->setFileName($fileName); $this->contents = file_get_contents(self::DOCUMENTS_PATH . "/" . $this->fileName); } } class ReadFileProxy extends ReadFileAbstract { private $file; public function __construct($fileName) { $this->fileName = $fileName; } public function lazyLoad() { if ($this->file === null) { $this->file = new ReadFile($this->fileName); } return $this->file; } } $proxies = array(); for ($i = 0; $i < 10; $i++) { // tell the proxy which file should be read (when lazy loaded) $proxies[$i] = new ReadFileProxy("file" . $i . ".txt"); } // Now it's time to read the contents of file3.txt $file3 = $proxies[3]->lazyLoad(); // echo the contents of file3.txt echo $file3->getContents();
Code language: PHP (php)

Ví dụ 2:

<?php namespace IcyApril\PetShop; interface AnimalFeeder { public function __construct(string $petName); public function dropFood(int $hungerLevel, bool $water = false): string; public function displayFood(int $hungerLevel): string; } class Cat implements AnimalFeeder { public function __construct(string $petName) { $this->petName = $petName; } public function dropFood(int $hungerLevel, bool $water = false): string { return $this->selectFood($hungerLevel) . ($water?' with water':''); } public function displayFood(int $hungerLevel): string { return $this->selectFood($hungerLevel); } protected function selectFood(int $hungerLevel): string { switch ($hungerLevel) { case 0: return 'lamb'; break; case 1: return 'chicken'; break; case 3: return 'tuna'; break; } } } class Dog { public function __construct(string $petName) { if (strlen($petName) > 10) { throw new \Exception('Name too long.'); } $this->petName = $petName; } public function dropFood(int $hungerLevel, bool $water = false): string { return $this->selectFood($hungerLevel) . ($water?' with water':''); } public function displayFood(int $hungerLevel): string { return $this->selectFood($hungerLevel); } protected function selectFood(int $hungerLevel): string { if ($hungerLevel == 3) { return "chicken and vegetables"; } elseif (date('H') < 10) { return "turkey and beef"; } else { return "chicken and rice"; } } } class AnimalFeederProxy { protected $instance; public function __construct(string $feeder, string $name) { $class = __NAMESPACE__ . '\\AnimalFeeders' . $feeder; $this->instance = new $class($name); } public function __call($name, $arguments) { return call_user_func_array([$this->instance, $name], $arguments); } } $felix = new \IcyApril\PetShop\AnimalFeederProxy('Cat', 'Felix'); echo $felix->displayFood(1); echo "\n"; echo $felix->dropFood(1, true); echo "\n"; $brian = new \IcyApril\PetShop\AnimalFeederProxy('Dog', 'Brian'); echo $brian->displayFood(1); echo "\n"; echo $brian->dropFood(1, true);
Code language: HTML, XML (xml)

Cảm ơn các bạn đã đọc.

Các bạn có thể tham khảo các bài viết hay về Laravel tại đây.


Hãy tham gia nhóm Học lập trình để thảo luận thêm về các vấn đề cùng quan tâm.

Nguồn tham khảo: allaravel

Leave a Reply

Your email address will not be published.