Created
June 30, 2022 04:55
-
-
Save andreconghau/ff2240705e679c8d7473a45795f68480 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* https://www.youtube.com/watch?v=IoLXT1UleX4&index=7&list=PLGJDCzBP5j3xGaW0AGlaVHK2TMEr2XkP9 | |
* https://github.com/ezimuel/PHP-design-patterns | |
* http://fsd14.com/post/91-design-pattern-decorator-design | |
* | |
* | |
* Chúng ta có thể sử dụng decorator pattern khi ta muốn đưa ra một số trách nhiệm bổ sung vào class cơ sở. Nghĩa là một class có thể | |
* được add thêm một chức năng của class khác mà không thay đổi cấu trúc của class. | |
* | |
* Design pattern này là một sự thay thế tuyệt vời cho tính năng sub-classing để mở rộng các chức năng với một số lợi ích được bổ sung. | |
* | |
* Với mỗi ứng dụng, chúng ta cần một vài kiểu thay đổi và/hoặc hoàn thiện nó tại những khoảng thời gian đồng nhất. | |
* Vì vậy, trong trường hợp này chúng ta có thể thực hiện decorator design pattern, cuối cùng code của chúng ta sẽ | |
* được cải thiện về chất lượng và tăng khả năng mở rộng của nó. | |
* | |
*/ | |
/** | |
* Vấn đề: | |
* Khi chúng ta thực hiện chức năng soạn nội dung mail. Thường chúng ta sẽ tạo 1 class với đầy đủ header, body, footer. | |
* Khi cần thay đổi nôi dung mail thường thi chúng ta sẽ tạo một class khác đẻ kế thừa và override lai ví dụ như Class christmasEmail | |
* Khi tới một sự kiện khác như Happy New Year chúng ta lại cần một nôi dung mail mới và ta làm điều tương tự với newYearEmail | |
* Vấn đề sẽ xảy ra khi ta cần gửi cả 2 nôi dung trong 1 mail. | |
*/ | |
class eMailBody | |
{ | |
private $header = 'This is email header'; | |
private $footer = 'This is email Footer'; | |
public $body = ''; | |
public function loadBody() | |
{ | |
$this->body .= "This is Main Email body.<br />"; | |
} | |
} | |
class christmasEmail extends eMailBody | |
{ | |
public function loadBody() | |
{ | |
parent::loadBody(); | |
$this->body .= "Added Content for Xmas<br />"; | |
} | |
} | |
$christmasEmail = new christmasEmail(); | |
$christmasEmail->loadBody(); | |
echo $christmasEmail->body; | |
print '<hr>'; | |
class newYearEmail extends eMailBody | |
{ | |
public function loadBody() | |
{ | |
parent::loadBody(); | |
$this->body .= "Added Content for New Year<br />"; | |
} | |
} | |
$newYearEmail = new newYearEmail(); | |
$newYearEmail->loadBody(); | |
echo $newYearEmail->body; | |
print '<hr>'; | |
print '<p>Decorator Pattern</p>'; | |
print '<hr>'; | |
/** | |
* Giải pháp: | |
* Decorator pattern (còn được gọi là Wrapper) | |
* là một design pattern cho phép các hành vi được thêm vào một đối tượng cụ thể, tĩnh hoặc động, | |
* mà không ảnh hưởng đến các hành vi của các đối tượng khác trong cùng một class. | |
*/ | |
interface eMailBodyDeco | |
{ | |
public function loadBody(); | |
} | |
/** | |
* Class eMail | |
* Main class: Đây là class chính nơi tạo ra default body của một email, cái mà tôi thường sử dụng để gửi email. | |
*/ | |
class eMailDeco implements eMailBodyDeco | |
{ | |
public function loadBody() | |
{ | |
echo "This is Main Email body.<br />"; | |
} | |
} | |
/** | |
* Class emailBodyDecorator | |
* Main decorator: Đây là decorator class chính của chúng ta, nó tham chiếu đến email class chính và thay đổi hành vi của mình khi cần thiết. | |
* Ở đây chúng ta đã định nghĩa một method trừu tượng loadBody mà sub decorator cần thực hiện việc thay đổi hành vi. | |
*/ | |
abstract class emailBodyDecorator implements eMailBodyDeco | |
{ | |
protected $emailBody; | |
public function __construct(eMailBodyDeco $emailBody) | |
{ | |
$this->emailBody = $emailBody; | |
} | |
abstract public function loadBody(); | |
} | |
/** | |
* Class christmasEmailBody | |
* Sub-Deco | |
*/ | |
class christmasEmailBody extends emailBodyDecorator | |
{ | |
public function loadBody() | |
{ | |
echo 'This is Extra Content for Christmas<br />'; | |
$this->emailBody->loadBody(); | |
} | |
} | |
/** | |
* Class newYearEmailBody | |
* Sub-deco | |
*/ | |
class newYearEmailBody extends emailBodyDecorator | |
{ | |
public function loadBody() | |
{ | |
echo 'This is Extra Content for New Year.<br />'; | |
$this->emailBody->loadBody(); | |
} | |
} | |
/** | |
* CALL DEMO | |
*/ | |
// Chay binh tnuong. | |
print '<p><strong>Noi dung binh thuong:</strong></p>'; | |
$email = new eMailDeco(); | |
$email->loadBody(); | |
// noi dung chirstmas. | |
print '<p><strong>Noi Dung christmas:</strong></p>'; | |
$email = new eMailDeco(); | |
$email = new christmasEmailBody($email); | |
$email->loadBody(); | |
// Noi Dung happy new year. | |
print '<p><strong>Noi Dung Happy new year:</strong></p>'; | |
$email = new eMailDeco(); | |
$email = new newYearEmailBody($email); | |
$email->loadBody(); | |
// Noi Dung ca 3 thong diep. | |
print '<p><strong>Noi Dung ca 3 thong diep:</strong></p>'; | |
$email = new eMailDeco(); | |
$email = new christmasEmailBody($email); | |
$email = new newYearEmailBody($email); | |
$email->loadBody(); | |
print '<hr><p><strong>Cach viet khac:</strong></p>'; | |
/** | |
* VD 2: | |
* | |
*/ | |
class Book | |
{ | |
private $author; | |
private $title; | |
function __construct($title_in, $author_in) | |
{ | |
$this->author = $author_in; | |
$this->title = $title_in; | |
} | |
function getAuthor() | |
{ | |
return $this->author; | |
} | |
function getTitle() | |
{ | |
return $this->title; | |
} | |
function getAuthorAndTitle() | |
{ | |
return $this->getTitle() . ' by ' . $this->getAuthor(); | |
} | |
} | |
class BookTitleDecorator | |
{ | |
protected $book; | |
protected $title; | |
public function __construct(Book $book_in) | |
{ | |
$this->book = $book_in; | |
$this->resetTitle(); | |
} | |
//doing this so original object is not altered | |
function resetTitle() | |
{ | |
$this->title = $this->book->getTitle(); | |
} | |
function showTitle() | |
{ | |
return $this->title; | |
} | |
} | |
class BookTitleExclaimDecorator extends BookTitleDecorator | |
{ | |
private $btd; | |
public function __construct(BookTitleDecorator $btd_in) | |
{ | |
$this->btd = $btd_in; | |
} | |
function exclaimTitle() | |
{ | |
$this->btd->title = "!" . $this->btd->title . "!"; | |
} | |
} | |
class BookTitleStarDecorator extends BookTitleDecorator | |
{ | |
private $btd; | |
public function __construct(BookTitleDecorator $btd_in) | |
{ | |
$this->btd = $btd_in; | |
} | |
function starTitle() | |
{ | |
$this->btd->title = Str_replace(" ", "*", $this->btd->title); | |
} | |
} | |
writeln('BEGIN TESTING DECORATOR PATTERN'); | |
writeln(''); | |
$patternBook = new Book('Gamma, Helm, Johnson, and Vlissides', 'Design Patterns'); | |
$decorator = new BookTitleDecorator($patternBook); | |
$starDecorator = new BookTitleStarDecorator($decorator); | |
$exclaimDecorator = new BookTitleExclaimDecorator($decorator); | |
writeln('showing title : '); | |
writeln($decorator->showTitle()); | |
writeln(''); | |
writeln('showing title after two exclaims added : '); | |
$exclaimDecorator->exclaimTitle(); | |
$exclaimDecorator->exclaimTitle(); | |
writeln($decorator->showTitle()); | |
writeln(''); | |
writeln('showing title after star added : '); | |
$starDecorator->starTitle(); | |
writeln($decorator->showTitle()); | |
writeln(''); | |
writeln('showing title after reset: '); | |
writeln($decorator->resetTitle()); | |
writeln($decorator->showTitle()); | |
writeln(''); | |
writeln('END TESTING DECORATOR PATTERN'); | |
function writeln($line_in) | |
{ | |
echo $line_in . "<br/>"; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment