PHP学习记录----策略模式
2014-04-04 13:13
375 查看
策略模式可以用来创建可插入,可替换,可重用的组件。
先写一个没有用策略模式的例子:
Lesson.class.php:
考虑第二个问题:是否可插入? 如果我们此时再加入一门新的课程,必须往主类中添加额外的代码,违反了高内聚,低耦合的原则,所以上述代码也不可怎么容易插入。
考虑第桑个问题:是否可替换? 如果将ENGLISH改为CHINESE的话,那么Lesson.php中也要修改,有ENGLISH的地方都要进行修改,造成连锁反应,所以替换也不行。
当项目不断扩展时,它的修改和维护会非常艰难。下面我们来再用继承的方式修改一下上述的代码:
Lesson.class.php:
English.class.php:
Math.class.php:
现在我们再来进一步使用策略模式来代替继承,因为在以后的扩展和维护中,策略模式要优于继承。
策略模式的组成: 1.策略类,通常由一个接口或抽象类来实现 2.具体的策略角色:包装了相关的算法和行为 3.环境角色:持有一个策略类的引用,最终给客户端调用。
Lesson.class.php:
lesson.php:
我们为子类添加一个父类来统一规范子类:
Lesson.class.php:
先写一个没有用策略模式的例子:
Lesson.class.php:
<?php //课程类 class Lesson { //课程购买人数 private $_num; //课程类型 private $_type; //英文课的标识 const ENGLISH = 1; //数学课的标识 const MATH = 2; //构造方法初始化 public function __construct($_num,$_type){ $this->_num=$_num; $this->_type=$_type; } //返回购买课程所需的费用 public function cost(){ switch($this->_type){ case self::ENGLISH: return 300*$this->_num; break; case self::MATH: return 180*$this->_num; break; } } //返回购买课程的名称 public function courseType(){ switch($this->_type){ case self::ENGLISH: return '您购买的是英文课'; break; case self::MATH: return '您购买的是数学课'; break; } } } ?>Lesson.php:
<?php require 'Lesson.class.php'; $_lesson = new Lesson(5,Lesson::ENGLISH); echo $_lesson->courseType().',总共花费了'.$_lesson->cost().'元'; echo '<br>'; $_lesson = new Lesson(5,Lesson::MATH); echo $_lesson->courseType().',总共花费了'.$_lesson->cost().'元'; ?>考虑第一个问题:是否可重用? 很明显上述代码是不可重用的,都是单独调用。
考虑第二个问题:是否可插入? 如果我们此时再加入一门新的课程,必须往主类中添加额外的代码,违反了高内聚,低耦合的原则,所以上述代码也不可怎么容易插入。
考虑第桑个问题:是否可替换? 如果将ENGLISH改为CHINESE的话,那么Lesson.php中也要修改,有ENGLISH的地方都要进行修改,造成连锁反应,所以替换也不行。
当项目不断扩展时,它的修改和维护会非常艰难。下面我们来再用继承的方式修改一下上述的代码:
Lesson.class.php:
<?php //抽象课程类 abstract class Lesson { //课程购买人数 protected $_num; //构造方法初始化 public function __construct($_num){ $this->_num=$_num; } //返回购买课程所需的费用 abstract public function cost(); //返回购买课程的名称 abstract public function courseType(); } ?>
English.class.php:
<?php class English extends Lesson { public function cost(){ return 300*$this->_num; } public function courseType(){ return '您购买的是英语课程'; } } ?>
Math.class.php:
<?php class Math extends Lesson { public function cost(){ return 180*$this->_num; } public function courseType(){ return '您购买的是数学课程'; } } ?>lesson.php:
<?php require 'Lesson.class.php'; require 'English.class.php'; require 'Math.class.php'; $_english = new English(5); echo $_english->courseType().',总共需要花费'.$_english->cost(); echo '<br>'; $_math = new Math(5); echo $_math->courseType().',总共需要花费'.$_math->cost(); ?>如果我们此时想要增加一门新的课程,就不需要再在主类中做任何修改了。只需要再增加一个新的类就行。
现在我们再来进一步使用策略模式来代替继承,因为在以后的扩展和维护中,策略模式要优于继承。
策略模式的组成: 1.策略类,通常由一个接口或抽象类来实现 2.具体的策略角色:包装了相关的算法和行为 3.环境角色:持有一个策略类的引用,最终给客户端调用。
Lesson.class.php:
<?php //课程类 class Lesson { //课程购买人数 private $_num; //策略属性,保存具体策略角色对象的引用 private $_strategy; //构造方法初始化 public function __construct($_num,$_strategy){ $this->_num = $_num; $this->_strategy = $_strategy; } //拦截器 public function __get($key){ return $this->$key; } //返回具体策略角色课程所需要的费用 public function cost(){ //$this表示Lesson类传递给English类 return $this->_strategy->cost($this); } //返回具体策略角色购买课程的名称 public function courseType(){ return $this->_strategy->courseType(); } } ?>English.class.php:
<?php class English { public function cost(Lesson $_lesson){ return 300*$_lesson->_num; } public function courseType(){ return '您购买的是英语课程'; } } ?>Math.class.php:
<?php class Math { public function cost(Lesson $_lesson){ return 180*$_lesson->_num; } public function courseType(){ return '您购买的是数学课程'; } } ?>
lesson.php:
<?php require 'Lesson.class.php'; require 'English.class.php'; require 'Math.class.php'; //通过不同的参数来改变不同的课程的行为,这种方法实现了类切换,类切换就是多态 $_lesson = new Lesson(5,new Math()); echo $_lesson->courseType().',总共花费了'.$_lesson->cost().'元'; echo '<br>'; $_lesson = new Lesson(5,new English()); echo $_lesson->courseType().',总共花费了'.$_lesson->cost().'元'; ?>以上的代码并不是完全形态的策略模式,下面来看进一步改进后的形式:
我们为子类添加一个父类来统一规范子类:
Lesson.class.php:
<?php //课程类 class Lesson { //课程购买人数 private $_num; //策略属性,保存具体策略角色对象的引用 private $_strategy; //构造方法初始化 public function __construct($_num,$_strategy){ $this->_num = $_num; $this->_strategy = $_strategy; } //拦截器 public function __get($key){ return $this->$key; } //返回具体策略角色课程所需要的费用 public function cost(){ //$this表示Lesson类传递给English类 return $this->_strategy->cost($this); } //返回具体策略角色购买课程的名称 public function courseType(){ return $this->_strategy->courseType(); } } ?>SuperClass.class.php:
<?php abstract class SuperCourse { abstract public function cost(Lesson $_lesson); abstract public function courseType(); } ?>Math.class.php:
<?php class Math extends SuperCourse{ public function cost(Lesson $_lesson){ return 180*$_lesson->_num; } public function courseType(){ return '您购买的是数学课程'; } } ?>English.class.php:
<?php class English extends SuperCourse{ public function cost(Lesson $_lesson){ return 300*$_lesson->_num; } public function courseType(){ return '您购买的是英语课程'; } } ?>lesson.php:
<?php require 'Lesson.class.php'; require 'SuperCourse.class.php'; require 'English.class.php'; require 'Math.class.php'; //通过不同的参数来改变不同的课程的行为,这种方法实现了类切换,类切换就是多态 $_lesson = new Lesson(5,new Math()); echo $_lesson->courseType().',总共花费了'.$_lesson->cost().'元'; echo '<br>'; $_lesson = new Lesson(5,new English()); echo $_lesson->courseType().',总共花费了'.$_lesson->cost().'元'; ?>这就是一个比较正宗的策略模式-。-
相关文章推荐
- 策略模式(StragetyPattern)学习记录
- Java设计模式学习记录-策略模式
- 记录我的学习设计模式的点点滴滴,从这一篇开始——策略模式
- php设计模式学习记录(上)
- php设计模式学习记录(下)
- 学习php设计模式 php实现策略模式(strategy)
- 学习php设计模式 php实现策略模式(strategy)
- 学习php设计模式 php实现访问者模式(Visitor)
- 对于社保截止日接口的学习记录---对于php时间的操作(date_time和timestamp)
- 学习php设计模式 php实现装饰器模式(decorator)
- 学习php设计模式 php实现享元模式(flyweight)
- 设计模式学习总结(一)策略模式Strategy Pattern
- PHPWeb开发相关知识学习记录
- PHP设计模式——适配器模式(研磨设计模式学习笔记)
- 学习php设计模式 php实现命令模式(command)
- 学习笔记——JAVA设计模式<18>策略模式
- 设计模式学习—策略模式
- php 学习记录 ajax responseXML Text
- 设计模式学习记录
- 设计模式 学习笔记(1)简单工厂模式、策略模式