適配器設計模式(應用於活動業務)

適配器的適用場景

  • 代碼的複用性強。php

  • 咱們一直在使用適配器,若是 只有USB鏈接頭,沒法將手機插到標準的插座上面充電 ,這時須要的一個適配器,一端接USB鏈接頭,另外一端接插座設計模式

  • 活動專題,例抽獎,固定的規則是充值有抽獎機會,可是忽然來了一個需求說充值還要分享纔能有抽獎機會,這時能夠運用上這個設計模式app

案例一(來自於php 設計模式 書) - 假設一個企業網站同時銷售軟件服務和軟件產品,目前全部的交易都在美國進行,後續業務決定向歐洲發展要增長貨幣換算(增長適配器)網站

案例二是自已設計於活動專題業務上,只是將邏輯摘取出來,代碼不可直接運行this

優勢

  1. 靈活性擴展性都很好spa

  2. 將目標類和適配者類解耦設計

適配器所涉及的角色包括下面幾種:

目標(Target):定義一個客戶端使用的特定接口。
客戶端(Client):使用目標接口,與和目標接口一致的對象合做。
被適配者(Adaptee):一個現存須要適配的接口。
適配器(Adapter):負責將Adaptee的接口轉換爲Target的接口。適配器是一個具體的類,這是該模式的核心。
適配器分爲類適配器和對象適配器兩種,下面將詳細講述。code

案例一

來自 php 設計模式 一書的適配器設計模式案例**對象

/**
 * EuroCalc.php
 * 美圓 - 能累加購買的服務和產品的價格 來自於php 設計模式
 */
class DollarCalc {
    private $dollar;
    private $product;
    private $service;
    public $rate = 1;

    public function requestCalc($productNow,$serviceNow) {
        $this->product = $productNow;
        $this->service = $serviceNow;
        $this->dollar = $this->product + $this->service;
        return $this->requestCount();
    }

    private function requestCount() {
        $this->dollar *= $this->rate;
        return $this->dollar;
    }
}


/**
 * EuroCalc.php
 * 歐元 -  能累加購買的服務和產品的價格
 */
class EuroCalc {
    private $euro;
    private $product;
    private $service;
    public $rate = 1;

    public function requestCalc($productNow,$serviceNow) {
        $this->product = $productNow;
        $this->service = $serviceNow;
        $this->euro = $this->product + $this->service;
        return $this->requestCount();
    }

    private function requestCount() {
        $this->euro *= $this->rate;
        return $this->euro;
    }
}
/**
 * 接口 ITarget.php
 */
interface ITarget {
    function requester();
}
/**
 * 例:找一個合適的適配器來適合歐洲的插座同樣,如下就是建立這個適配器
 * EuroAdapter 實現了一個接口又擴展了一個類
 */

class EuroAdapter extends EuroCalc implements ITarget {
    public function __construct() {
        $this->requester();
    }
    public function requester() {
        $this->rate = 0.8111;
        return $this->rate;
    }
}
/**
 * 用戶
 */
class Client {
    private $euroRequest;
    private $dollarRequest;
    public function __construct() {
        $this->euroRequest = new EuroAdapter();
        $this->dollarRequest = new DollarCalc();

        $euros = "€";
        echo "Euros:$euros".$this->makeAdapterRequest($this->euroRequest)."<br />";
        echo "dollar:".$this->makeDollarRequest($this->dollarRequest);
    }

    public function makeAdapterRequest(ITarget $req) {
        return $req->requestCalc(40,50);
    }

    public function makeDollarRequest(DollarCalc $req) {
        return $req->requestCalc(40,50);
    }
}
$worker = new Client();

案例二 我的運用於自動化活動專題的接口設計

抽獎例子(代碼只顯示對應的設計邏輯部分)接口

<?php

/**
 * 適配器模式 - 抽獎接口
 * comment 當後臺規則不知足自動化,能夠添加對應的適配器,增長代碼的複用
 * author AT
 */

namespace controller;


// 每月份對應的適配器 06年3月 = SixMarch
use \Adapter\SixMarch\LotteryAdapter;

/**
 * 抽獎接口 入口文件
 */
final class Lottery extends WebController
{
    // 活動的配置信息 存放後臺配置的活動信息
    private $hd_info;

    public function __construct() {
        // 加載配置信息
        $this->hd_info = ''; 
    }
    public function _lottery()
    {
        // 實例
        $lottery = new LotteryAdapter($hd_info);
        // 取得抽獎結果
        $rs      = $lottery->_getLotteryResult();
        return $rs;
    }

}

namespace controller;

use \bbts\App as BaseApp;
/**
 * 
 */
class LotteryAdapter extends AutoLottery implements ILottery
{
    public function __construct($hd_info) {
        // 後臺配置是否須要使用適配器
        if($hd_info['use_adapter'] === true) {
            $adapter_name = $hd_info['adapter_name'];
            // $adapter_name = 'adapter_name'; test
            $this->$adapter_name();
        }
        
    }
    /**
     * adapter_name 該活動對應的適配器
     */
    private function adapter_name()
    {
        // 假設不符合自動化的需求條件是必須進入遊戲後5分纔可抽獎,增長適配器的該內容便可,從而不用重寫整個抽獎活動
        $game_info = App::$app->model()->checkEnterGameInfo();
        if(strtotime($info['TIME']) - time() < 300) {
            $this->adapter_status = false;
            $this->adapter_code   = -51;
        }
    }
}

namespace controller;

use \bbts\App as BaseApp;
/**
 * 自動化抽獎接口的基類
 */
class AutoLottery {
     // 單獨開發條件的狀態
    public $adapter_status = true;
    public $adapter_code = 0;
    public function _getLotteryResult(){
        
        
        //  最後判斷適配器的狀態
        if(!$this->adapter_status) {
            App::jetJsonpOutput($this->adapter_return_code);
        }

        // 業務邏輯判斷
        
        // 經過則將數據入庫
        $rs_status = App::$app->model()->insert($rs);
       
        // 返回結果
        return $rs;
    }
}
?>
相關文章
相關標籤/搜索