8只设计模式

本文介绍了8种常见的设计模式,包括单例模式、工厂模式、注册模式、适配器模式、策略模式、观察者模式、原型模式和装饰器模式。这些模式旨在减少代码耦合,提高系统的可扩展性和复用性。通过实例解析,帮助读者掌握如何在实际开发中应用这些模式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 单例模式

防止多次调用导致new多次(如比较常见的数据库连接),防止服务去当场去世

<?php

/**
 * Class Demo
 * 4个私有
 */
class Demo
{
    //保存实例的成员变量
    private static $_instance;

    //构造方法(设为私用,不许再次调用)
    private function _construct(){

    }

    //克隆方法(设为私用,不许再次调用)
    private function _clone(){

    }

    //获取实例
    static public function getInstance(){
        //如果没有自我实例
        if(!(self::$_instance instanceof self)){
            self::$_instance = new self();
        }
        return self::$_instance;
    }

}

//调用
$demo = Demo::getInstance();

2.工厂模式

工厂模式就像一个工厂的生产方式,只要能生产,不会理会是哪个只员工干活,员工随时可以替换或者更改,意义主要是减少代码之间的耦合度

Personnel.php

/**
 * Class Personnel
 * 员工
 */
class Personnel
{
    //熬夜通宵玩命加班ing...
    public function keepWork(){
        echo '996';
    }

}

Factory.php

/**
 * Class Factory
 * 某大型养猪厂
 */
class Factory
{
    //我有个想法()
    static public function BigPlane(){
        //某个员工执行(实例化类,返回整个类)
        $personnel = new Personnel();
        return $personnel;
    }

}

Boss.php

//找到工厂实现
$Plane = Factory::BigPlane();
//工厂某员工实现
$Plane->keepWork();

3.注册模式

注册模式定义对象到全局,保存一个静态的数组,方便获取,生存周期是静态参数模式,与全局参数生产周期相同

class register{

    //注册树
    protected static $obj;

    //挂到树上(自挂东南枝)
    function set($alias,$object){
        self::$obj[$alias] = $object;
    }

    //获取树上对象
    static function get($name){
        return self::$obj[$name];
    }

    //从树上摘除对象
    function _unset($alias){
        unset(self::$obj[$alias]);
    }
}

4.适配器模式

基本上采用接口类定义调用方法,在以需要的多种形式实现。如多种数据库的调用,实际连接数据库的代码不一样,但是使用数据库的步骤一样,而适配器就是把规范调用数据库的形式。适配器模式其实和转接口相似,如usb转接器,把usb转为typc-c或者usb接口。适配器模式和接口类搭配使用,所以比较需要了解接口类的使用。
总结:其实就是把一个重复或者比较复杂的功能拆分,减少耦合,方便将来扩展

//声明接口类,定义子类需拥有以下方法
interface IDatebase
{
    //连接数据库
    public function conncet($host, $username, $password, $database);
    //操作
    public function query($sql);
    //关闭
    public function close();
}

//mysql数据库连接适配器
class Mysql implements IDatebase
{
    public function conncet($host, $username, $password, $database)
    {
        //省略
    }
    public function query($sql)
    {
        //省略
    }
    public function close()
    {
        //省略
    }
}
//sqlite数据库连接适配器
class Sqliter implements IDatebase{

    public function conncet($host, $username, $password, $database)
    {
        // TODO: Implement conncet() method.
    }
    public function query($sql)
    {
        // TODO: Implement query() method.
    }
    public function close()
    {
        // TODO: Implement close() method.
    }

}

$host     = 'localhost';
$username = 'root';
$password = 'root';
$database = 'mysql';
//假如需要连接mysql而非sqlite
$mysql = new Mysql();
$mysql->conncet($host, $username, $password, $database);

5.策略模式

策略模式是封装算法的(算法可以比作解决问题的方法,例如商城的满减或者打折、满相对数量打折等等促销手段,当年又菜又咸的我去面试以为算法是算法是数学公式…)

在这里插入图片描述

abstract class StratergyAbstract{

    //优惠需要的方案
    public abstract function DoAction();
}

//满减策略
class MnaJian extends StratergyAbstract{
    public function DoAction()
    {
        // TODO: Implement DoAction() method.
    }
}

//打折策略
class DaZhe extends StratergyAbstract{
    public function DoAction()
    {
        // TODO: Implement DoAction() method.
    }
}

//策略工厂类,(选择策略的类)
class StrategyFind{

    private $strategy_mode;

    //重载选择策略
    public function _construct($mode){
        $this->strategy_mode = $mode;
    }

    //执行策略方法
    public function get($money){
        $this->strategy_mode->doAction();
    }
}

//选择了满减策略
$model = new StrategyFind(new MnaJian());
$model->get(1000);

其实从上面代码看出,如果需要调用某某策略,不知道有什么策略是很难选择用什么策略的,所以调用之前需要只要有哪些策略。
策略模式转自该地址

6.观察者模式

观察者模式代码主要分为两块,事件部分和观察部分,当被观察者发生变化,就触发事件,例如登录功能是被观察者,一旦用户发生登录,添加日志,弹出欢迎语句等等,也算是触发的事件,这样有利于增加事件,从而不影响原有的事件,更方便策划大大找抽。

abstract class observer{

    //目标人物事件
    public abstract function update();
}

//事件类型A
class observerA extends observer{

    public function update()
    {
        // TODO: Implement update() method.
    }

    //不够可以自已加饭
    public function addFan(){

    }
}

//事件类型B
class observerB extends observer{

    public function update()
    {
        // TODO: Implement update() method.
    }

}

//通知事件触发类
class EventBase{

    private static $objectlist;

    //添加触发事件
    public function add($object){
        self::$objectlist[] = $object;
    }

    //通知触发指定事件
    public function ontify(){
        foreach (self::$objectlist as $object)
        {
            $object->update();
        }
    }
}

//发生事件----

$EventBase = new EventBase();
//添加事件
$EventBase->add(new observerA());
$EventBase->add(new observerB());

//通知事件触发
$EventBase->ontify();

7.原型模式

克隆对象,避免创建新对象时的消耗,适用于创建大对象(这时我想到了享元模式,与原型模式相似,不过享元模式是为了避免多个对象)。顺便提下,php里有个魔术函数_clone()可以克隆对象

abstract class Prototype{
    abstract function cloned();
}

class Plane extends Prototype{

    public $color;

    public function operating(){

    }

    //复制自已,返回
    public function cloned()
    {
        return clone $this;
    }
}

//业务场景
$plane  = new Plane();

$plane1 = $plane->color('Blue');
$plan2  = $plane->cloned();

8.装饰器模式

需要在不影响其他对象的情况下,以动态、透明的方式给对象添加职责。
如果不适合使用子类来进行扩展的时候,可以考虑使用装饰器模式。

//装饰接口类
interface decorator{
    public function before_Draw();
    public function after_Draw();
}

//雪花装饰类
class Snowflake_Decorator implements decorator {

    public function before_Draw()
    {
        echo '挂上雪花饰品';
    }

    public function after_Draw()
    {
        echo'系紧绳子,固定雪花饰品';
    }

}

//圣诞老人小玩偶装饰类
class SantaClaus_Decorator implements decorator {
    public function before_Draw()
    {
        echo '挂上圣诞老人玩偶';
    }
    public function after_Draw()
    {
        echo '在圣诞老人的背包里塞进入红包';
    }
}

//圣诞树类
class ChristmasTree{

    private $decorators = [];

    //添加装饰品
    public function addDecoratoe(decorator $decorator)
    {
        $this->decorators[] = $decorator;
    }

    public function beforeDraw()
    {
        foreach ($this->decorators as $decorator){
            $decorator->before_Draw();
        }
    }

    public function afterDraw()
    {
        $decorator = array_reverse($this->decorators);
        foreach ($this->decorators as $decorator){
            $decorator->after_Draw();
        }
    }

    public function pendant()
    {
        $this->beforeDraw();
        $this->afterDraw();
    }


}

//只挂上雪花装饰
$ChristmasTree = new ChristmasTree();
$ChristmasTree->addDecoratoe(new Snowflake_Decorator());
$ChristmasTree->pendant();

//我全都要挂
$ChristmasTree = new ChristmasTree();
$ChristmasTree ->addDecoratoe(new Snowflake_Decorator());
$ChristmasTree ->addDecoratoe(new SantaClaus_Decorator());
$ChristmasTree ->pendant();

参考地址:https://www.cnblogs.com/yuanwanli/p/8796402.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值