zoukankan      html  css  js  c++  java
  • 浅谈php之设计模式基础

      本人近期正在学习php,所以就以设计模式的基础来谈一下自己的一些看法

      一:什么是设计模式

      学习编程的应该很多都有听说过设计模式,经常是什么js的设计模式,php设计模式,那么什么是设计模式呢?通俗的讲,设计模式就是一套被反复使用,很多人都知晓的,代码设计经验的总结,更功利的说法是,设计模式是为了可重用代码,更容易让其他人理解,保证了代码的可靠性。其核心有四个部分组成,就是命名,问题,解决方案,效果。当然,这些空套话多说了也是无益,下面我就以一个循序渐进的例子来简要的谈下,设计模式是有多么重要。

    第一版:最原始的做法,以Lesson类的课程销售系统为例子

      以大学中的选课系统中的一个简单的例子,我们这里有一个关于Lesson的类,所谓‘类’,这个说起来大家都很熟悉,无非包含的就是方法和属性,那么我就简要的给这个类定义两个属性和两个方法,文字书写比较麻烦,我就以一个简单的图来展示一下

    很明显,这个就是给这个类定义了_num,_type属性,以及cost()和type()方法,至于具体的使用观看看以下的代码

     1 <?php
     2 //课程类
     3 class Lesson {
     4     //课程购买人数
     5     private $_num;
     6     //课程的类型
     7     private $_type;
     8     //计算机课的标识
     9     const COMPUTER = 1;
    10     //数学课的标识
    11     const MATH = 2;
    12     //构造方法初始化
    13     public function __construct($_num, $_type) {
    14         $this->_num = $_num;
    15         $this->_type = $_type;
    16     }
    17     //返回课程所需的费用
    18     public function cost() {
    19         switch ($this->_type) {
    20             case self::COMPUTER :
    21                 return 300 * $this->_num;
    22                 break;
    23             case self::MATH : 
    24                 return 180 * $this->_num;
    25                 break;
    26         }
    27     }
    28     //返回购买的课程
    29     public function type() {
    30         switch ($this->_type) {
    31             case self::COMPUTER : 
    32                 return '您购买的是计算机课!';
    33                 break;
    34             case self::MATH : 
    35                 return '您购买的是数学课!';
    36                 break;
    37         }
    38     }
    39 }
    40 ?>

    稍微有点基础的人应该都能看懂这段代码,就是简单的给这个类定义了两个属性,而且注释说的很详细,所以这里不再进行更多的阐释,至于客户端的调用也是非常的简单,就是new Lesson(),在括号内传入两个参数,比如说new Lesson(5,Lesson::MATH),然后将这个结果赋值给一个变量,然后这个变量就可以调用定义好的方法了,当然前提是要先require这个php文件,客户端这里看起来没有很大的问题,但是,我们看看这个Lesson这个类,如果我们进行进行添加属性和方法时,会遇到很大的麻烦,比如说,我们想要添加一个sport这个课程,就要跟其他的两个选课一样,先要定义一个常量,然后还要再两个方法中,依次添加关于这个sport的东西,照葫芦画瓢,跟其他的两个课程一样,这样看起来,添加一个两个问题倒不是很大,但是要添加很多个课程的时候,就会非常的繁琐,而且很容易出错,这里是两个方法还好的,但是如果这里涉及很多方法,就为了这么的一个新课程,还要依次在这些方法里添加这个课程的东西,确实很繁琐,所以便有了下面的改进。

    二:用继承的方法让子类做具体的实现

      废话不多少,先上图

    一眼看这个图,感觉主类跟前面的一种方法没啥区别,而且这个继承,要怎么继承,所以接下来看代码最为重要,这里我是需要四个类,Lesson.class.php,English.class.php,Math.class.php和lesson.php

    先看Lesson.class.php的代码

     1 <?php
     2 //抽象课程类
     3 abstract class Lesson {
     4     //课程购买人数
     5     protected $_num;
     6     
     7     //构造方法初始化
     8     public function __construct($_num) {
     9         $this->_num = $_num;
    10     }
    11     
    12     //返回课程所需的费用
    13     abstract public function cost();
    14     
    15     //返回购买的课程
    16     abstract public function type();
    17     
    18 }
    19 ?>

    很明显这里定义了一个抽象类,一个属性,构造函数,以及两个方法,这里的方法之所以都定义为抽象方法,其主要的目的就是为了让子类去继承,那么我们就以English为例子来说明怎么利用这个父类

     1 <?php
     2 class English extends Lesson {
     3     public function cost() {
     4         return 300 * $this->_num;
     5     }
     6     public function type() {
     7         return '您购买的是英语课程!';
     8     }
     9 }
    10 ?>

    很简单是吧,就是重写了父类的两个方法,同样的,另外的一个课程Math也是一样,只需要根据自己的需求对cost()方法和type()方法进行改善就行,那么客户端要怎么进行调用呢,很容易,就以英语这个课程来说,先new English(),然后在括号中传递一个参数,表示人数,数学的话也是一样的道理,当然还是要require相关的文件然后将这个new出来的对象传递给一个变量,之后就可以调用其中的方法了,那么这个看起来跟上面的那一种有什么好处呢?比起之前的那种,现在比如说你要添加其他课程的话,比如说体育,那么就是直接再弄出来一个sport类,继承父类,再写上相应东西就行,不用担心写错了,写漏了这些,而且不去动用父类,要知道,动用父类是比较危险的。但是这样也是有一个坏处,就是无法实现多态,就是无法动态的切换类,这样,又是一大缺点了。所以就引出来接下来的第三种方式。第三种方式可以实现动态的去切换类。也就是实现所谓的多态

    三:使用了组合的策略模式代替继承

    先上图先

    比起之前的模式,这次就是在Lesson中加了strategy,那么这个具体要怎么用呢?加了这个之后怎样实现多态呢?别急,我先使用一段代码来展示一下,这个是Lesson.class.php的代码。

     1 <?php
     2 //课程类
     3 class Lesson {
     4     //课程购买人数
     5     private $_num;
     6     //策略属性字段,保存具体策略角色对象的引用,例如English对象或者Math对象
     7     private $_strategy;
     8     
     9     //构造方法初始化
    10     public function __construct($_num, $_strategy) {
    11         $this->_num = $_num;
    12         $this->_strategy = $_strategy;
    13     }
    14     
    15     //拦截器
    16     public function __get($key) {
    17         return $this->$key;
    18     }
    19     
    20     //返回具体策略角色课程所需的费用
    21     public function cost() {                            //$this表示Lesson类,传递给English
    22         return $this->_strategy->cost($this); //$this->_strategy保存了English对象(new English())
    23     }
    24     
    25     //返回具体策略角色购买的课程
    26     public function type() {
    27         return $this->_strategy->type();
    28     }
    29     
    30 }
    31 ?>

    那么加入的这个strategy有什么作用?先看English.class.php代码

    <?php
    class English  {
        public function cost(Lesson $_lesson) {
            return 300 * $_lesson->_num;
        }
        public function type() {
            return '您购买的是英语课程!';
        }
    }
    
    ?>

    在客户端其实最主要的就是一行代码,就是$_lesson=new Lesson(5,new English()),然后在调用其中的方法,这个原理无非就是将new出来的对象传递给Lesson类的strategy,那么其中的$this->strategy就是代表的English()类,其中在使用$this->strategy->cost($this),就是English这个类调用了cost()方法,参数$this就是Lesson类,再回到English类中的cost方法,return 300 * $_lesson->_num;就是访问了Lesson类中的$_num属性,饶了这么多,究竟是有什么好处呢?再回到$_lesson=new Lesson(5,new English()),这个的好处就是可以通过传递不同的参数,实现不同的类之间进行切换,比如说我想现在进行的是Math类,就是使用$_lesson=new Lesson(5,new Math()),这也就是实现了所谓的多态,比起第二种方式的好处是实现不同的类进行切换。

    四:结束语

      php的设计模式之中,还有很多的细分的东西,比如是要对一个父类进行规范,所有子类的继承这个规范的父类,还有很多的东西,今天因为时间的原因,就先钱钱的谈到这里,因为这是刚学习不久,也是自己的第一篇php博客,所以难免漏洞,今后一定对于这个设计模式进行更深一步的完善的博客再推出来。

  • 相关阅读:
    20155333 《网络对抗》 Exp6 信息搜集与漏洞扫描
    20155333 《网络对抗》 Exp5 MSF基础应用
    20155333 《网络对抗》Exp4 恶意代码分析
    20155333 《网络对抗》Exp3 免杀原理与实践
    20155333 《网络对抗》Exp2 后门原理与实践
    2017-2018-2 20155333 《网络对抗技术》 Exp1 PC平台逆向破解
    2017-2018-1 20155333 《信息安全系统设计基础》第三周学习总结
    内核模块实践实验报告
    Linux内核期末总结
    Linux内核期中
  • 原文地址:https://www.cnblogs.com/jtxn/p/5425972.html
Copyright © 2011-2022 走看看