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

碎碎念:

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

前言:

设计模式有超过20多种,这里我只分享给大家几个常用的设计模式(每篇文章只介绍一种设计模式,如果全部介绍,文章的篇幅会过长,对于阅读和理解也不友好,望谅解),分享的每个设计模式都会通过3个方面(定义、举例说明、代码说明)进行讲解和说明。
常用的设计模式:
1.工厂模式、2.单例模式、3.适配器模式、4.观察者模式、5.策略模式、
6.注册树模式(它的定位可能和“简单工厂”差不多,都是一种简化的,实用的技巧,【不算在真正的的23种设计模式之中】)
7.其他等等模式

学习前的准备:

在学习设计模式前,需要掌握一些类的基础知识(有经验的可以跳过),比如:接口、抽象类。(该类知识可学习菜鸟教程里面向对象这一章)
菜鸟教程: www.runoob.com/php/php-oop.html
接口和抽象类的概念有点相似:
接口:一个类要实现一个接口,类中必须实现接口中定义的所有方法,接口中定义的所有方法都必须是公有。
抽象类:一个类继承抽象类,子类必须定义父类中的所有抽象方法,子类中的方法访问控制(public、protected 、private)必须和父类中一样(或者更为宽松),例如某个抽象方法被声明为受保护的,那么子类中实现的方法就应该声明为受保护的或者公有的,而不能定义为私有的。(私有比受保护的更高级和更严格)
正文:

工厂模式

a.简单工厂模式:

1.定义:用来实现创建对象和对象的使用分离,将对象的创建交给专门的工厂类负责。
2.举例说明:我有一个工厂类,我们有A产品类生产A产品和B产品类生产B产品或更多的产品类,你下单什么产品,工厂就调用指定的产品类进行生产产品。
3.代码说明:

<?php 
//简单工厂模式
class ProductA
{
  function __construct()
  {
      echo "I am ProductA class <br>";
  }
}
class ProductB
{
  function __construct()
  {
      echo "I am ProductB class <br>";
  }
}
class Factory
{
  public static function CreateProduct($name){
      if ($name == 'A') {
          return new ProductA();
      } elseif ($name == 'B') {
          return new ProductB();
      }
  }
}
$cat = Factory::CreateProduct('A');
$dog = Factory::CreateProduct('B');

b.工厂模式:

1.定义:在该模式中,核心的工厂类不再负责所有产品的创建,而是将具体创建工作交给子类去做。这个核心类仅仅负责给出具体工厂必须实现的接口,而不负责产品类被实例化这种细节。
2.举例说明:我有一个工厂总部(核心)和一个产品总部(核心),工厂总部负责管工厂,产品总部负责管产品,产品总部下有多少个产品,工厂总部下就有多少个工厂,即指定的工厂生产指定的产品(一对一关系);如果你下单A产品,A工厂就生产产品;你下单B产品,B工厂就生产产品。
3.代码说明:

<?php 
  interface Product{     //产品接口(核心类)
      public function getProduct();
  }
  class ProductA implements Product   //A类产品
  {
      public function getProduct(){
          echo "I'm ProductA <br>";
      }
  }
  class ProductB implements Product   /B类产品
  {
      public function getProduct(){
          echo "I'm ProductB <br>";
      }
  }
abstract class Factory{      //抽象工厂类(抽象类)(核心工厂类)
      abstract static function createProduct();
  }
  class ProductAFactory extends Factory   //A工厂继承工厂类
  {
      public static function createProduct()
      {
          return new ProductA();   //A工厂创建A产品类对象
      }
  }
  class ProductBFactory extends Product  //B工厂继承工厂类
  {
      public static function createProduct()
      {
          return new ProductB();    //B工厂创建B产品类对象
      }
  }

调用:

    注意:声明为static的静态方法不能通过new实例化对象进行访问,必须使用类名::方法名() 访问
  $ProductA = ProductAFactory::createProduct();
  $ProductA->getProduct();
  $ProductB = ProductBFactory::createProduct();
  $ProductB->getProduct();

c.抽象工厂模式:

1.定义:此模式是对工厂方法模式的进一步扩展。在工厂方法模式中,一个具体的工厂负责生产一类具体的产品,即一对一的关系,但是,如果需要一个具体的工厂生产多种产品对象,那么就需要用到抽象工厂模式了,即一个工厂可以生产多种产品。
2.举例说明:产品分为2类,有鼠标产品类总部(核心类),有键盘产品类总部(核心类),鼠标类总部下有戴尔鼠标、联想鼠标2种品牌的鼠标产品类,键盘类总部下也有戴尔键盘、联想键盘2种品牌的键盘产品类,这时有一个工厂总部类(核心类),可以生产鼠标和键盘,工厂总部下面有戴尔工厂、联想工厂2种品牌的工厂,但是这2种工厂每个工厂都可以生产鼠标和键盘。
看图更为直观:
file
3.代码说明:

<?php 
interface Mouse{     //鼠标产品接口(核心类)
      public function getMouse();  //获取鼠标
  }
class DellMouse implements Mouse   //戴尔类产品
  {
      public function getMouse(){
          echo "我是戴尔鼠标<br>";
      }
  }
class LenovoMouse implements Mouse   //联想类产品
  {
      public function getMouse(){
          echo "我是联想鼠标<br>";
      }
  }
interface Keybo{     //键盘产品接口(核心类)
      public function getKeybo();  //获取键盘
  }
class DellKeybo implements Keybo   //戴尔类产品
  {
      public function getKeybo(){
          echo "我是戴尔键盘<br>";
      }
  }
class LenovoKeybo implements Keybo   //联想类产品
  {
      public function getKeybo(){
          echo "我是联想键盘<br>";
      }
  }
abstract class Factory{      //抽象工厂类(核心工厂类)
      abstract static function createMouse(); //生产鼠标
      abstract static function createKeybo();//生产键盘
  }
class DellFactory extends Factory   //戴尔牌工厂继承工厂类
  {
      public static function createMouse()
      {
          return new DellMouse();   //工厂创建戴尔鼠标类对象
      }
      public static function createKeybo()
      {
          return new DellKeybo();   //工厂创建戴尔键盘类对象
      }
  }
class LenovoFactory extends Factory   //联想牌工厂继承工厂类
  {
      public static function createMouse()
      {
          return new LenovoMouse();   //工厂创建联想鼠标类对象
      }
      public static function createKeybo()
      {
          return new LenovoKeybo();   //工厂创建联想键盘类对象
      }
  }

调用:

//输出“我是戴尔鼠标”
$dell_mouse =DellFactory::createMouse();
echo  $dell_mouse->getMouse();
//输出“我是戴尔键盘”
$dell_keybo = DellFactory::createKeybo();
echo $dell_keybo->getKeybo();
//输出“我是联想鼠标”
$lenovo_mouse = LenovoFactory::createMouse();
echo $lenovo_mouse->getMouse();
//输出“我是联想键盘”
$lenovo_keybo = LenovoFactory::createKeybo();
echo $lenovo_keybo->getKeybo();

好了,工厂模式介绍完毕,有理解和总结不对的地方,希望可以指点一下,后续会继续分享其他常用模式。
下一篇分享: 博客:[浅谈设计模式(二)] 让你一分钟读懂设计模式

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

哎 学完总是忘记

5年前 评论
wanghan

b工厂模式的代码说明中有错误

5年前 评论
wanghan

c抽象工厂模式中,interface里定义的方法,实现类里不需要都实现的吗?

5年前 评论

是的,你是对的,我已经做了修改。 感谢指出

5年前 评论
AloneUtopia

@best辉 有些不太理解的地方,请教一下 。 在抽象工厂类Factory中定义的create 方法,同时使用了abstract 和 static 关键字,abstract 用来声明抽象方法,抽象方法是不能被调用的,只能在子类中被重写;而static 用来声明静态方法 ,静态方法可以不用实例化类就直接调用 。 这样两者不就有点矛盾了么 ? 在php严格模式应该会不会报错? 这样写是否规范? 有没有更好的方式呢?

4年前 评论

抽象工厂模式的代码说明里面的 核心工厂类 为什么要用抽象类呢,用 interface 不是也可以吗

abstract class Factory{      //抽象工厂类(核心工厂类)
      abstract static function createMouse(); //生产鼠标
      abstract static function createKeybo();//生产键盘
  }
3年前 评论
OuYang 1年前

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