1. 程式人生 > >代理模式+簡單工廠或代理模式+策略模式實現開通推廣功能

代理模式+簡單工廠或代理模式+策略模式實現開通推廣功能

rom face ram inter truct cond strong LV 所有

實現功能:

1.用戶金幣或銀兩達到一定數額後,可以用相應數量的金幣或銀兩開通推廣功能,開通推廣功能後,由此產生的收益歸該用戶所有

2.推廣類,不允許直接操作推廣類,需要判斷用戶是否有金幣或銀兩來開通,所以使用代理類.

3.用戶可以用銀兩也可以用金幣來開通,所以使用策略模式或簡單工廠模式;就系統目前而言就兩種開通方式,比較固化,所以使用簡單工廠模式來創建開通類會比較恰當.

一.推廣接口

/**
 * 推廣接口
 * Interface PromotionInterface
 */
interface PromotionInterface
{
    const LEVEL_FIRST   = 1;
    const LEVEL_SECOND  = 2;
    const LEVEL_THIRD   = 3;
    public function open($level);
}

  

二.銀兩開通推廣類:

class PromotionSilver implements PromotionInterface
{
    const EXPEND = [
        PromotionInterface::LEVEL_FIRST   => 1000,
        PromotionInterface::LEVEL_SECOND  => 2000,
        PromotionInterface::LEVEL_THIRD   => 3000,
    ];

    public function open($level)
    {
        echo "已開通{$level}推廣級別";
    }
}

  

三.金幣開通推廣

/**
 * 金幣開通推廣
 * Class PromotionMoney
 */
class PromotionMoney implements PromotionInterface
{
    const EXPEND = [
        PromotionInterface::LEVEL_FIRST   => 100,
        PromotionInterface::LEVEL_SECOND  => 200,
        PromotionInterface::LEVEL_THIRD   => 300,
    ];

    public function open($level)
    {
        echo "已開通{$level}推廣級別";
    }
}

  

四.用戶類

/**
 * Class User
 */
class User
{
    private $uid;
    private $money;     // 金幣
    private $silver;    // 銀兩

    public function __construct($uid)
    {
        $this->uid      = $uid;
        $this->money    = 200;
        $this->silver   = 5000;
    }

    public function getMoney()
    {
        return $this->money;
    }

    /**
     * 獲得用戶擁有的銀兩
     * @return int
     */
    public function getSilver()
    {
        return $this->silver;
    }

    /**
     * 扣除用戶金幣
     * @param $money
     */
    public function reduceMoney($money)
    {
        $this->money -= $money;
    }

    /**
     * 扣除用戶銀兩
     * @param $silver
     */
    public function reduceSilver($silver)
    {
        $this->silver -= $silver;
    }
}

  

五.代理類+策略模式:

/**
 * Class PromotionProxy
 */
class PromotionProxy implements PromotionInterface
{
    private $user;
    private $promotion;

    public function __construct($uid)
    {
        $this->user = new User($uid);
    }

    public function setPromotion(PromotionInterface $promotion)
    {
        $this->promotion = $promotion;
    }

    public function open($level)
    {
        if ($this->promotion instanceof PromotionSilver) {
            $expend = PromotionSilver::EXPEND[$level];
            if ($this->user->getSilver() < $expend) {
                echo ‘銀兩不足‘;
                return false;
            }
            // 扣除銀兩
            $this->user->reduceSilver($expend);
        }
        if ($this->promotion instanceof PromotionMoney) {
            $expend = PromotionMoney::EXPEND[$level];
            if ($this->user->getMoney() < $expend) {
                echo ‘金幣不足‘;
                return false;
            }
            // 扣除金幣
            $this->user->reduceMoney($expend);
        }

        $this->promotion->open($level);
        echo $this->user->getMoney();
    }
}

  

調用:

$client = new PromotionProxy($uid = 10);
$client->setPromotion(new PromotionMoney());
$client->open(PromotionInterface::LEVEL_FIRST);

  

六.代理類+簡單工廠模式

/**
 * Class PromotionProxy
 */
class PromotionProxy2 implements PromotionInterface
{
    const OPEN_MONEY    = ‘money‘;
    const OPEN_SILVER   = ‘silver‘;

    private $user;
    private $promotion;

    public function __construct($uid, $type)
    {
        $this->user = new User($uid);

        switch ($type) {
            case self::OPEN_MONEY:
                $this->promotion = new PromotionMoney();
                break;
            case self::OPEN_SILVER:
                $this->promotion = new PromotionSilver();
                break;
            default:
                throw new Exception(‘開通類別錯誤‘);
                break;
        }
    }

    /**
     * @param $level
     * @return bool
     */
    public function open($level)
    {
        if ($this->promotion instanceof PromotionSilver) {
            if ($this->user->getSilver() < PromotionSilver::EXPEND[$level]) {
                echo ‘銀兩不足‘;
                return false;
            }
        }

        if ($this->promotion instanceof PromotionMoney) {
            if ($this->user->getMoney() < PromotionMoney::EXPEND[$level]) {
                echo ‘金幣不足‘;
                return false;
            }
        }

        $this->promotion->open($level);
        return true;
    }
}

  

調用:

$client = new PromotionProxy2(10, PromotionProxy2::OPEN_SILVER);
$client->open(PromotionInterface::LEVEL_FIRST);

代理模式+簡單工廠或代理模式+策略模式實現開通推廣功能