注册 登录  
 加关注
查看详情
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

Copper peas ' Bolg

Keep On Moving...This Is My Life...

 
 
 

日志

 
 

【原】桥接设计模式,策略设计模式,工厂方法模式组合使用案例  

2011-06-14 15:15:56|  分类: php |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

<?php
/**
 *  网上有一篇文章,是关于桥接设计模式,我看了以后,觉得还可以完善,就练手了,扩展了功能。

http://csq-3.blog.163.com/blog/static/38738439201151431556181/

 实现一个图书销售后计算最终售价的模块。
 假想案例说明:出版社在出版的书后会在多家书店销售,假如所有的书的销售都由一个总公司负责销售,它可以控制书的销售方式,例如:计算机书打八折,生活类的打七折等。同时公司可以选择地区经销商做为二级代理,二级代理都必须服从公司的促销方式,如果公司打折,二级代理也要打折,同时总公司会根据二级代理的销售业绩分为不同的二级代理,例如:钻石,黄金,VIP等,它们在得到的回扣上会有不同。钻石,黄金,VIP 分别为20% 10% 5%。计算打折过程中,各二级代理商分别获取多少。注:如果总公司打八折,代理实际卖的价格等于八折的八折。
 现有:《PHP设计模式》 一书 原定价:30元  成本10元 
 回扣等于 (卖的价格-成本)*比例
 
 首先分析了,出现了打折的类型和回扣类型等算法,策略设计模式的特色。
 然后分析了,代理商价格与图书打折两个变化维度出现了纵横交错关系,桥接设计模式的特色。
 然后分析了,变化点,打折的变化由总公司不定时变化,需要弱耦合封装方便扩展它。
 基本结构定了,分离抽象和实现类。
 
 * 桥接设计模式,策略设计模式,工厂方法模式组合使用案例
 *
 * @anthor Chen Wei Han <csq-3@163.com>
 * @copyright Chen Wei Han 2011-6-14下午03:13:26
 * @link http://csq-3.blog.163.com
 * @package
 * @version
 */
header("content-type:text/html;charset=utf-8");
/**
 * 抽象图书打折类
 */
abstract  class abstract_BookDiscount
{
 /**
  * 图书原价
  */
    protected $price;
   
    /**
  * 图书成本价
  */
 private   $costprice;
   
    /**
     * 设置图书的成本价
     * @param INT $price
     */
 public function Setcostprice($price)
 {
  $this->costprice = $price;
 }
 
    public function Getcostprice()
 {
  return $this->costprice;
 }
      
    /**
     * 设置图书的原价
     * @param INT $price
     */
 public function Setprice($price)
 {
  $this->price = $price;
 }
 
    public function Getprice()
 {
  return $this->price;
 }
 
 abstract public function Getpricetype();
 abstract public function Discountprice();
}

/**
 * 图书具体打八折
 */
class Book8 extends abstract_BookDiscount
{  
 
 /**
  * 图书打折类型
  */
 private $pricetype;
 
 
 public function __construct()
 {
  $this->pricetype = 0.8;
 }
 
 public function Getpricetype()
 {
  return $this->pricetype;
 }
 
 public function Discountprice()
 {
  return $this->price * 0.8;
 }
}

/**
 * 图书具体打七折
 */
class Book7 extends abstract_BookDiscount
{  
 private $pricetype;
 
 public function __construct()
 {
  $this->pricetype = 0.7;
 }
 
 public function Getpricetype()
 {
  return $this->pricetype;
 }
 
 public function Discountprice()
 {
  return $this->price*0.7;
 }
}


/*********************************************************************************/
/**
 *  抽象代理商
 */
abstract class abstract_Agency
{
 /**
     * 获取打折的实例
     */
    protected $discount;
   
    public function Setdiscount(abstract_BookDiscount $discount)
    {
         $this->discount = $discount;
    }
   
    /**
     * 获取总公司打折后的代理价格
     */
    public function Getbookprice()
    {
     return $this->discount->Discountprice();
    }
   
    /**
     * 获取图书的成本价
     */
    public function Getbookcostprice()
    {
     return $this->discount->Getcostprice();
    }
   
    /**
     * 代理商图书卖的价格
     */
 abstract public function Agencyprice();
 
 /**
     * 代理商卖图书的回扣
     */
 abstract public function Agencybackprice();
}

/**
 * 钻石代理商
 */
class DiamoliteAgency extends abstract_Agency
{
 private $agencyprice;
 
 public function Agencyprice()
 {
  $this->agencyprice=$this->discount->Getpricetype() * $this->discount->Discountprice();
  return $this->agencyprice;
 }
 
 public function Agencybackprice()
 {
  if($this->Agencyprice()<=$this->Getbookcostprice())
  {
   throw new Exception("没有回扣利润哦!");  
  }  
  /**
         * 实例对应策略类
         */  
  $backprice20    =  new BackPrice20($this->Agencyprice(),$this->Getbookcostprice());
        /**
        * 使用策略入口调用策略
        * 注:这里实例策略入口,是后面加的,最开始我是直接使用策略类调用方法。加了策略入口调用,调用会更规范,以后处理策略结果后的共性功能也方便。
        */
  $strategy       =  new UseStrategy($backprice20);
        $this->result   =  $strategy -> Strategy();       
        return $this->result;
 }
}


/*************************************回扣策略模式***********************************************/
/*注:上面打折和下面回扣都有类型,上面打折没有策略的特点,因为无论打几折,所有代理都通用,而下面的回扣对应不同的代理使用不同的策略*/

/**
 * 回扣抽象类
 */
abstract class abstract_BackPrice
{
 abstract public function backprice();
}

/**
 * 调用策略类入口
 */
class UseStrategy
{
 private $_strategy;
    public function __construct($strategy)
    {
       $this->_strategy = $strategy;   
    }
   
    public function Strategy() {
       return $this->_strategy->backprice();
    }
}

/**
 * 回扣20%具体实现类
 */
class BackPrice20 extends abstract_BackPrice
{
 
 private $valuea;
 private $valueb;
 
 public function __construct($valuea,$valueb)
 {
  $this->valuea = $valuea;
  $this->valueb = $valueb;
 }
 
 public function backprice()
 { 
  return ($this->valuea-$this->valueb)* 0.2;
 }
}

/**
 * 回扣10%具体实现类
 */
class BackPrice10 extends abstract_BackPrice
{
 
 private $valuea;
 private $valueb;
 
 public function __construct($valuea,$valueb)
 {
  $this->valuea = $valuea;
  $this->valueb = $valueb;
 }
 
 public function backprice()
 {
  return ($this->valuea-$this->valueb)* 0.1;
 }
}

/*
 * 说明:无论是修改回扣类型,还是代理商,和图书价格的打折类型,或者是添加新的平行功能 都只需要修改或者添加对应的子类,而不需要修改其他类。
 * 满足了开放关闭原则,依赖倒转原则,
 */

/*
测试使用返回钻石代理商买这本书八折的回扣
//书的八折实例
$cb   = 10;//成本
$gs   = 30;//原价
$pricetype = 8; //促销8折
$agencytype="钻石代理商";
//echo 30*0.8*0.8."<br>";
$book = new Book8();
$book ->Setcostprice($cb);
$book ->Setprice($gs);
$diamoliteagency = new DiamoliteAgency();
$diamoliteagency->Setdiscount($book);
echo "代理商卖php设计模式一书的价格:";
echo $diamoliteagency->Agencyprice();
echo "<br/>";
echo "代理商卖php设计模式一书的价格回扣:";
echo $diamoliteagency->Agencybackprice();
*/

/**
 * 很明显如果这里需要判断$agencytype来显示内容,就的使用工厂方法模式
 */

/*******************************工厂方法模式********************************/

/**
 *  抽象工厂方法
 */
abstract class abstract_factory
{
  abstract public static function GreateClass();
}

/**
 * 钻石代理商子类
 */
class FactoryDiamolite extends abstract_factory
{
 public static function GreateClass()
 {
  return  new DiamoliteAgency();
 }
}

/********************************************************************************/
/**
 * 调用封装后的获取回扣客户端接口
 */
class getprice
{
 public static function backprice($pricetype,$cb,$agencytype,$gs)
 {
  
  $classbook = "Book".$pricetype;//如果没有类命名特殊关联,也可以使用工厂方法模式
  $book = new $classbook;
  $book ->Setcostprice($cb);
  $book ->Setprice($gs);
  //静态调用
  switch ($agencytype)
  {
      case "钻石代理商":
        $backclass = FactoryDiamolite::GreateClass();
      break;
      default:
        echo "err!";
        die();
      break;
   }
   $backclass->Setdiscount($book); 
   return $backclass->Agencybackprice();
 }
}

 


$cb   = 10;//成本
$gs   = 30;//卖原价
$pricetype = 8; //促销8折
$agencytype="钻石代理商";

try
{
   echo getprice::backprice($pricetype,$cb,$agencytype,$gs);
}
catch(Exception $e){
 echo '异常获取: ' .$e->getMessage(); //获取抛出没有利润的异常,把原价和成本定为一样,就会抛出异常,没有回扣利润的 
}


 

  评论这张
 
阅读(244)| 评论(4)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018