不同设计模式实现源码

分类: 源代码 > PHP

一、简单工厂模式【就是传递不同的参数生成不同的对象】

案例:想象一下,你正在建造一座房子而且需要几扇房门,如果每次需要房门的时候,不是用工厂制造的房门,而是穿上木匠服,然后开始自己制造房门,将会搞得一团糟

概述: 简单工厂模式只是为客户端创建实例,而不将任何实例化逻辑暴露给客户端

简介:在面向对象程序设计中,工厂通常是一个用来创建其他对象的对象。通常来讲,工厂是指某个功能或方法,此功能或方法返回不同类型的对象或者类的某个方法调用,返回的东西看起来是新的

interface Door {
    public function getWidth();
    public function getHeight();
}

class WoodenDoor implements Door {
    protected $width;
    protected $height;

    public function __construct($width, $height) {
        $this->width = $width;
        $this->height = $height;
    }

    public function getWidth() {
        return $this->width;
    }
    
    public function getHeight() {
        return $this->height;
    }
}
class DoorFactory {
    public static function makeDoor($width, $height) {
        return new WoodenDoor($width, $height);
    }
}

$door = DoorFactory::makeDoor(100, 200);
echo ($door->getWidth() . '*' . $door->getHeight());

二、工厂方法模式

案例:考虑招聘经理的情况。一个人不可能应付所有职位的面试,对于空缺职位,招聘经理必须委派不同的人去面试。

概述: 工厂方法模式提供了一种将实例化逻辑委托给子类的方法

简介:

    1. 在基于类的编程中,工厂方法模式是一种使用了工厂方法的创建型设计模式,在不指定对象具体类型的情况下,处理创建对象的问题。

    2. 创建对象不是通过调用构造器而是通过调用工厂方法(在接口中指定工厂方法并在子类中实现或者在基类中实现,随意在派生类中重写)来完成。

interface interviewer {
    public function askQuestions();
}

class Developer implements interviewer {
    public function askQuestions() {
        echo 'Asking about design patterns!';
    }
}

class Producter implements interviewer {
    public function askQuestions() {
        echo 'Asking about product!';
    }
}

abstract class HiringManager {
    abstract public function makeInterviewer();

    public function taskInterviewer() {
        $interview = $this->makeInterviewer();
        $interview->askQuestions();
    }
}

class DeveloperManager extends HiringManager {
    public function makeInterviewer() {
        return new Developer();
    }
}

class ProducterManage extends HiringManager {
    public function  makeInterviewer() {
        return new Producter();
    }
}

$devManager = new DeveloperManager();
$devManager->taskInterviewer();
$proManager = new ProducterManage();
$proManager->taskInterviewer();

三、抽象工厂模式

案例:扩展一下简单工厂模式中的房门例子。基于所需,你可能需要从木门店获取木门,从铁门店获取铁门或者从相关的门店获取 PVC 门。进一步讲,你可能需要不同种类的专家来安装房门,比如木匠安装木门,焊接工安装铁门等等。正如你所料,房门有了依赖,木门需要木匠,铁门需要焊接工

概述: 一组工厂的工厂:将相关或者互相依赖的单个工厂聚集在一起,而不指定这些工厂的具体类。

简介:抽象工厂模式提供了一种方式,这种方式可以封装一组具有共同主题的个体工厂,而不指定这些工厂的具体类。

interface Door {
    public function getDescription();
}

class WoodenDoor implements Door {
    public function getDescription() {
        echo 'WoodenDoor';
    }
}

class IronDoor implements Door {
    public function getDescription() {
        echo 'IronDoor';
    }
}

interface DoorInstall {
    public function getDescription();
}

class WoodenDoorInstall implements DoorInstall {
    public function getDescription() {
        echo 'WoodenDoorInstall';
    }
}

class IronDoorInstall implements DoorInstall {
    public function getDescription() {
        echo 'IronDoorInstall';
    }
}

interface DoorFactory {
    public function makeDoor();

    public function makeDoorInstall();
}

class WoodenDoorFactory implements DoorFactory {
    public function makeDoor() {
        return new WoodenDoor();
    }

    public function makeDoorInstall() {
        return new WoodenDoorInstall();
    }
}

$woodenFactory = new WoodenDoorFactory();
echo $woodenFactory->makeDoor()->getDescription();
echo $woodenFactory->makeDoorInstall()->getDescription();

四、生成器模式

案例:想象一下你在 Hardee’s 餐厅点了某个套餐,比如「大 Hardee 套餐」,然后工作人员会正常出餐,这是简单工厂模式。但是在很多情况下,创建逻辑可能涉及到更多步骤。比如,你想要一个定制的 Subway 套餐,对于你的汉堡如何制作有几个选项可供选择,比如你想要什么类型的酱汁?你想要什么奶酪? 在这种情况下,建造者模式便可以派上用场。

概述: 允许创建不同风格的对象,同时避免构造器污染。当创建多种风格的对象时或者创建对象时涉及很多步骤,可以使用生成器模式

简介:生成器模式是一种对象创建软件设计模式,其目的是找到重叠构造器反面模式的解决方案。

class Door {
    protected $length;
    protected $width;
    protected $height;

    public function __construct($custom) {
        $this->length = $custom->length;
        $this->width = $custom->width;
        $this->height = $custom->height;
    }

    public function __toString() {
        echo $this->length . '*' . $this->width . '*' . $this->height;
    }
}

class customDoor {
    public $length;
    public $width;
    public $height;

    public function __construct() {
    }

    public function setLength($length) {
        $this->length = $length;
        return $this;
    }

    public function setWidth($width) {
        $this->width = $width;
        return $this;
    }

    public function setHeight($height) {
        $this->height = $height;
        return $this;
    }
}

$custom = (new customDoor)->setLength(10)->setWidth(10)->setHeight(10);
$door = new Door($custom);
echo $door;

五、单例模式

案例:多次请求数据库只需要一个连接对象

概述: 允许创建不同风格的对象,同时避免构造器污染。当创建多种风格的对象时或者创建对象时涉及很多步骤,可以使用生成器模式

简介:生成器模式是一种对象创建软件设计模式,其目的是找到重叠构造器反面模式的解决方案。

优点:1. 在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例;2. 避免对资源的多重占用

缺点:没有接口,不能继承,与单一职责原则冲突

final class Door {
    private static $instance;

    private function __construct() {
    }

    public static function getInstance() {
        if (!self::$instance) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    public function get() {
        echo 'get';
    }

    private function __clone() {
        // Disable cloning
    }
}

Door::getInstance()->get();
echo '<br />';

$door1 = Door::getInstance();
$door2 = Door::getInstance();
var_dump($president1 === $president2);

六、适配器模式

案例:考虑这样一个场景,你的存储卡中有一些照片,你需要将其传输到计算机。为此,你需要某种与计算机端口兼容的适配器,以便将存储卡连接到计算机上。在这种情况下,读卡器就是适配器。另外一个例子就是大名鼎鼎的电源适配器:一个三脚插头不能连接到双插头插座,需要使用电源适配器使其与双插头插座兼容。另外一个例子是译者将一个人说的话翻译给另一个人。

概述: 配器模式可以将不兼容的对象包装成适配器来适配其它类。

简介:在软件工程中,适配器模式是允许将现有类的接口用作另一个类接口的软件设计模式。它通常用于现有类与其他类的协作,而无需修改现有类的代码。

interface Lion {
    public function roar();
}

class AfricanLion implements Lion {
    public function roar() {
        echo 'AfricanLion';
    }
}

class AsianLion implements Lion {
    public  function roar() {
        echo 'AsianLion';
    }
}

// 猎人希望可以狩猎任何实现 Lion 接口的狮子
class Hunter {
    public function hunt(Lion $lion) {
        $lion->roar();
    }
}

class WildDog {
    public function bark() {
        echo 'WildDog';
    }
}

class WildDogAdapter implements Lion {
    protected $dog;

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

    public function roar() {
        return $this->dog->bark();
    }
}

$dog = new WildDog();
$dogAdapter = new WildDogAdapter($dog);

$hunter = new Hunter();
$hunter->hunt($dogAdapter);

六、策略模式

简介:传递不同的参数调用不同的策略

<?php
class Walk{
    public function way(){
        echo "walk";
    }
}
class Bus{
    public function way(){
        echo "bus";
    }
}
//传递的参数为对象传递不一样的对象会调用不同的方法
class Student{
    public function how($obj){
        $obj->way();
    }
}

七、装饰器模式

动态地给一个对象添加一些额外的职责

<?php
class BaseArt{
    protected $content;//存放文章内容
    protected $art = null;//存放文章对象
    public function __construct($content){
        $this->content = $content; //构造基础文章
    }
    public function decorator(){
        return $this->content;//返回文章内容
    }
}

class BianArt extends BaseArt{ //创建小编类
    public function __construct(BaseArt $art){
        $this->art = $art;//实例化小编类时需要传递基础文章类对象作为参数
        $this->decorator();//返回修饰完成之后的文章
    }
    public function decorator(){
        return $this->content = $this->art->decorator() . '小编摘要'; //返回构造函数是传递过来的文章类的文章在加上修饰的部分赋值给当前对象的文章内容并返回。
    }
}

class SEOArt extends BaseArt{
    public function __construct(BaseArt $art){
        $this->art = $art;
        $this->decorator();
    }
    public function decorator(){
        return $this->content = $this->art->decorator() . 'SEO';
    }
}
$a = new BaseArt('文章');
echo $a->decorator(); //文章
	
$b = new BianArt($a);
echo $b->decorator(); //文章小编摘要
	
$c = new SEOArt($b);
echo $c->decorator();//文章小编摘要SEO
	
$d = new SEOArt($a);
echo $d->decorator();//文章SEO

来源:原创 发布时间:2022-07-13 12:34:59