流暢介面,常用於撰寫如同文章般容易閱讀的程式碼,如果以大頭菜來講,那麼在建立大頭菜的同時,希望可以順便賦予其鈴錢價格、數量,並且最終獲得的依舊是大頭菜物件。
什麼是流暢介面#
核心概念#
流暢介面核心概念
流暢介面(Fluent Interface)是一種設計模式,它提供鏈式調用的方式來撰寫可讀性更好的程式碼。每個方法都返回物件本身,從而允許多個方法調用連續在一起。
使用時機#
適用情境
- 需要提供直觀、易讀的 API
- 想要減少物件建構的複雜性
- 需要支援鏈式調用(Method Chaining)
- 適用於配置類別或建置器模式
- 想讓程式碼讀起來像自然語言
UML#

實作#
建立流暢介面類別(Fluent Interface Class)#
流暢介面設計重點
這次只需要實作一個大頭菜物件,其精隨在於賦予鈴錢價格、數量時,最後會將整個物件再回傳出來,透過被呼叫的方法來回傳當前物件。這種設計讓方法能夠鏈式調用。
Turnips.php#
/**
* Class Turnips.
*/
class Turnips
{
/**
* @var int
*/
protected $price = 0;
/**
* @var int
*/
protected $count = 0;
/**
* @param int $price
*
* @return Turnips
*/
public function price(int $price): Turnips
{
$this->price = $price;
return $this;
}
/**
* @param int $count
*
* @return Turnips
*/
public function count(int $count): Turnips
{
$this->count = $count;
return $this;
}
/**
* @return int
*/
public function calculatePrice(): int
{
return $this->price * $this->count;
}
}
測試#
測試目標#
測試清單
我們要來實際測試大頭菜是否能夠以流暢介面的方式來建立物件,驗證流暢介面的鏈式調用機制:
- 鏈式調用測試: 測試是否能夠使用鏈式調用來設定屬性值
- 物件返回測試: 驗證每個方法都返回物件本身
- 功能測試: 測試最終的計算結果是否正確
- 可讀性測試: 驗證程式碼的可讀性和流暢性
測試程式碼#
FluentInterfaceTest.php#
/**
* Class FluentInterfaceTest.
*/
class FluentInterfaceTest extends TestCase
{
/**
* @test
*/
public function test_build_turnips()
{
$turnips = (new Turnips())
->price(100)
->count(40);
$this->assertEquals(4000, $turnips->calculatePrice());
}
}
測試結果#
最後測試的執行結果會獲得如下:
PHPUnit Pretty Result Printer 0.28.0 by Codedungeon and contributors.
==> Configuration: ~/php-design-pattern/vendor/codedungeon/phpunit-result-printer/src/phpunit-printer.yml
PHPUnit 9.2.6 by Sebastian Bergmann and contributors.
==> AbstractFactoryTest ✔ ✔ ✔ ✔
==> BuilderPatternTest ✔ ✔ ✔ ✔
==> FactoryMethodTest ✔ ✔ ✔ ✔
==> PoolPatternTest ✔ ✔
==> PrototypePatternTest ✔ ✔
==> SimpleFactoryTest ✔ ✔ ✔ ✔
==> SingletonPatternTest ✔
==> StaticFactoryTest ✔ ✔ ✔ ✔ ✔
==> AdapterPatternTest ✔ ✔
==> BridgePatternTest ✔ ✔ ✔
==> CompositePatternTest ✔ ✔ ✔
==> DataMapperTest ✔ ✔
==> DecoratorPatternTest ✔ ✔
==> DependencyInjectionTest ✔ ✔ ✔
==> FacadePatternTest ✔
==> FluentInterfaceTest ✔
Time: 00:00.079, Memory: 6.00 MB
OK (43 tests, 94 assertions)