文档章节

委托者模式和策略模式的区别

吾爱
 吾爱
发布于 2014/05/20 23:22
字数 867
阅读 1010
收藏 14
php

看《PHP设计模式》这本书,里面写到委托模式和策略模式,我翻来覆去的看,从代码上看它们是一种东西,至少实现的原理是一样的。

搜了百度、谷歌、bing,对于委托模式资料很少,勉强自己总结了一下:

委托模式:当一个对象在不同的情况下需要调用不同的方法,而这些方法自己本身没有实现,就可以通过委托的方式来让其他对象来做。

策略模式:当一个类里某个方法在不同的情况下需要不同的算法实现,这时候可以用策略模式。

先说委托模式,我们假设有一个公司职员的基类Person基类里包含了基本的方法,比如获取员工的姓名、年龄等。但是员工有不同的角色,比如后端工程师、前端工程师、项目经理,一般情况下我们想要获取后端工程师特有的数据,会想到用继承的方式,如果场景固定,可以这么做,但有时候一个人可能同时身兼多种角色,这时候你需要添加"后端and经理" "前端and后端" 等等组合,角色越多问题越大,最后你会发现无尽的继承。委托模式这时候就可以派上用场了可以动态的切换角色,直接看代码吧:

<?php
class Person {
    public $age;
    public $name;
    private $_delegator;
    //获取出勤记录
    public function getAttendance(){
        ...
    }
    
    //以上都是公共方法
    ...
    
    //注册委托者
    function setDelegator($delegator){
        $this->_delegator = $delegator;
    }
    //调用委托者的方法
    function invokeDelegator($method,$params=array()){
        array_unshift($params,$this);//使委托者对象能够调用Person对象的属性和方法
        return call_user_func_array(array($this->_delegator,$method),$params);
    }   
}

//项目经理类
class Manager{
    //获取会议记录
    function meeting($person){
         ...
         return $data;
    }
}

//工程师类
class Engineer{
    //获取项目列表
    function projectList($person){
         ...
         return $data;
    }
}


$person = new Person();
$person->name = "张三";
$person->age = 34;
//获取张三作为项目经理的工龄
$person->setDelegator(new Manager());
$meeting = $person->invokeDelegator("meeting");//获取项目经理的会议记录
//角色切换到工程师
$person->setDelegator(new Engineer());
$projectList = $person->invokeDelegator("projectList");//获取工程师的项目列表



这样,我们就不用将项目经理、工程师都去继承person类,而且可以动态切换角色,并且避免了过度继承造成的类爆炸。


再看看策略模式:

策略模式是当某个类中某一个方法可能在不同的情形下需要有不同的算法,比如一个唱片CD类,其中有一个方法是getList()获取唱片列表,客户A可能需要的是json格式,客户B可能需要的是xml格式,这时候就需要为getList就难以满足这些变化的需求,策略模式可以解决这个问题。

<?php
class CD {
   public $list;//列表源数据,数组模式
   function getList($list_maker){
       return $list_maker->getList($list);
   }
}

class Json {
   function getList($list){
      return json_encode($list);
   }

}


class Xml {
   function getList($list){
      ...
      return $xml->saveXml();
   }
}


$CD = new CD();
$jsonlist = $CD->getList(new Json());//json格式的列表
$xmllist = $CD->getList(new Xml());//获取xml格式的列表



与委托模式的区别主要是理念上的,我们CD类本身是有getList这个功能的,只是后来根据不同的情景需要有不同的算法,我们只是把switch...case...封装出去了:Json、Xml……

我想,大概就是如此了吧。

© 著作权归作者所有

吾爱
粉丝 142
博文 272
码字总数 91680
作品 0
后端工程师
私信 提问
加载中

评论(2)

爱宠网
爱宠网
讲的不错 不过感觉你总结的策略模式还是不是很理解感觉你对策略模式的定义还是比较倾向于委托模式,这个是书中对策略模式的定义“策略设计模式帮助构建的对象不必自身包含逻辑,而是能够根据需要利用其它对象中的算法”按书中的定义看策略模式应该更像工厂模式 按我的理解委托模式倾向对象的方法 策略模式倾向对象的构建
大灰狼wow
大灰狼wow
不错
设计模式之抽象工厂模式(创建型)

模式定义 抽象工厂模式(Abstract Factory Pattern):提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。抽象工厂模式又称为Kit模式,属于对象创建型模式。 模式角色 抽象...

smileNicky
01/01
0
0
JavaScript设计模式总结

之前看过《JavaScript设计模式与开发实践》这本书,对书中的设计模式和一些相关案例也有了一定的了解,同时把这些设计模式的应用对应在在一些其他的项目中,进行了一些整理,如下仅供参考: ...

jefferyE
03/26
0
0
23种设计模式(3):抽象工厂模式

定义:为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类。 类型:创建类模式 类图: 抽象工厂模式与工厂方法模式的区别 抽象工厂模式是工厂方法模式的升级版本,他用来...

LCZ777
2014/07/05
128
0
EasyToLearnDesignPattern

简单上手设计模式 GITHUB:https://github.com/Fisher-Joe/EasyToLearnDesignPattern 本文旨在使用最简单的语言,最简单的代码让人学习设计模式(最起码是我) 说明: 本文的所有内容都是基于...

芝麻开门
04/19
0
0
设计模式学习笔记十四:适配器模式、桥接模式与外观模式

1.适配器模式与桥接模式的区别和联系 适配器模式和桥接模式都是间接引用对象,因此可以使系统更灵活,在实现上都涉及从自身以外的一个接口向被引用的对象发出请求。 两种模式的区别在于使用场...

长平狐
2013/06/17
123
0

没有更多内容

加载失败,请刷新页面

加载更多

RxJava进行单元测试的方式

@Test public void completeTask_retrievedTaskIsComplete() { // Given a new task in the persistent repository final Task newTask = new Task(TITLE, ""); ......

SuShine
22分钟前
5
0
正则表达式大全

检验手机号码 # 要求:手机号码必须为11位数字,以1开头,第二位为1或5或8。import redef verify_mobile(): mob = input("请输入手机号码:") ret = re.match(r"1[358]\d{9}", m......

彩色泡泡糖
26分钟前
5
0
QT之border-image属性

一、border-image的兼容性 border-image可以说是CSS3中的一员大将,将来一定会大放光彩,其应用潜力真的是非常的惊人。可惜目前支持的浏览器有限,仅Firefox3.5,chrome浏览器,Safari3+支持...

shzwork
27分钟前
6
0
Kubernetes Operator简易教程

1. 安装operator-sdk //安装 operator-sdk$ apt-get install operator-sdk.....$ operator-sdk versionoperator-sdk version: v0.7.0$ go versiongo version go1.11.4 darwin/amd64 2......

Robotcl_Blog
27分钟前
5
0
再谈DAG任务分解和Shuffle RDD

1、DagScheduler分析 DagScheduler功能主要是负责RDD的各个stage的分解和任务提交。Stage分解是从触发任务调度过程的finalStage开始倒推寻找父stage,如果父stage没有提交任务则循环提交缺失...

守望者之父
33分钟前
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部