Design Pattern là gì? Structural Patterns ? (P2)



    Structural Patterns

    1. Adapter (Ổn định)
    Giải thích: Mẫu Adapter cho phép bạn chuyển đổi giao diện của một lớp thành một giao diện khác mà các đối tượng khác có thể sử dụng.
    Ví dụ:
    <?
    // Adapter interface
    interface MediaPlayer {
    public function play($audioType, $fileName);
    }

    // Existing class with incompatible interface
    class Mp3Player {
    public function playMp3($fileName) {
    echo "Playing MP3 file: $fileName\n";
    }
    }

    // Adapter class
    class MediaAdapter implements MediaPlayer {
    private $mp3Player;

    public function __construct() {
    $this->mp3Player = new Mp3Player();
    }

    public function play($audioType, $fileName) {
    if ($audioType == 'mp3') {
    $this->mp3Player->playMp3($fileName);
    }
    }
    }

    // Client code
    $mediaAdapter = new MediaAdapter();
    $mediaAdapter->play('mp3', 'song.mp3');

    2. Bridge (Cầu) 

    Giải thích: Mẫu Bridge tách biệt một lớp trừu tượng từ việc triển khai của nó, cho phép chúng hoạt động độc lập với nhau.

    Ví dụ PHP:
    <? // Abstraction
    abstract class Shape {
    protected $color;

    public function __construct($color) {
    $this->color = $color;
    }

    abstract public function draw();
    }

    // Implementor
    interface DrawAPI {
    public function drawCircle($radius, $x, $y);
    }

    // Concrete Implementor
    class RedCircle implements DrawAPI {
    public function drawCircle($radius, $x, $y) {
    echo "Drawing a red circle at ($x, $y) with radius $radius\n";
    }
    }

    // Refined Abstraction
    class Circle extends Shape {
    private $x, $y, $radius;

    public function __construct($x, $y, $radius, $color, DrawAPI $drawAPI) {
    parent::__construct($color);
    $this->x = $x;
    $this->y = $y;
    $this->radius = $radius;
    $this->drawAPI = $drawAPI;
    }

    public function draw() {
    $this->drawAPI->drawCircle($this->radius, $this->x, $this->y);
    }
    }

    // Client code
    $redCircle = new Circle(100, 100, 10, 'red', new RedCircle());
    $redCircle->draw();



    3. Composite (Tổ hợp)
    Giải thích: Mẫu Composite cho phép bạn xây dựng cấu trúc cây đối tượng dạng cây để biểu diễn các mối quan hệ phân cấp giữa các đối tượng.
    Ví dụ PHP:

    <? // Abstraction
    // Component
    interface Employee {
    public function showDetails();
    }

    // Leaf
    class Developer implements Employee {
    private $name;
    private $position;

    public function __construct($name, $position) {
    $this->name = $name;
    $this->position = $position;
    }

    public function showDetails() {
    echo "Developer: $this->name, Position: $this->position\n";
    }
    }

    // Composite
    class Manager implements Employee {
    private $name;
    private $position;
    private $subordinates = [];

    public function __construct($name, $position) {
    $this->name = $name;
    $this->position = $position;
    }

    public function add(Employee $employee) {
    $this->subordinates[] = $employee;
    }

    public function showDetails() {
    echo "Manager: $this->name, Position: $this->position\n";
    foreach ($this->subordinates as $subordinate) {
    $subordinate->showDetails();
    }
    }
    }

    // Client code
    $developer1 = new Developer('Alice', 'Front-end Developer');
    $developer2 = new Developer('Bob', 'Back-end Developer');
    $manager = new Manager('Charlie', 'Project Manager');
    $manager->add($developer1);
    $manager->add($developer2);
    $manager->showDetails();



    4. Decorator (Trang trí)
    Giải thích: Mẫu Decorator cho phép bạn thêm chức năng mới cho đối tượng mà không cần sửa đổi mã nguồn gốc của nó.
    Ví dụ PHP:
    <? // Component
    interface Coffee {
    public function cost();
    }

    // Concrete Component
    class SimpleCoffee implements Coffee {
    public function cost() {
    return 5; // Giá cà phê đơn giản
    }
    }

    // Decorator
    abstract class CoffeeDecorator implements Coffee {
    protected $coffee;

    public function __construct(Coffee $coffee) {
    $this->coffee = $coffee;
    }

    public function cost() {
    return $this->coffee->cost();
    }
    }

    // Concrete Decorator
    class MilkDecorator extends CoffeeDecorator {
    public function cost() {
    return parent::cost() + 2; // Cộng thêm giá sữa
    }
    }

    // Concrete Decorator
    class SugarDecorator extends CoffeeDecorator {
    public function cost() {
    return parent::cost() + 1; // Cộng thêm giá đường
    }
    }

    // Client code
    $coffee = new SimpleCoffee();
    $coffeeWithMilk = new MilkDecorator($coffee);
    $coffeeWithMilkAndSugar = new SugarDecorator($coffeeWithMilk);

    echo "Cost of simple coffee: {$coffee->cost()} USD\n";
    echo "Cost of coffee with milk: {$coffeeWithMilk->cost()} USD\n";
    echo "Cost of coffee with milk and sugar: {$coffeeWithMilkAndSugar->cost()} USD\n";



    5. Facade (Gương mặt)
    Giải thích: 
    Mẫu Facade cung cấp một giao diện đơn giản cho một hệ thống phức tạp, giúp che đi sự phức tạp và tạo điểm truy cập dễ dàng cho client.
    Ví dụ PHP:
    <?
    // Subsystem
    class CPU {
    public function freeze() { echo "CPU freeze\n"; }
    public function jump($address) { echo "CPU jump to $address\n"; }
    public function execute() { echo "CPU execute\n"; }
    }

    class Memory {
    public function load($position, $data) { echo "Memory load data into position $position: $data\n"; }
    }

    class HardDrive {
    public function read($sector, $size) { echo "Hard Drive read sector $sector with size $size\n"; }
    }

    // Facade
    class ComputerFacade {
    private $cpu;
    private $memory;
    private $hardDrive;

    public function __construct() {
    $this->cpu = new CPU();
    $this->memory = new Memory();
    $this->hardDrive = new HardDrive();
    }

    public function start() {
    $this->cpu->freeze();
    $this->memory->load(0, 'Boot data');
    $this->cpu->jump(1);
    $this->cpu->execute();
    }
    }

    // Client code
    $computer = new ComputerFacade();
    $computer->start();



    6. Flyweight (Nhẹ)
    Giải thích: Mẫu Flyweight giúp bạn chia sẻ thông tin chung giữa nhiều đối tượng để giảm bộ nhớ hoặc tối ưu hóa hiệu suất.
    Ví dụ PHP:
    <?
    // Flyweight interface
    interface Coffee {
    public function serve();
    }

    // Concrete Flyweight
    class Espresso implements Coffee {
    public function serve() {
    return "Espresso";
    }
    }

    // Flyweight Factory
    class CoffeeFactory {
    private $coffeeTypes = [];

    public function getCoffee($type) {
    if (!isset($this->coffeeTypes[$type])) {
    $this->coffeeTypes[$type] = new $type();
    }
    return $this->coffeeTypes[$type];
    }
    }

    // Client code
    $factory = new CoffeeFactory();
    $espresso1 = $factory->getCoffee('Espresso');
    $espresso2 = $factory->getCoffee('Espresso');

    echo $espresso1->serve() . " is the same as " . $espresso2->serve() . "\n";



    7. Proxy (Ủy quyền)
    Giải thích: Mẫu Proxy cho phép bạn cung cấp một đối tượng đại diện để kiểm soát quyền truy cập đối tượng gốc hoặc thực hiện các hành động bổ sung trước hoặc sau khi gọi phương thức của đối tượng gốc.
    Ví dụ PHP:
    <?
    // Subject
    interface Image {
    public function display();
    }

    // Real Subject
    class RealImage implements Image {
    private $filename;

    public function __construct($filename) {
    $this->filename = $filename;
    $this->loadImage();
    }

    private function loadImage() {
    echo "Loading image: $this->filename\n";
    }

    public function display() {
    echo "Displaying image: $this->filename\n";
    }
    }

    // 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);
    }
    $this->realImage->display();
    }
    }

    // Client code
    $image1 = new ProxyImage('image1.jpg');
    $image2 = new ProxyImage('image2.jpg');

    // Image1 will be loaded and displayed, Image2 will only be loaded and displayed when needed.
    $image1->display();
    $image2->display();



    Đăng nhận xét

    Mới hơn Cũ hơn