浅谈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博客,所以难免漏洞,今后一定对于这个设计模式进行更深一步的完善的博客再推出来。

时间: 2024-12-20 16:38:23

浅谈php之设计模式基础的相关文章

NLP系列(1)_从破译外星人文字浅谈自然语言处理的基础

作者:龙心尘 &&寒小阳 时间:2016年1月. 出处: http://blog.csdn.net/longxinchen_ml/article/details/50543337, http://blog.csdn.net/han_xiaoyang/article/details/50545650 声明:版权所有,转载请联系作者并注明出处 1. 如果让你破译"三体"人文字你会怎么办? 我们试着开一下脑洞:假如你有一个优盘,里面存了大量"三体"人(刘慈

浅谈23种设计模式

类之间的关联关系:在使用Java.C#和C++等编程语言实现关联关系时,通常将一个类作为另一个类的属性. (1)双向关联,两个类互相为各自的属性,比如顾客类Customer和商品类Product,顾客拥有商品,商品与某个顾客相关联. (2)单向关联,一个类作为另一个类的属性,顾客Customer拥有地址Address,UML图用带箭头的直线表示,由Customer指向Address. (3)自关联,此类的属性对象类型属于该类本身,例如节点类Node的成员又是节点对象. (4)多重关联,Form类

浅谈MVC&amp;MTV设计模式

在目前基于Python语言的几十个Web开发框架中,几乎所有的全栈框架都强制或引导开发者使用MVC设计模式.所谓全栈框架,是指除了封装网络和线程操作,还提供HTTP.数据库读写管理.HTML模板引擎等一系列功能的Web框架,比如Django.Tornado和Flask. MVC设计模式: 最早由Trygve Teenskaug在1978年提出,上世纪80年代是程序语言Smalltalk的一种内部架构.后来MVC被其他领域借鉴,成为了软件工程中的一种软件架构模式. MVC把Web框架分为3个基础部

浅谈2D游戏设计模式--游戏剧情设计(1)

博主不才,人生有2大爱好,写程序和玩游戏,本人玩的又是一款2D的在旁人看来弱智的网络游戏. 这款游戏在中国的名称叫做冒险岛,不知道园子里有没有人玩过. 我打算有空的话,就把我玩游戏中的心得和程序结合起来,一方面自己也想做个总结,毕竟玩了那么久游戏,总该写个总结, 另一方面,也是想把自己的心得分享给大家. 这款游戏实在是很大,大道我都不知道从何写起比较好,我就分块介绍好吧,因为我没有游戏设计的经验, 我只能从一个老玩家的视角进行剖析. 首先我来说一下游戏的色调吧,一个游戏最重要的无非就是游戏的创意

浅谈Android MVP 设计模式

为什么需要MVP 关于什么是MVP,以及MVC.MVP.MVVM有什么区别,这类问题网上已经有很多的讲解,你可以自行搜索或看看文末的参考文章,这里就只讲讲为什么需要MVP. 在Android开发中,Activity并不是一个标准的MVC模式中的Controller,它的首要职责是加载应用的布局和初始化用户界面,并接受并处理来自用户的操作请求,进而作出响应.但是,随着界面及其逻辑的复杂度不断提升,Activity类的职责不断增加,以致很容易变得庞大而臃肿. 越小的类,bug越不容易出现,越容易调试

浅谈群集与分布式基础知识

长期以来对于做IT的人员来说可能会经常听见一个名词,群集,什么负载均衡群集,高可用群集,双活群集,这对于非相关人员来说根本不明白是什么意思,好像群集很神秘,很高大上,其实群集的概念并没有想象中那么复杂,本文老王会试着用比较简单的语言,来为大家分享我所学习了解的群集知识,尽量让只有简单服务器 网络基础的朋友也可以听懂,如果有说的不对的地方欢迎指正 什么是群集呢,简单来说,群集就是把一堆计算机组合起来做一件事情,把一堆计算机组合起来一起干活,它们就可以叫做群集,通常群集给人的感觉就好像是一个"整体计

浅谈密码学中数论基础

1.模运算(mod) 模运算也可以称为取余运算,例如 23≡11(mod12),因此如果a=kn+b,也可以表示为a ≡ b(mod n),运算规则: (a+b) mod n = ((a mod n) + (b mod n))mod n (a*b) mod n = ((a mod n) * (b mod n)) mod n 完全剩余集合 1~n-1构成了自然数n的完全剩余集合,对于任意一个整数m%n都存在于1~n的集合中. 构造加法链 在加密算法中,运用到了大量的取模运算,对于一个k位数模n,所

浅谈PL/SQL语言基础

在前面的学习中,我们大部分接触的都是SQL语言,但是,在实现复杂操作的时候,SQL语言就无能为力了,这时候就需要引入新的语言,PL/SQL语言就是对SQL语言的扩展,可以实现存储过程,函数等的创建.下面是我对PL/SQL语言的总结,和大家分享一下. 一.基本结构 1.PL/SQL是一种块结构的语言,它将一组语句放在一个块中,一次性发送给服务器,当PL/SQL引擎分析收到PL/SQL语句块中的内容,把其中的过程语句由PL/SQL引擎自身去执行,把PL/SQL语句块中的SQL语句交给服务器的SQL语

浅谈2D游戏设计模式2- WZ文件详解(UI.WZ)之MapLogin.img(1)

玩过冒险岛的人都知道有一个WZ文件,那么这个WZ文件的内部是怎么样的呢,今天我就带大家一探究竟. 说实在的,我这是第一次接触WZ文件,但是却让我很震撼,为什么很震撼,因为这个居然是用VS2010写的!还是.NET,我TMD居然就是搞.NET程序设计的, 早知道早点问@卧室好人要WZ文件了,哈哈. 言归正传,既然自己是一个编程方面的菜鸟,多多少少还是知道一些的.下面就带大家来研究WZ文件,也希望一些大神能提供一些帮助. 这个系列的只是从WZ的表面研究,并没有深入源代码,待我到时候反编译(或者问本人