[浅谈设计模式(二)] 让你一分钟读懂设计模式

碎碎念

在此分享的是我学习中的一些理解和总结,大家一起学习和共勉,希望对大家有所帮助;在大家看了以后,觉得我理解和总结有不到位或者不对的地方希望大家在留言区指出,我会及时修改,感谢!!!

前言:

这篇文章接续上一篇文章,上一篇主要分享的是设计模式-工厂模式,篇幅较长,如果有没有看过第一篇文章的朋友,下面有链接(浅谈设计模式(一))。该篇主要分享的设计模式是:单例模式和适配器模式。分享的每个设计模式都会通过3个方面(定义、举例说明、代码说明)进行讲解和说明。

【浅谈设计模式(一)】:博客:[浅谈设计模式(一)] 让你一分钟读懂设计模式

正文:

单例模式

1.定义:保证一个类仅有一个实例,并提供一个访问它的全局访问点。
2.举例说明:Windows 是多进程多线程的,在操作一个文件的时候,就不可避免地出现多个进程或线程同时操作一个文件的现象,所以所有文件的处理必须通过唯一的实例来进行。 或者一些设备管理器常常设计为单例模式,比如一个电脑有两台打印机,在输出的时候就要处理不能两台打印机打印同一个文件。
3.代码说明:

 <?php 
  class Singleton
  {
      private static $instance;
      //私有构造方法,禁止使用new创建对象
      private function __construct(){}
      //实例化化对象
      public static function getInstance(){
          if (!isset(self::$instance)) {   //判断是否实例化
              self::$instance = new self;   
          }
          return self::$instance;
      }
      //将克隆方法设为私有,禁止克隆对象
      private function __clone(){}

      public function operation()
      {
          echo "这里可以添加其他方法和操作 <br>";
      }
  }

  $shiyanlou = Singleton::getInstance();
  $shiyanlou->operation();

这里多补充一点单例模式的特点:
(1)单例类只能有一个实例。
(2)单例类必须自己创建自己的唯一实例。
(3)单例类的构造函数定义为private私有方法。
(4)单例类必须自行向整个系统提供这个实例。

适配器模式

个人理解:通俗点就是使用不同的方法名实现同一个功能
1.定义:将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
2.举例说明:小明有一辆遥控玩具汽车,它可以向前进,向后退,左拐,右拐(这里只以前进作为举例)。小明对遥控汽车进行前进操作,只需要调用forward()方法即可。这时候小明的基友小李和妹子小唐也想要操作玩具汽车前进,但小李他只会调用didForward()方法,小唐她只会调用doForward()。这个时候如何才能让小李实现对遥控汽车的前进操作呢?要实现它,可以使用适配器模式来实现。(即:如何让小李和小唐在不改变调用方法的情况下,也可以操作玩具车前进)

<说明>(这里有点抽象,结合下面代码进行理解)
(1)目标(Target)角色:定义客户端使用的与特定领域相关的接口,这也就是我们所期待得到的这里的小李和小唐要求实现的相关接口。我们可以看到LiTarget和TangTarget必须实现didForward和doForward方法
(2)源(Adaptee)角色:需要进行适配的接口,这里的源角色是小明的Car实例
(3)适配器(Adapter)角色:对Adapter的接口与Target接口进行适配;适配器是本模式的核心,适配器把源接口转换成目标接口,此角色为具体类LiAdapter实现了LiTarget接口,创建时接收一个Car实例。
3.代码说明:

a.小明操作玩具汽车的方法:

abstract class Toy
{
    public abstract function forward();
}
class Car extends Toy  
{
    public function forward()
    {
        echo "Car forward \n";  //前进
    }
}

//小明操作玩具车
$car = new Car();
$car->forward();  //玩具车前进

b.适配器接口:

//小李请求的接口方法  
interface LiTarget  
{  
    public function didForward();   
} 
//小唐请求的接口方法  
interface TangTarget  
{  
    public function doForward();   
} 

//类适配器角色:小李
class LiAdapter implements LiTarget  
{  
    private $adaptee;  
    function __construct(Car $car)  
    {  
        $this->adaptee = $car;   
    }  
    public function didForward()    
    {  
        $this->adaptee->forward();    //玩具车前进
    }  
} 
//类适配器角色:小唐
class TangAdapter implements TangTarget  
{  
    private $adaptee;  
    function __construct(Car $car)  
    {  
        $this->adaptee = $car;   
    }  
    public function doForward()    
    {  
        $this->adaptee->forward();    //玩具车前进
    }  
} 

c.小李操作玩具汽车前进:

//小李调用
$car = new Car();   //实例化源角色类
$Li = new LiAdapter($car);  //调用接口类
$Li->didForward(); //前进
//小唐调用
$car = new Car();   //实例化源角色类
$Tang = new TangTarget($car);  //调用接口类
$Tang->doForward(); //前进

这样适配器就实现了我们需要的结果,小李只调用didForward()方法就可以操作玩具车前进,小唐只调用doForward()也可以操作玩具车前进。
其实设计模式学着感觉也不是很难,但是关键要用到项目中的话,确实要花点心思去设计和分析的!
下一篇分享:【浅谈设计模式(二)】:博客:[浅谈设计模式(三)] 让你一分钟读懂设计模式
上一篇分享:【浅谈设计模式(一)】:博客:[浅谈设计模式(一)] 让你一分钟读懂设计模式

php
本作品采用《CC 协议》,转载必须注明作者和本文链接
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 3

(1)目标(Target)角色:定义客户端使用的与特定领域相关的接口,这也就是我们所期待得到的这里的小李和小唐要求实现的相关接口。我们可以看到LiTarget和TangTarget必须实现didForwarddidForward方法

这里是笔误了吧?

5年前 评论

@PhoenixIcy :joy: 是的 已经修改了

5年前 评论

建议在加一下使用场景。感觉有时候简单的 demo 示例可以看懂,但是在实际项目中不知道什么时候需要使用。

4年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!