PHP 設計模式系列之 specification規格模式_php執行個體

來源:互聯網
上載者:User
1、模式定義

規格模式是組合模式的一種擴充,在架構性開發中使用較多(項目級開發很少使用),這裡做一個簡單的介紹。
規格模式(Specification)可以認為是組合模式的一種擴充。有時項目中某些條件決定了商務邏輯,這些條件就可以抽離出來以某種關係(與、或、非)進行組合,從而靈活地對商務邏輯進行定製。另外,在查詢、過濾等應用場合中,通過預定義多個條件,然後使用這些條件的組合來處理查詢或過濾,而不是使用邏輯判斷語句來處理,可以簡化整個實現邏輯。

這裡的每個條件就是一個規格,多個規格/條件通過串聯的方式以某種邏輯關係形成一個組合式的規格。

2、UML類圖


3、範例程式碼

Item.php

<?phpnamespace DesignPatterns\Behavioral\Specification;class Item{protected $price;/*** An item must have a price** @param int $price*/public function __construct($price){$this->price = $price;}/*** Get the items price** @return int*/public function getPrice(){return $this->price;}}

SpecificationInterface.php

<?phpnamespace DesignPatterns\Behavioral\Specification;/*** 規格介面*/interface SpecificationInterface{/*** 判斷對象是否滿足規格** @param Item $item** @return bool*/public function isSatisfiedBy(Item $item);/*** 建立一個邏輯與規格(AND)** @param SpecificationInterface $spec*/public function plus(SpecificationInterface $spec);/*** 建立一個邏輯或規格(OR)** @param SpecificationInterface $spec*/public function either(SpecificationInterface $spec);/*** 建立一個邏輯非規格(NOT)*/public function not();}

AbstractSpecification.php

<?phpnamespace DesignPatterns\Behavioral\Specification;/*** 規格抽象類別*/abstract class AbstractSpecification implements SpecificationInterface{/*** 檢查給定Item是否滿足所有規則** @param Item $item** @return bool*/abstract public function isSatisfiedBy(Item $item);/*** 建立一個新的邏輯與規格(AND)** @param SpecificationInterface $spec** @return SpecificationInterface*/public function plus(SpecificationInterface $spec){return new Plus($this, $spec);}/*** 建立一個新的邏輯或組合規格(OR)** @param SpecificationInterface $spec** @return SpecificationInterface*/public function either(SpecificationInterface $spec){return new Either($this, $spec);}/*** 建立一個新的邏輯非規格(NOT)** @return SpecificationInterface*/public function not(){return new Not($this);}}

Plus.php

<?phpnamespace DesignPatterns\Behavioral\Specification;/*** 邏輯與規格(AND)*/class Plus extends AbstractSpecification{protected $left;protected $right;/*** 在建構函式中傳入兩種規格** @param SpecificationInterface $left* @param SpecificationInterface $right*/public function __construct(SpecificationInterface $left, SpecificationInterface $right){$this->left = $left;$this->right = $right;}/*** 返回兩種規格的邏輯與評估** @param Item $item** @return bool*/public function isSatisfiedBy(Item $item){return $this->left->isSatisfiedBy($item) && $this->right->isSatisfiedBy($item);}}

Either.php

<?phpnamespace DesignPatterns\Behavioral\Specification;/*** 邏輯或規格*/class Either extends AbstractSpecification{protected $left;protected $right;/*** 兩種規格的組合** @param SpecificationInterface $left* @param SpecificationInterface $right*/public function __construct(SpecificationInterface $left, SpecificationInterface $right){$this->left = $left;$this->right = $right;}/*** 返回兩種規格的邏輯或評估** @param Item $item** @return bool*/public function isSatisfiedBy(Item $item){return $this->left->isSatisfiedBy($item) || $this->right->isSatisfiedBy($item);}}

Not.php

<?phpnamespace DesignPatterns\Behavioral\Specification;/*** 邏輯非規格*/class Not extends AbstractSpecification{protected $spec;/*** 在建構函式中傳入指定規格** @param SpecificationInterface $spec*/public function __construct(SpecificationInterface $spec){$this->spec = $spec;}/*** 返回規格的相反結果** @param Item $item** @return bool*/public function isSatisfiedBy(Item $item){return !$this->spec->isSatisfiedBy($item);}}

PriceSpecification.php

<?phpnamespace DesignPatterns\Behavioral\Specification;/*** 判斷給定Item的價格是否介於最小值和最大值之間的規格*/class PriceSpecification extends AbstractSpecification{protected $maxPrice;protected $minPrice;/*** 設定最大值** @param int $maxPrice*/public function setMaxPrice($maxPrice){$this->maxPrice = $maxPrice;}/*** 設定最小值** @param int $minPrice*/public function setMinPrice($minPrice){$this->minPrice = $minPrice;}/*** 判斷給定Item的定價是否在最小值和最大值之間** @param Item $item** @return bool*/public function isSatisfiedBy(Item $item){if (!empty($this->maxPrice) && $item->getPrice() > $this->maxPrice) {return false;}if (!empty($this->minPrice) && $item->getPrice() < $this->minPrice) {return false;}return true;}}

4、測試代碼

Tests/SpecificationTest.php

<?phpnamespace DesignPatterns\Behavioral\Specification\Tests;use DesignPatterns\Behavioral\Specification\PriceSpecification;use DesignPatterns\Behavioral\Specification\Item;/*** SpecificationTest 用於測試規格模式*/class SpecificationTest extends \PHPUnit_Framework_TestCase{public function testSimpleSpecification(){$item = new Item(100);$spec = new PriceSpecification();$this->assertTrue($spec->isSatisfiedBy($item));$spec->setMaxPrice(50);$this->assertFalse($spec->isSatisfiedBy($item));$spec->setMaxPrice(150);$this->assertTrue($spec->isSatisfiedBy($item));$spec->setMinPrice(101);$this->assertFalse($spec->isSatisfiedBy($item));$spec->setMinPrice(100);$this->assertTrue($spec->isSatisfiedBy($item));}public function testNotSpecification(){$item = new Item(100);$spec = new PriceSpecification();$not = $spec->not();$this->assertFalse($not->isSatisfiedBy($item));$spec->setMaxPrice(50);$this->assertTrue($not->isSatisfiedBy($item));$spec->setMaxPrice(150);$this->assertFalse($not->isSatisfiedBy($item));$spec->setMinPrice(101);$this->assertTrue($not->isSatisfiedBy($item));$spec->setMinPrice(100);$this->assertFalse($not->isSatisfiedBy($item));}public function testPlusSpecification(){$spec1 = new PriceSpecification();$spec2 = new PriceSpecification();$plus = $spec1->plus($spec2);$item = new Item(100);$this->assertTrue($plus->isSatisfiedBy($item));$spec1->setMaxPrice(150);$spec2->setMinPrice(50);$this->assertTrue($plus->isSatisfiedBy($item));$spec1->setMaxPrice(150);$spec2->setMinPrice(101);$this->assertFalse($plus->isSatisfiedBy($item));$spec1->setMaxPrice(99);$spec2->setMinPrice(50);$this->assertFalse($plus->isSatisfiedBy($item));}public function testEitherSpecification(){$spec1 = new PriceSpecification();$spec2 = new PriceSpecification();$either = $spec1->either($spec2);$item = new Item(100);$this->assertTrue($either->isSatisfiedBy($item));$spec1->setMaxPrice(150);$spec2->setMaxPrice(150);$this->assertTrue($either->isSatisfiedBy($item));$spec1->setMaxPrice(150);$spec2->setMaxPrice(0);$this->assertTrue($either->isSatisfiedBy($item));$spec1->setMaxPrice(0);$spec2->setMaxPrice(150);$this->assertTrue($either->isSatisfiedBy($item));$spec1->setMaxPrice(99);$spec2->setMaxPrice(99);$this->assertFalse($either->isSatisfiedBy($item));}}

以上內容是指令碼之家小編給大家分享的PHP 設計模式系列之 specification規格模式,希望本文分享能夠協助大家。

  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.