目錄
創造模式
一. 工廠方法模式
1. Eloquent ORM 模型工廠
2. 表單請求工廠
3. 服務容器中的工廠方法
二. 抽象工廠模式
1. 配置文件
2. 服務提供者
3. 門面(Facades)
4. 多環境配置
5. 依賴注入容器
三.原型模式
1. 配置對象的復制
2. 請求和響應的快速復制
3. 會話管理
4. 數據模型的快速復制
5. 緩存數據的復制
四. 建造者模式
1. 表單和HTML的構建
2. 查詢構建器
3. 郵件消息構建
4. 視圖組件和插槽
5. 集合操作
6. 表單請求驗證
五. 單例模式
1. 服務容器
2. 門面(Facades)
3. 配置和環境
4. 日志
5. 路由服務
6. 會話管理
7. 緩存管理
8. 應用實例
結構型模式
一 .享元模式
1. 配置對象的共享
2. 數據庫連接的共享
3. 緩存對象的共享
4. 會話對象的共享
5. 路由參數對象的共享
6. 視圖組件的共享
二.橋接模式
1. 服務容器和具體服務實現
2. 門面與底層服務
3. 路由和請求處理器
4. 表單請求和驗證邏輯
5. 視圖組件和視圖類
6. 事件和監聽器
7. 策略模式實現
三. 適配器模式
1. 數據庫連接適配器
2. 緩存存儲適配器
3. 隊列驅動適配器
4. 郵件發送適配器
5. 事件和監聽器
6. 服務提供者適配器
7. 第三方包集成
四. 代理模式
1. 門面(Facades)
2. 服務容器和服務提供者
3. 事件監聽器
4. 表單請求
5. 路由中間件
6. 模型事件
7. 隊列和作業
五. 外觀模式
1. 門面(Facades)
2. 服務提供者
3. 路由文件
4. 視圖組件
5. 表單宏
6. 配置文件
7. 助手函數
六. 裝飾模式
1. 中間件(Middleware)
2. 服務提供者(Service Providers)
3. 視圖組件和指令
4. 模型事件
5. 表單請求擴展
6. 資源類(Resource)
7. 緩存裝飾者
七. 組合模式
1. 分類系統
2. 權限和角色管理系統
3. 多級菜單
4. 組織結構
5. 文件系統
行為型模式
一. 模板模式
1. 控制器方法
2. 服務提供者(Service Providers)
3. 命令模式(Command Pattern)
4. 事件和監聽器
5. 郵件發送
6. 隊列作業(Queueable Jobs)
7. 測試案例
創造模式
一. 工廠方法模式
(Factory Method Pattern)是一種創建型設計模式,它提供了一種在不指定具體類的情況下創建對象的方法。這種模式允許一個類的實例化延遲到子類中進行,使得子類能夠改變一個對象的類型。
在 Laravel 框架中,工廠方法模式被廣泛應用于模型(Eloquent ORM)和請求(Form Request)的創建過程中。
1. Eloquent ORM 模型工廠
Laravel 的 Eloquent ORM 提供了一種非常方便的方式來創建和存儲數據。模型工廠用于生成測試數據。每個模型通常有一個對應的工廠類,這個類繼承自 Illuminate\Database\Eloquent\Factories\Factory
。
use Illuminate\Database\Eloquent\Factories\Factory;class UserFactory extends Factory
{/*** 定義模型的默認狀態。** @return array*/public function definition(){return ['name' => $this->faker->name,'email' => $this->faker->unique()->safeEmail,'email_verified_at' => now(),'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password'remember_token' => Str::random(10),];}
}
使用工廠生成數據:
$user = User::factory()->create();
2. 表單請求工廠
Laravel 的表單請求也支持工廠方法模式。你可以創建一個工廠類來生成表單請求的實例,這在測試時非常有用。
use Illuminate\Support\Facades\Hash;
use App\Models\User;class UserRequestFactory
{public static function create(array $attributes = []){$user = User::factory()->create($attributes);return new StoreUserRequest(['name' => $user->name,'email' => $user->email,'password' => Hash::make('password'),]);}
}
使用工廠創建請求:
$request = UserRequestFactory::create();
3. 服務容器中的工廠方法
Laravel 的服務容器也使用了工廠方法模式。你可以在服務提供者中綁定一個接口到其具體實現的工廠方法。
$this->app->bind(CacheStore::class, function ($app) {return new RedisCacheStore();
});
然后,你可以在應用程序中通過服務容器解析這個接口,得到具體的實現。
$cacheStore = app(CacheStore::class);
工廠方法模式在 Laravel 中的使用提高了代碼的可維護性和可測試性,同時也使得對象的創建更加靈活和可配置。
二. 抽象工廠模式
(Abstract Factory Pattern)是一種創建型設計模式,它允許創建一系列相關或依賴對象,而無需指定它們具體的類。這種模式提供了一種方式,可以保證客戶端使用與抽象工廠提供的接口兼容的產品族。
在 Laravel 框架中,雖然抽象工廠模式不像工廠方法模式那樣直接明顯,但是它的思想在某些方面得到了應用。以下是一些可能的抽象工廠模式的應用場景:
1. 配置文件
Laravel 的配置文件可以看作是一種抽象工廠。配置文件定義了應用程序的設置,但是具體的實現細節(如數據庫連接、緩存驅動等)可以在運行時根據配置文件來創建。
// config/database.php
return ['default' => env('DB_CONNECTION', 'mysql'),'connections' => ['mysql' => [// MySQL 連接配置],'pgsql' => [// PostgreSQL 連接配置],],
];
應用程序根據配置文件創建具體的數據庫連接:
$connection = DB::connection($connectionName);
2. 服務提供者
Laravel 的服務提供者(Service Provider)可以被視為抽象工廠的一種形式。服務提供者負責在應用程序的生命周期中注冊服務和類綁定,但是具體的實現細節是在服務提供者內部定義的。
namespace App\Providers;use Illuminate\Support\ServiceProvider;class AppServiceProvider extends ServiceProvider
{public function register(){// 注冊服務}public function boot(){// 啟動服務}
}
3. 門面(Facades)
Laravel 的門面(Facades)也可以看作是一種抽象工廠。門面提供了一個“靜態”接口來訪問更復雜的服務邏輯,而這些服務的具體實現是在服務容器中定義的。
// 使用門面訪問服務
// 使用門面訪問服務
Cache::put('key', 'value', $minutes);
4. 多環境配置
在 Laravel 中,你可以為不同的環境(如開發、測試、生產)定義不同的配置。這可以通過環境特定的配置文件實現,這些配置文件充當了抽象工廠的角色,為不同環境創建不同的配置實例。
// .env 文件
APP_ENV=local// config/app.php
return ['env' => env('APP_ENV', 'production'),
];
根據環境變量 APP_ENV
的值,應用程序將使用不同的配置。
5. 依賴注入容器
Laravel 的依賴注入容器(Service Container)本身可以被視為一個抽象工廠。容器負責創建對象的實例,但是具體的創建邏輯是在容器內部定義的,并且可以在運行時動態地改變。
$this->app->bind('MyInterface', 'MyClass');// 使用容器解析接口
$myService = app('MyInterface');
雖然 Laravel 沒有直接實現一個抽象工廠類,但是它的許多組件和設計原則都體現了抽象工廠模式的思想,即通過定義一個創建對象的接口,讓子類決定實例化哪一個類。這有助于提高代碼的靈活性和可擴展性。
三.原型模式
(Prototype Pattern)是一種創建型設計模式,它允許通過復制現有的實例(原型)來創建新的實例,而不是通過新建實例。這種模式特別適用于創建復雜對象,或者當對象的創建成本很高時。
在 Laravel 中,原型模式的應用并不像其他設計模式那樣常見,因為 Laravel 的設計哲學更傾向于使用服務容器和依賴注入來管理對象的生命周期。然而,原型模式的思想仍然可以在某些情況下被應用,尤其是在需要快速復制對象時。
以下是一些可能的原型模式應用場景:
1. 配置對象的復制
在 Laravel 中,配置對象可能包含大量的數據,創建這些對象可能代價昂貴。通過原型模式,可以首先創建一個配置對象的實例,然后復制這個實例來創建新的配置對象。
class Config {protected $data;public function __construct(array $data) {$this->data = $data;}public function cloneData() {return clone $this;}
}$config = new Config(/* 復雜數據 */);
$newConfig = $config->cloneData();
2. 請求和響應的快速復制
在處理 HTTP 請求和響應時,有時可能需要快速復制現有的請求或響應對象,以便進行修改或重用。
class Config {protected $data;public function __construct(array $data) {$this->data = $data;}public function cloneData() {return clone $this;}
}$config = new Config(/* 復雜數據 */);
$newConfig = $config->cloneData();
3. 會話管理
在會話管理中,可能需要復制會話數據以進行不同的操作,而不影響原始會話。
class Session {protected $data;public function __construct(array $data) {$this->data = $data;}public function cloneSession() {return clone $this;}
}$session = new Session(/* 會話數據 */);
$newSession = $session->cloneSession();
4. 數據模型的快速復制
在處理數據模型時,可能需要復制模型實例以進行測試或其他操作。
class Model {// 模型數據...public function cloneModel() {return clone $this;}
}$model = new Model(/* 模型數據 */);
$newModel = $model->cloneModel();
5. 緩存數據的復制
在緩存系統中,可能需要復制緩存項以進行不同的處理。
class CacheItem {protected $value;public function __construct($value) {$this->value = $value;}public function cloneCacheItem() {return clone $this;}
}$cacheItem = new CacheItem(/* 緩存數據 */);
$newCacheItem = $cacheItem->cloneCacheItem();
在 Laravel 中,雖然原型模式不是主要的設計模式,但是通過使用 PHP 的 clone
關鍵字,可以在需要時實現對象的快速復制。這種方式可以減少創建復雜對象的開銷,提高應用程序的性能。然而,需要注意的是,原型模式可能會增加內存的使用,因此在內存敏感的應用中應謹慎使用。
四. 建造者模式
(Builder Pattern)是一種創建型設計模式,用于創建一個復雜的對象,同時允許用戶只通過指定復雜對象的類型和內容就能構建它們,隱藏了內部的構建細節。
在 Laravel 中,建造者模式主要體現在幾個方面:
1. 表單和HTML的構建
Laravel 提供了一個強大的 HTML 和表單構建類,這些類使用建造者模式來創建 HTML 元素和表單。例如,使用 Form
和 Html
facades 可以構建復雜的表單和 HTML 結構。
use Illuminate\Support\Facades\Form;
use Illuminate\Support\Facades\Html;// 創建一個文本輸入框
echo Form::text('username');// 創建一個下拉選擇框
echo Form::select('gender', ['male' => 'Male', 'female' => 'Female']);// 創建一個復選框
echo Form::checkbox('terms', '1');
2. 查詢構建器
Laravel 的 Eloquent ORM 和查詢構建器(Query Builder)也使用了建造者模式。它們允許開發者以鏈式調用的方式構建復雜的數據庫查詢。
use App\Models\User;// 構建一個查詢來獲取所有活躍的用戶
$users = User::where('active', 1)->orderBy('created_at', 'desc')->get();
3. 郵件消息構建
Laravel 的郵件系統允許開發者構建郵件消息,通過鏈式方法調用設置郵件的各個部分。
use Illuminate\Support\Facades\Mail;Mail::send('emails.welcome', $data, function ($message) use ($user) {$message->to($user->email)->subject('Welcome to Our Application');
});
4. 視圖組件和插槽
Laravel 的 Blade 模板引擎支持組件和插槽,它們可以用來構建復雜的視圖結構。組件可以接收數據和方法,然后構建視圖。
<x-alert type="success">{{ $slot }}
</x-alert><x-alert type="success">@slot('default')This is a success message!@endslot
</x-alert>
5. 集合操作
Laravel 的集合類(Collection)也使用了建造者模式。集合操作允許開發者對數據集合進行鏈式操作。
use Illuminate\Support\Collection;$collection = collect([1, 2, 3, 4, 5]);
$filtered = $collection->filter(function ($value) {return $value > 2;
});
6. 表單請求驗證
Laravel 的表單請求驗證也采用了建造者模式。表單請求類允許開發者鏈式地定義驗證規則。
use Illuminate\Foundation\Http\FormRequest;class StoreBlogPost extends FormRequest
{public function rules(){return ['title' => 'required|max:255','body' => 'required',];}
}
建造者模式在 Laravel 中被廣泛使用,它提供了一種清晰和靈活的方式來構建復雜的對象和結構。通過鏈式調用,開發者可以以一種聲明性的方式構建對象,同時隱藏了實現細節,使得代碼更加簡潔和易于維護。
五. 單例模式
(Singleton Pattern)是一種創建型設計模式,它確保一個類只有一個實例,并提供一個全局訪問點來獲取這個實例。這種模式通常用于需要全局狀態或者需要頻繁訪問的資源。
在 Laravel 中,單例模式的應用主要體現在以下幾個方面:
1. 服務容器
Laravel 的服務容器(Service Container)本身就是一個單例。它在整個應用程序的生命周期中只創建一次,并被所有服務提供者和依賴注入所共享。
$app = app(); // 獲取服務容器的單例實例
2. 門面(Facades)
Laravel 的門面(Facades)提供了一個“靜態”接口來訪問服務容器中的單例服務。例如,DB
門面是數據庫服務的單例訪問點。
use Illuminate\Support\Facades\DB; DB::table('users')->get();
// 訪問數據庫服務的單例實例
3. 配置和環境
Laravel 的配置和環境設置也是單例模式的應用。配置文件在整個應用程序中只加載一次,然后被緩存起來供全局訪問。
$env = config('app.env'); // 獲取環境配置的單例數據
4. 日志
Laravel 的日志服務是另一個單例模式的例子。日志服務在整個應用程序中只實例化一次,并用于記錄日志信息。
use Illuminate\Support\Facades\Log; Log::info('This is an info message.'); // 使用日志服務的單例實例
5. 路由服務
Laravel 的路由服務也是一個單例,它負責注冊和解析應用程序的路由。
use Illuminate\Support\Facades\Route;Route::get('/', function () {return 'Hello World';
});
6. 會話管理
會話管理器(Session Manager)在 Laravel 中也是一個單例,它負責處理用戶的會話數據。
use Illuminate\Support\Facades\Session;Session::put('key', 'value'); // 操作會話數據的單例實例
7. 緩存管理
緩存管理器(Cache Manager)在 Laravel 中同樣是一個單例,用于處理緩存數據。
use Illuminate\Support\Facades\Cache;Cache::put('key', 'value', $ttl); // 使用緩存服務的單例實例
8. 應用實例
app()
函數是獲取 Laravel 應用實例的單例訪問點。
$app = app(); // 獲取 Laravel 應用的單例實例
單例模式在 Laravel 中被廣泛使用,主要是因為它提供了一種簡單的方式來管理全局狀態和資源,同時確保了資源的一致性和效率。然而,過度使用單例模式可能會導致代碼難以測試和維護,因此在設計應用程序時應謹慎考慮。
結構型模式
一 .享元模式
享元模式(Flyweight Pattern)是一種結構型設計模式,旨在通過共享來高效地管理大量細粒度的對象。這種模式非常適合于當對象的創建成本很高,或者對象數量非常多,以至于內存消耗成為問題時使用。
在 Laravel 中,享元模式的應用可能不是直接顯而易見的,因為 Laravel 的設計哲學更傾向于使用服務容器和依賴注入來管理對象的生命周期。然而,享元模式的思想可以在一些場景中得到應用,尤其是在需要高效管理大量相似對象時。
以下是一些可能的享元模式應用場景:
1. 配置對象的共享
在 Laravel 中,配置對象可能包含大量的數據,并且多個地方可能需要使用相同的配置數據。通過享元模式,可以共享相同的配置對象實例,而不是為每個使用場景創建新的實例。
class Config {protected $data;public function __construct(array $data) {$this->data = $data;}public static function getInstance(array $data) {static $instances = [];$key = md5(serialize($data));if (!isset($instances[$key])) {$instances[$key] = new self($data);}return $instances[$key];}
}$config = Config::getInstance(/* 配置數據 */);
2. 數據庫連接的共享
Laravel 的數據庫連接可以使用享元模式來共享,特別是當使用相同的連接配置時。這樣可以減少創建多個相同配置的數據庫連接的開銷。
class DatabaseConnection {// 數據庫連接邏輯
}$connection = DatabaseConnection::getInstance(/* 連接配置 */);
3. 緩存對象的共享
在 Laravel 中,緩存對象可以通過享元模式來共享,以避免重復創建相同的緩存鍵。
class CacheItem {// 緩存項邏輯
}$cacheItem = CacheItem::getInstance(/* 緩存鍵 */);
4. 會話對象的共享
會話管理中,可以使用享元模式來共享會話對象,特別是當多個用戶具有相同的會話數據時。
class Session {// 會話邏輯
}$session = Session::getInstance(/* 會話ID */);
5. 路由參數對象的共享
在處理路由時,Laravel 可以共享具有相同參數的路由對象,以減少對象創建的開銷。
class RouteParameter {// 路由參數邏輯
}$routeParameter = RouteParameter::getInstance(/* 參數數據 */);
6. 視圖組件的共享
在 Blade 模板中,可以使用享元模式來共享具有相同屬性的視圖組件。
@component('component-name', ['shared' => true])<!-- 組件內容 -->
@endcomponent
享元模式在 Laravel 中的使用可以提高應用程序的性能,尤其是在處理大量相似對象時。然而,需要注意的是,享元模式可能會導致對象狀態管理的復雜性增加,因為共享的對象需要確保它們的狀態是線程安全的,并且在多個地方使用時不會相互影響。在設計應用程序時,應該根據實際需求和上下文來決定是否使用享元模式。
二.橋接模式
(Bridge Pattern)是一種結構型設計模式,用于將抽象部分與其實現部分分離,使它們可以獨立地變化。這種模式創建了一個抽象層,允許獨立地擴展抽象和實現。
在 Laravel 中,橋接模式可以用于多種場景,尤其是在需要將功能和實現分離以提供靈活性和擴展性時。以下是一些可能的橋接模式應用場景:
1. 服務容器和具體服務實現
Laravel 的服務容器允許你將接口(抽象)與具體的服務實現分離。這使得你可以在運行時動態地替換服務的實現。
// 定義一個抽象接口
interface LoggerInterface {}// 實現該接口的具體類
class FileLogger implements LoggerInterface {}// 在服務容器中綁定接口到具體實現
$container->bind(LoggerInterface::class, FileLogger::class);// 使用時,通過接口引用具體實現
$logger = app(LoggerInterface::class);
2. 門面與底層服務
Laravel 的門面(Facades)提供了一個“靜態”接口來訪問底層服務。門面定義了抽象的接口,而具體的實現則在服務容器中。
// 定義路由
Route::get('/', 'HomeController@index');// 請求處理器實現
class HomeController
{public function index(){return 'Hello World';}
}
3. 路由和請求處理器
Laravel 的路由系統允許你將路由定義(抽象)與請求的處理邏輯(實現)分離。
// 定義路由
Route::get('/', 'HomeController@index');// 請求處理器實現
class HomeController
{public function index(){return 'Hello World';}
}
4. 表單請求和驗證邏輯
Laravel 的表單請求(Form Request)允許你將驗證邏輯(實現)與控制器(抽象)分離。
// 表單請求類作為驗證邏輯的實現
class StorePostRequest extends FormRequest
{public function rules(){return ['title' => 'required|max:255','body' => 'required',];}
}// 控制器作為抽象層
class PostController extends Controller
{public function store(StorePostRequest $request){// 驗證邏輯由 StorePostRequest 處理}
}
5. 視圖組件和視圖類
Laravel 的 Blade 模板引擎支持組件,你可以將組件的抽象定義與具體的視圖邏輯分離。
{{-- 組件類定義 --}}
@component('alert', ['type' => 'success']){{ $slot }}
@endcomponent{{-- 使用組件 --}}
<x-alert type="success">這是一個成功消息!
</x-alert>
6. 事件和監聽器
Laravel 的事件系統允許你將事件定義(抽象)與監聽器的實現分離。
// 定義事件
event(new UserRegistered($user));// 監聽器實現
class UserRegisteredHandler
{public function handle($event){// 處理邏輯}
}
7. 策略模式實現
策略模式(Strategy Pattern)通常與橋接模式結合使用,以實現算法族和封裝它們的變化獨立于使用它們的客戶端。
// 定義策略接口
interface ShippingStrategy {}// 實現策略接口的具體策略
class FedExShipping implements ShippingStrategy {}// 客戶端使用策略
class Order
{protected $shippingStrategy;public function __construct(ShippingStrategy $strategy){$this->shippingStrategy = $strategy;}public function ship(){// 使用策略}
}
橋接模式在 Laravel 中的使用提供了一種靈活的方式來組織代碼,使得抽象和實現可以獨立地變化和擴展。這種模式有助于創建更加模塊化和可維護的代碼結構。
三. 適配器模式
(Adapter Pattern)是一種結構型設計模式,它允許不兼容的接口之間能夠一起工作。通過創建一個包裝對象(適配器),它將一個類的接口轉換成客戶端期望的另一個接口。
在 Laravel 中,適配器模式的應用主要體現在以下幾個方面:
1. 數據庫連接適配器
Laravel 的 Eloquent ORM 使用適配器模式來連接不同類型的數據庫。它提供了一個統一的接口來操作數據庫,而具體的數據庫連接實現則由不同的適配器來完成。
use Illuminate\Database\Capsule\Manager as DB;$capsule = new DB;$capsule->addConnection(['driver' => 'mysql','host' => env('DB_HOST', '127.0.0.1'),'database' => env('DB_DATABASE', 'forge'),'username' => env('DB_USERNAME', 'forge'),'password' => env('DB_PASSWORD', ''),'charset' => 'utf8','collation' => 'utf8_unicode_ci','prefix' => '',
]);$capsule->setAsGlobal();
$capsule->bootEloquent();
2. 緩存存儲適配器
Laravel 的緩存系統使用適配器模式來支持多種緩存后端,例如 Redis、Memcached 或文件緩存。通過適配器,Laravel 提供了一個統一的緩存接口。
use Illuminate\Support\Facades\Cache;Cache::store('redis')->put('key', 'value', $minutes);
3. 隊列驅動適配器
Laravel 的隊列系統支持多種驅動,如數據庫、Redis、Amazon SQS 等。每個隊列驅動都是適配器模式的一個實現。
use Illuminate\Support\Facades\Queue;Queue::connection('redis')->push(new Job());
4. 郵件發送適配器
Laravel 的郵件發送功能支持多種郵件發送服務,如 SMTP、Mailgun、Sendmail 等。每個郵件發送服務都是一個適配器。
use Illuminate\Support\Facades\Mail;Mail::send('emails.welcome', $data, function ($message) use ($user) {$message->to($user->email);
});
5. 事件和監聽器
Laravel 的事件系統允許你定義事件和監聽器,適配器模式在這里可以用于將事件轉換為監聽器期望的格式或類型。
use Illuminate\Support\Facades\Event;class UserRegisteredEvent {}class UserRegisteredListener
{public function handle($event){// 處理邏輯}
}Event::listen(UserRegisteredEvent::class, UserRegisteredListener::class);
6. 服務提供者適配器
Laravel 的服務提供者(Service Provider)可以看作是一種適配器,它將服務容器與服務的注冊邏輯適配起來。
namespace App\Providers;use Illuminate\Support\ServiceProvider;class AppServiceProvider extends ServiceProvider
{public function register(){// 注冊服務}public function boot(){// 啟動服務}
}
7. 第三方包集成
在集成第三方包時,適配器模式可以用來確保第三方包的接口與 Laravel 的接口兼容。
// 第三方包的類
class SomeThirdPartyClass {}// 適配器類
class ThirdPartyAdapter implements SomeInterface
{protected $thirdPartyClass;public function __construct(SomeThirdPartyClass $thirdPartyClass){$this->thirdPartyClass = $thirdPartyClass;}// 實現接口方法,委托給第三方類public function someMethod(){// ...}
}
適配器模式在 Laravel 中的使用有助于提高應用程序的靈活性和可擴展性,它允許開發者將現有的類和第三方庫集成到 Laravel 應用程序中,而無需修改它們的源代碼。通過適配器,可以保持代碼的整潔和解耦。
四. 代理模式
(Proxy Pattern)是一種結構型設計模式,它為另一個對象提供一個代替或占位符,以控制對它的訪問。代理可以在不改變對象的代碼的情況下,增加額外的功能操作,例如延遲初始化、訪問控制、日志記錄、緩存等。
在 Laravel 中,代理模式的應用主要體現在以下幾個方面:
1. 門面(Facades)
Laravel 的門面(Facades)可以被視為一種靜態代理。門面提供了一個簡單的方式來訪問服務容器中的對象,而不需要直接從容器中解析它們。
// 使用門面來代理服務容器中的對象
use Illuminate\Support\Facades\Cache;Cache::put('key', 'value', 10);
2. 服務容器和服務提供者
Laravel 的服務容器使用代理模式來解析服務。當請求服務時,服務容器充當代理,根據配置創建或提供服務的實例。
$app = new Illuminate\Foundation\Application;// 服務容器代理服務的解析
$app->bind("SomeInterface", function($app) {return new SomeClass();
});// 請求服務時,代理將提供實例
$service = $app->make("SomeInterface");
3. 事件監聽器
Laravel 的事件系統可以看作是一種代理模式的應用。事件本身作為委托者,而事件監聽器作為實際執行操作的代理。
use Illuminate\Support\Facades\Event;class UserRegisteredEvent {}class UserRegisteredEventListener
{public function handle($event){// 處理事件}
}// 注冊事件和監聽器
Event::listen(UserRegisteredEvent::class, [UserRegisteredEventListener::class, 'handle']);
4. 表單請求
Laravel 的表單請求(Form Request)可以被視為一種代理,它封裝了驗證邏輯,并代理到控制器。
use Illuminate\Foundation\Http\FormRequest;class StorePostRequest extends FormRequest
{public function authorize(){// 授權邏輯}public function rules(){// 驗證規則}
}// 控制器中使用表單請求
public function store(StorePostRequest $request)
{// 請求已經通過驗證
}
5. 路由中間件
Laravel 的路由中間件作為請求處理流程的代理,可以執行額外的邏輯,如認證、授權等,然后再將控制權傳遞給下一個中間件或最終的請求處理器。
Route::get('/home', function () {// 首頁
})->middleware('auth');// 中間件作為代理執行認證邏輯
class AuthenticateMiddleware
{public function handle($request, $next){if (!Auth::check()) {// 未認證,執行其他邏輯}return $next($request);}
}
6. 模型事件
Laravel 的 Eloquent ORM 模型事件可以看作是一種代理模式。模型事件允許你在模型生命周期的關鍵點執行代碼,代理模型的其他操作。
class User extends Model
{protected static function boot(){parent::boot();static::creating(function ($user) {// 創建代理邏輯});}
}
7. 隊列和作業
Laravel 的隊列系統使用代理模式,作業(Job)類代理執行實際的工作,而隊列系統負責作業的調度和執行。
use Illuminate\Support\Facades\Queue;
use App\Jobs\SendEmail;// 將作業推送到隊列
Queue::push(new SendEmail);// 作業類作為代理執行發送郵件的操作
class SendEmail implements ShouldQueue
{public function handle(){// 發送郵件的邏輯}
}
五. 外觀模式
(Facade Pattern)是一種結構型設計模式,它提供了一個統一的高層接口來訪問子系統中的一群接口。外觀模式定義了一個高層接口,這個接口使得子系統更容易使用。
在 Laravel 中,外觀模式被廣泛應用于簡化應用程序中復雜邏輯的訪問。以下是 Laravel 中外觀模式的一些具體應用:
1. 門面(Facades)
Laravel 的門面是外觀模式的一個典型例子。門面提供了一個簡單、靜態的接口來訪問服務容器中的服務,隱藏了底層的復雜性。
// 使用門面訪問服務容器中的服務
use Illuminate\Support\Facades\Cache;Cache::put('key', 'value', 10);
2. 服務提供者
Laravel 的服務提供者(Service Provider)也使用了外觀模式。服務提供者定義了應用程序啟動時需要執行的任務的高層接口,例如注冊服務、事件監聽器等。
namespace App\Providers;use Illuminate\Support\ServiceProvider;class AppServiceProvider extends ServiceProvider
{public function register(){// 注冊服務}public function boot(){// 啟動服務}
}
3. 路由文件
Laravel 的路由文件(如 web.php
和 api.php
)作為外觀模式,提供了一個集中的地方來定義所有請求的路由和控制器。
use Illuminate\Support\Facades\Route;// 定義路由
Route::get('/', function () {return view('welcome');
});
4. 視圖組件
Laravel 的 Blade 模板引擎支持組件,這些組件可以看作是外觀模式的實現,提供了一個簡單的接口來封裝復雜的視圖邏輯。
{{-- 使用組件 --}}
<x-alert type="success" :messages="$messages" />
5. 表單宏
LaravelCollective 提供的宏(Macros)允許開發者擴展現有的門面功能,通過外觀模式封裝復雜的表單創建邏輯。
use Collective\Html\FormFacade as Form;// 創建表單
{{ Form::open(['url' => 'post/create']) }}{{ Form::text('title') }}{{ Form::submit('Create') }}
{{ Form::close() }}
6. 配置文件
Laravel 的配置文件作為外觀模式,提供了一個簡單的接口來訪問應用程序的配置設置。
// 訪問配置
$debug = config('app.debug');
7. 助手函數
Laravel 提供了許多助手函數,這些函數作為外觀模式,簡化了常見的操作,如生成 URL、加密等。
// 生成 URL
$url = url('user/profile');
外觀模式在 Laravel 中的使用,極大地簡化了應用程序的復雜性,使得開發者可以更加專注于業務邏輯,而不必深入了解底層的實現細節。通過提供高層的接口,外觀模式幫助開發者更容易地使用 Laravel 的強大功能。
六. 裝飾模式
(Decorator Pattern)是一種結構型設計模式,允許用戶向一個對象添加新的功能,同時不改變其結構。這種模式通過創建一個包裝對象,包裹實際對象,來擴展對象的功能。
在 Laravel 中,裝飾模式的應用可能不如其他模式那樣明顯,但是它的思想可以在多個地方找到。以下是一些可能的裝飾模式應用場景:
1. 中間件(Middleware)
Laravel 的中間件可以被視為裝飾模式的實現。中間件包裝了 HTTP 請求的生命周期,可以在請求處理前后添加額外的行為。
namespace App\Http\Middleware;use Closure;class ExampleMiddleware
{public function handle($request, Closure $next){// 在處理請求之前添加邏輯return $next($request);// 在處理請求之后添加邏輯}
}
2. 服務提供者(Service Providers)
服務提供者在 Laravel 中用于進行服務注冊和啟動邏輯,它們也可以被視為裝飾者,因為它們擴展了應用程序的功能。
namespace App\Providers;use Illuminate\Support\ServiceProvider;class AppServiceProvider extends ServiceProvider
{public function register(){// 注冊服務}public function boot(){// 啟動服務}
}
3. 視圖組件和指令
Laravel 的 Blade 模板引擎支持組件和指令,這些組件可以看作是裝飾者,因為它們擴展了視圖的功能。
{{-- 使用 Blade 組件 --}}
<x-alert type="error" :messages="$errorMessages" />
4. 模型事件
Eloquent ORM 的模型事件允許在模型的生命周期中插入額外的行為,這可以被視為裝飾模式的一種形式。
class User extends Model
{protected static function boot(){parent::boot();static::created(function ($user) {// 用戶創建后添加的邏輯});}
}
5. 表單請求擴展
表單請求可以擴展現有的驗證邏輯,通過裝飾模式添加額外的驗證規則或授權檢查。
class StorePostRequest extends FormRequest
{public function rules(){return ['title' => 'required|max:255',// 添加額外的規則];}
}
6. 資源類(Resource)
API 資源類可以被視為裝飾者,因為它們擴展了模型數據的表示方式,為 JSON 或其他格式的響應添加了額外的結構。
use Illuminate\Http\Resources\Json\JsonResource;class UserResource extends JsonResource
{public function toArray($request){return ['id' => $this->id,'name' => $this->name,// 添加額外的數據];}
}
7. 緩存裝飾者
Laravel 的緩存裝飾者可以用于延遲初始化或增強緩存邏輯。
use Illuminate\Cache\CacheManager;$cache = app('cache');
$decoratedCache = new SomeCacheDecorator($cache);
裝飾模式在 Laravel 中的使用提高了代碼的靈活性和可擴展性,允許開發者在不修改現有代碼的情況下添加新功能。這種模式有助于保持代碼的整潔和關注點分離。
七. 組合模式
(Composite Pattern)是一種結構型設計模式,它允許你將對象組合成樹形結構,以表示“部分-整體”的層次結構。組合模式使得用戶對單個對象和組合對象的使用具有一致性。
在 Laravel 中,組合模式可以用于多種場景,尤其是在需要表示層次結構數據時。以下是一些可能的組合模式應用場景:
1. 分類系統
如果你的應用程序有一個復雜的分類系統,你可以使用組合模式來表示這些分類。每個分類可以作為一個葉節點或組合節點。
class Category
{protected $name;protected $children = [];public function __construct($name){$this->name = $name;}public function add(Category $category){$this->children[] = $category;}public function remove(Category $category){// 邏輯來從 children 中移除一個分類}public function display(){foreach ($this->children as $child) {echo $child->name;$child->display();}}
}
2. 權限和角色管理系統
在權限和角色管理中,可以使用組合模式來表示不同角色可以擁有的權限集合。
class Permission
{// 權限邏輯
}class Role
{protected $name;protected $permissions = [];public function __construct($name){$this->name = $name;}public function addPermission(Permission $permission){$this->permissions[] = $permission;}// 其他角色相關邏輯
}
3. 多級菜單
如果你的應用程序有一個多級菜單系統,組合模式可以用來構建和顯示菜單項。
class MenuItem
{protected $title;protected $items = [];public function __construct($title){$this->title = $title;}public function add($item){$this->items[] = $item;}public function render(){// 渲染當前菜單項和子菜單項}
}
4. 組織結構
在表示公司的組織結構時,可以使用組合模式來表示不同層級的員工和團隊。
class Employee
{protected $name;protected $subordinates = [];public function __construct($name){$this->name = $name;}public function addSubordinate(Employee $employee){$this->subordinates[] = $employee;}public function report(){// 生成報告}
}
5. 文件系統
在模擬文件系統時,可以使用組合模式來表示文件和文件夾的層次結構。
interface FileSystemElement
{public function delete();public function rename($newName);
}class Folder implements FileSystemElement
{protected $name;protected $elements = [];public function __construct($name){$this->name = $name;}public function add(FileSystemElement $element){$this->elements[] = $element;}// 實現 FileSystemElement 接口的方法
}class File implements FileSystemElement
{protected $name;public function __construct($name){$this->name = $name;}// 實現 FileSystemElement 接口的方法
}
組合模式在 Laravel 中的使用有助于簡化對層次結構數據的操作,使得你可以統一地對待單個對象和組合對象。這種模式提高了代碼的復用性,并使得層次結構的管理更加靈活和強大。
行為型模式
一. 模板模式
(Template Pattern)是一種行為型設計模式,它定義了算法的骨架,將一些步驟的執行延遲到子類中。模板方法使得子類可以在不改變算法結構的情況下,重新定義算法的某些特定步驟。
在 Laravel 中,模板模式的概念被廣泛應用,尤其是在框架的架構和組件設計中。以下是一些可能的模板模式應用場景:
1. 控制器方法
Laravel 控制器中的某些方法可以看作是模板方法。例如,資源控制器的方法遵循一個標準的 CRUD 模式。
class UserController extends Controller
{// 展示用戶列表public function index(){// ...}// 展示單個用戶public function show($id){// ...}// 創建新的用戶頁面public function create(){// ...}// 存儲新用戶public function store(Request $request){// ...}// 編輯用戶頁面public function edit($id){// ...}// 更新用戶public function update(Request $request, $id){// ...}// 刪除用戶public function destroy($id){// ...}
}
2. 服務提供者(Service Providers)
服務提供者的 register
和 boot
方法遵循模板模式,允許開發者在這些方法中定義服務的注冊和啟動邏輯。
class AppServiceProvider extends ServiceProvider
{public function register(){// 注冊服務到服務容器}public function boot(){// 執行啟動邏輯,如事件注冊、路由定義等}
}
3. 命令模式(Command Pattern)
Laravel 的 Artisan 命令行工具使用模板模式來定義命令的結構。每個命令類都遵循一個模板,包括 handle
方法作為算法的骨架。
class GenerateReportCommand extends Command
{protected $signature = 'report:generate';protected $description = 'Generate a report';public function handle(){// 執行報告生成的邏輯}
}
4. 事件和監聽器
Laravel 的事件監聽器可以被視為遵循模板模式,每個監聽器類都有一個 handle
方法,這是事件處理的模板方法。
class UserRegisteredEvent
{// ...public function handle(User $user){// 用戶注冊后的邏輯}
}
5. 郵件發送
Laravel 的郵件發送類也遵循模板模式,允許開發者定義郵件發送的邏輯。
class SendWelcomeEmail extends Mailable
{public function build(){return $this->view('emails.welcome')->with([// 郵件數據]);}
}
6. 隊列作業(Queueable Jobs)
Laravel 的隊列作業遵循模板模式,特別是當它們使用 shouldQueue
方法時。作業的執行邏輯在 handle
方法中定義。
class SendEmailJob implements ShouldQueue
{public function handle(){// 發送郵件的邏輯}
}
7. 測試案例
Laravel 的測試案例也遵循模板模式,測試方法 testMethodName
是測試算法的模板方法。
class ExampleTest extends TestCase
{public function testBasicTest(){// 測試邏輯}
}
模板模式在 Laravel 中的使用有助于保持代碼的一致性和可維護性,允許開發者集中定義算法的骨架,同時提供靈活性以適應不同的實現需求。這種模式非常適合于創建一系列的相似對象,它們遵循相同的算法但包含不同的實現細節。
還有10種行為模式,后續補上。希望能給大家帶來一些收獲。