zoukankan      html  css  js  c++  java
  • 设计模式之装饰者模式

    装饰模式:动态的给对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更加的灵活。

    装饰者模式与传统模式的区别

    一般要给对象添加功能时的做法:

    传统模式:

      (1)直接修改对象添加相应的功能,

      (2)派生对应的子类来拓展原有类的功能

    装饰者模式:

      使用对象组合的方式,动态的组合功能

    装饰者模式的具体做法

    在这种模式下,对已有对象的部分内容或者是功能进行调整,但是不修改原始的对象结构。换句话说,不修改已有的类,而是通过创建另外一个装饰者类去动态的拓展其需要修改的内容。

    优势:

    (1)可以保证类的层次不会因过多而发生混乱

    (2)当我们需求的修改很小时,不用改变原有的数据结构

    装饰者模式把每个要装饰的功能放在单独的类中,并让这个类包装它需要装饰的对象。因此,当需要执行特殊行为时吗,客户端代码就可以在运行时根据需求有选择的,按顺序的的使用装饰功能来包装对象。有效的把类的核心职责和装饰功能区分开,而且可以去除相关类中重复的逻辑代码。

    案例1

     1 <?php
     2 
     3 /** * 被修饰类 现在的需求: 要求能够动态为CD添加音轨、能显示CD音轨列表。 显示时应采用单行并且为每个音轨都以音轨好为前缀。 */
     4 
     5 
     6 class CD {
     7     public $trackList;
     8  
     9     function __construct()   {
    10         # code...
    11         $this->trackList=array();
    12     }
    13  
    14     public function addTrack($track){
    15         $this->trackList[]=$track;
    16     }
    17  
    18     public function getTrackList(){
    19         $output=" ";
    20         foreach ($this->trackList as $key => $value) {
    21             # code...
    22             $output.=($key+1).") {$value}. ";
    23         }
    24         return $output;
    25     }
    26 
    27 }
    28 
    29 /* 现在需求发生变化: 要求将当前实例输出的音轨都采用大写形式。 这个需求并不是一个变化特别大的需求,不需要修改基类或创建一个父子关系的子类,此时创建一个基于装饰器模式的装饰器类。 */
    30 
    31 class CDTrackListDecoratorCaps{
    32     private $_cd;
    33  
    34     public function __construct(CD $CD){
    35         $this->_cd=$CD;
    36     }
    37  
    38     public function makeCaps(){
    39         foreach ($this->_cd->trackList as $key => $value) {
    40             # code...
    41             $this->_cd->trackList[$key]=strtoupper($value); //转换成大写
    42         }
    43     }
    44 }
    45  
    46 //客户端测试
    47 $myCD=new CD();
    48 $trackList=array(   "what It Means",   "brr",   "goodBye"  );
    49 foreach ($trackList as $key => $value) {
    50     # code...
    51     $myCD->addTrack($value);
    52 }
    53  
    54 $myCDCaps=new CDTrackListDecoratorCaps($myCD);
    55 $myCDCaps->makeCaps();
    56 print "The CD contains the following tracks:".$myCD->getTrackList();

    案例2

     1 UserInfo.php
     2 //装饰器模式,对已有对象的部分内容或者功能进行调整,但是不需要修改原始对象结构,可以使用装饰器设计模式
     3 class UserInfo {
     4  
     5     public $userInfo = array(); 
     6         
     7     public function addUser($userInfo) {
     8         $this->userInfo[] = $userInfo;
     9     }
    10         
    11     public function getUserList() {
    12         print_r($this->userInfo);
    13     }
    14 }
    15  
    16 //UserInfoDecorate 装饰一样,改变用户信息输出为大写格式,不改变原先UserInfo类
    17 <?php
    18 include("UserInfo.php");
    19 class UserInfoDecorate {
    20     
    21     public function makeCaps($UserInfo) {
    22         foreach ($UserInfo->userInfo as &$val) {
    23             $val = strtoupper($val);
    24         }
    25     }
    26     
    27 }
    28  
    29 $UserInfo = new UserInfo;
    30 $UserInfo->addUser('zhu');
    31 $UserInfo->addUser('initphp');
    32 $UserInfoDecorate = new UserInfoDecorate;
    33 $UserInfoDecorate->makeCaps($UserInfo);
    34 $UserInfo->getUserList();
  • 相关阅读:
    windows server 2008 R2 安装 sql server 2000 遇到的种种问题
    圆心的VPS记录信息
    无法访问.您可能没有权限使用网络资源.局域网无法访问共享,局域网无法访问打印机的一些方法
    win7 32位 fastcgi模式 运行php
    SpringBoot+JPA实例
    马斯洛的锤子论
    一道算法题
    MySQL源码解读之数据结构LF_HASH
    JS学习专辑外传(1)
    WPF 用DynamicResource动态样式切换
  • 原文地址:https://www.cnblogs.com/wawjandcsws/p/10983932.html
Copyright © 2011-2022 走看看