0% found this document useful (0 votes)
5 views10 pages

PHP Structural Patterns Explained

The document provides examples of various structural design patterns in PHP, including Adapter, Bridge, Composite, Decorator, Facade, Flyweight, and Proxy. Each pattern is described with its purpose, how it works, and when to use it, along with relevant PHP code examples. These patterns help in organizing code, enhancing functionality, and managing complexity in software development.

Uploaded by

tunguyen1401
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
5 views10 pages

PHP Structural Patterns Explained

The document provides examples of various structural design patterns in PHP, including Adapter, Bridge, Composite, Decorator, Facade, Flyweight, and Proxy. Each pattern is described with its purpose, how it works, and when to use it, along with relevant PHP code examples. These patterns help in organizing code, enhancing functionality, and managing complexity in software development.

Uploaded by

tunguyen1401
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd

Structural Patterns - PHP Examples

6. Adapter
Mục đích: Chuyển đổi interface của class thành interface khác mà client
mong đợi.
Cách hoạt động: Wrapper class chuyển đổi interface không tương thích.
<?php
// Target Interface
interface PaymentGateway {
public function pay(float $amount): string;
}

// Adaptee (third-party library)


class StripeAPI {
public function makePayment(int $cents): string {
return "Stripe processed {$cents} cents";
}
}

// Adapter
class StripeAdapter implements PaymentGateway {
private $stripe;

public function __construct(StripeAPI $stripe) {


$this->stripe = $stripe;
}

public function pay(float $amount): string {


$cents = (int)($amount * 100);
return $this->stripe->makePayment($cents);
}
}

// Usage
$stripe = new StripeAPI();
$adapter = new StripeAdapter($stripe);
echo $adapter->pay(50.99); // Converts $50.99 to 5099 cents

Khi nào dùng:


 Tích hợp thư viện bên thứ 3
 Legacy code integration
 Ví dụ: Payment gateways, API wrappers, Database adapters
7. Bridge
Mục đích: Tách abstraction khỏi implementation để cả hai có thể thay đổi
độc lập.
Cách hoạt động: Composition thay vì inheritance.
<?php
// Implementation Interface
interface MessageSender {
public function send(string $message): string;
}

// Concrete Implementations
class EmailSender implements MessageSender {
public function send(string $message): string {
return "Email: {$message}";
}
}

class SMSSender implements MessageSender {


public function send(string $message): string {
return "SMS: {$message}";
}
}

// Abstraction
abstract class Notification {
protected $sender;

public function __construct(MessageSender $sender) {


$this->sender = $sender;
}

abstract public function notify(string $message): string;


}

// Refined Abstractions
class UrgentNotification extends Notification {
public function notify(string $message): string {
return $this->sender->send("[URGENT] " . $message);
}
}

class RegularNotification extends Notification {


public function notify(string $message): string {
return $this->sender->send($message);
}
}
// Usage
$emailNotification = new UrgentNotification(new EmailSender());
echo $emailNotification->notify("Server down!") . "\n";

$smsNotification = new RegularNotification(new SMSSender());


echo $smsNotification->notify("Hello!");

Khi nào dùng:


 Tránh explosion của subclasses
 Muốn thay đổi implementation runtime
 Ví dụ: UI themes, Database drivers, Notification systems

8. Composite
Mục đích: Tổ chức objects thành cấu trúc cây để xử lý individual và
composite objects giống nhau.
Cách hoạt động: Tree structure với leaf và composite nodes.
<?php
// Component Interface
interface FileSystemComponent {
public function getSize(): int;
public function getName(): string;
}

// Leaf
class File implements FileSystemComponent {
private $name;
private $size;

public function __construct(string $name, int $size) {


$this->name = $name;
$this->size = $size;
}

public function getSize(): int {


return $this->size;
}

public function getName(): string {


return $this->name;
}
}

// Composite
class Directory implements FileSystemComponent {
private $name;
private $children = [];

public function __construct(string $name) {


$this->name = $name;
}

public function add(FileSystemComponent $component) {


$this->children[] = $component;
}

public function getSize(): int {


$total = 0;
foreach ($this->children as $child) {
$total += $child->getSize();
}
return $total;
}

public function getName(): string {


return $this->name;
}
}

// Usage
$root = new Directory("root");
$root->add(new File("[Link]", 100));
$root->add(new File("[Link]", 200));

$subDir = new Directory("documents");


$subDir->add(new File("[Link]", 500));
$root->add($subDir);

echo "Total size: " . $root->getSize() . " bytes"; // 800

Khi nào dùng:


 File systems
 Menu structures
 Organization hierarchies
 Ví dụ: Category trees, Comment threads, UI components

9. Decorator
Mục đích: Thêm chức năng mới cho object động mà không thay đổi
structure.
Cách hoạt động: Wrapping objects với decorators.
<?php
// Component Interface
interface Coffee {
public function getCost(): float;
public function getDescription(): string;
}

// Concrete Component
class SimpleCoffee implements Coffee {
public function getCost(): float {
return 10;
}

public function getDescription(): string {


return "Simple coffee";
}
}

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

public function __construct(Coffee $coffee) {


$this->coffee = $coffee;
}
}

// Concrete Decorators
class MilkDecorator extends CoffeeDecorator {
public function getCost(): float {
return $this->coffee->getCost() + 2;
}

public function getDescription(): string {


return $this->coffee->getDescription() . ", milk";
}
}

class SugarDecorator extends CoffeeDecorator {


public function getCost(): float {
return $this->coffee->getCost() + 1;
}

public function getDescription(): string {


return $this->coffee->getDescription() . ", sugar";
}
}

// Usage
$coffee = new SimpleCoffee();
echo $coffee->getDescription() . " = $" . $coffee->getCost() . "\n";

$coffeeWithMilk = new MilkDecorator($coffee);


echo $coffeeWithMilk->getDescription() . " = $" . $coffeeWithMilk-
>getCost() . "\n";

$coffeeWithMilkAndSugar = new SugarDecorator($coffeeWithMilk);


echo $coffeeWithMilkAndSugar->getDescription() . " = $" .
$coffeeWithMilkAndSugar->getCost();

Khi nào dùng:


 Thêm features động
 Alternative cho subclassing
 Ví dụ: Middleware, Stream filters, UI components

10. Facade
Mục đích: Cung cấp interface đơn giản cho hệ thống phức tạp.
Cách hoạt động: Unified interface che giấu complexity.
<?php
// Complex subsystems
class VideoFile {
private $filename;

public function __construct(string $filename) {


$this->filename = $filename;
}

public function getFilename(): string {


return $this->filename;
}
}

class CodecFactory {
public function extract(VideoFile $file): string {
return "Extracting codec from {$file->getFilename()}";
}
}

class BitrateReader {
public function read(VideoFile $file): string {
return "Reading bitrate of {$file->getFilename()}";
}
}
class AudioMixer {
public function fix(VideoFile $file): string {
return "Fixing audio of {$file->getFilename()}";
}
}

// Facade
class VideoConverter {
public function convert(string $filename, string $format): string
{
$file = new VideoFile($filename);
$codec = new CodecFactory();
$bitrate = new BitrateReader();
$audio = new AudioMixer();

$result = [];
$result[] = $codec->extract($file);
$result[] = $bitrate->read($file);
$result[] = $audio->fix($file);
$result[] = "Converting to {$format}";

return implode("\n", $result);


}
}

// Usage
$converter = new VideoConverter();
echo $converter->convert("video.mp4", "avi");

Khi nào dùng:


 Simplify complex APIs
 Provide entry point to subsystem
 Ví dụ: Library wrappers, Service layers, Framework facades

11. Flyweight
Mục đích: Tiết kiệm bộ nhớ bằng cách chia sẻ data giữa nhiều objects.
Cách hoạt động: Tách intrinsic (shared) và extrinsic (unique) state.
<?php
// Flyweight
class TreeType {
private $name;
private $color;
private $texture;

public function __construct(string $name, string $color, string


$texture) {
$this->name = $name;
$this->color = $color;
$this->texture = $texture;
}

public function render(int $x, int $y): string {


return "Drawing {$this->name} tree at ({$x}, {$y})";
}
}

// Flyweight Factory
class TreeFactory {
private static $treeTypes = [];

public static function getTreeType(string $name, string $color,


string $texture): TreeType {
$key = md5($name . $color . $texture);

if (!isset(self::$treeTypes[$key])) {
self::$treeTypes[$key] = new TreeType($name, $color,
$texture);
}

return self::$treeTypes[$key];
}

public static function getCount(): int {


return count(self::$treeTypes);
}
}

// Context
class Tree {
private $x;
private $y;
private $type;

public function __construct(int $x, int $y, TreeType $type) {


$this->x = $x;
$this->y = $y;
$this->type = $type;
}

public function render(): string {


return $this->type->render($this->x, $this->y);
}
}
// Usage
$forest = [];
$forest[] = new Tree(10, 20, TreeFactory::getTreeType("Oak", "Green",
"Rough"));
$forest[] = new Tree(30, 40, TreeFactory::getTreeType("Oak", "Green",
"Rough"));
$forest[] = new Tree(50, 60, TreeFactory::getTreeType("Pine", "Dark
Green", "Smooth"));

foreach ($forest as $tree) {


echo $tree->render() . "\n";
}

echo "Total tree types created: " . TreeFactory::getCount(); // Only 2


instead of 3

Khi nào dùng:


 Nhiều objects tương tự nhau
 Memory optimization
 Ví dụ: Game objects, Text formatting, Caching

12. Proxy
Mục đích: Cung cấp placeholder/surrogate cho object khác để kiểm soát
access.
Cách hoạt động: Wrapper kiểm soát access đến real object.
<?php
// Subject Interface
interface Image {
public function display(): string;
}

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

public function __construct(string $filename) {


$this->filename = $filename;
$this->loadFromDisk();
}

private function loadFromDisk(): void {


echo "Loading {$this->filename} from disk...\n";
}

public function display(): string {


return "Displaying {$this->filename}";
}
}

// Proxy
class ProxyImage implements Image {
private $filename;
private $realImage = null;

public function __construct(string $filename) {


$this->filename = $filename;
}

public function display(): string {


// Lazy loading
if ($this->realImage === null) {
$this->realImage = new RealImage($this->filename);
}
return $this->realImage->display();
}
}

// Usage
$image1 = new ProxyImage("[Link]");
$image2 = new ProxyImage("[Link]");

// Image not loaded yet


echo $image1->display(); // Loads and displays
echo $image1->display(); // Just displays (already loaded)

Các loại Proxy:


 Virtual Proxy: Lazy loading (như ví dụ trên)
 Protection Proxy: Access control
 Remote Proxy: Đại diện cho remote object
 Caching Proxy: Cache results
Khi nào dùng:
 Lazy initialization
 Access control
 Logging/monitoring
 Ví dụ: ORM lazy loading, API rate limiting, Image loading

You might also like