1. Facade Pattern là gì
Facade Pattern là một trong những Pattern thuộc nhóm cấu trúc (Structural Pattern). Pattern này cung cấp một giao diện chung đơn giản thay cho một nhóm các giao diện có trong một hệ thống con (subsystem). Facade Pattern định nghĩa một giao diện ở một cấp độ cao hơn để giúp cho người dùng có thể dễ dàng sử dụng hệ thống con này.
Facade Pattern cho phép các đối tượng truy cập trực tiếp giao diện chung này để giao tiếp với các giao diện có trong hệ thống con. Mục tiêu là che giấu các hoạt động phức tạp bên trong hệ thống con, làm cho hệ thống con dễ sử dụng hơn.
2. Cài đặt Facade Pattern như thế nào?

Các thành phần cơ bản của một Facade Pattern:
- Facade: biết rõ lớp của hệ thống con nào đảm nhận việc đáp ứng yêu cầu của client, sẽ chuyển yêu cầu của client đến các đối tượng của hệ thống con tương ứng.
- Subsystems: cài đặt các chức năng của hệ thống con, xử lý công việc được gọi bởi Facade. Các lớp này không cần biết Facade và không tham chiếu đến nó.
- Client: đối tượng sử dụng Facade để tương tác với các subsystem.
Các đối tượng Facade thường là Singleton bởi vì chỉ cần duy nhất một đối tượng Facade.
Ví Dụ: Một công ty bán hàng online cung cấp nhiều lựa chọn cho khách hàng khi mua sản phẩm. Khi một sản phẩm được mua, nó sẽ qua các bước xử lý: lấy thông tin tài khoản, sản phẩm, tạo đơn hàng, gửi email hoặc sms thông báo, vận chuyển.
Ứng dụng của chúng ta được thiết kế với Facade Pattern, bao gồm các class như sau:
- UserFacade: lấy thông tin tài khoản.
- ProductFacade: lấy thông tin sản phẩm.
- OrderFacade: lưu thông tin đơn hàng.
- ContactFacade: gửi email hoặc sms cho khách hàng.
- ShopFacade: class này bao gồm các dịch vụ có bên trong hệ thống. Nó cung cấp một vài phương thức để Client có thể dễ dàng mua hàng. Tùy vào nghiệp vụ mà nó sẽ sử dụng những dịch tương ứng, chẳng hạn nếu thông tin khách hàng có số điện thoại thì ưu tiên gửi thông báo bằng sms.
- Client: là người dùng cuối sử dụng ShopFacade để mua hàng.

UserFacade
<?php
class UserFacade
{
public function find($filter)
{
return 'user';
}
}
ProductFacade
<?php
class ProductFacade
{
public function find($filter)
{
return 'products';
}
}
ContactFacade
<?php
class ContractFacade
{
public function sendSMS($data, $user)
{
return 'sms sent';
}
public function sendEmail($data, $user)
{
return 'email sent';
}
}
OrderFacade
<?php
class OrderFacade
{
public function create($data)
{
return 'order created';
}
}
ShopFacade
<?php
use ContractFacade;
use OrderFacade;
use PaymentFacade;
use UserFacade;
use ProductFacade;
class ShopFacade
{
$contractFacade;
$orderFacade;
$paymentFacade;
$userFacade;
$productFacade;
public function contractFacade()
{
if (!emtpy($this->contractFacade)) {
return $this->contractFacade;
} else{
return new ContractFacade();
}
}
public function orderFacade()
{
if (!emtpy($this->orderFacade)) {
return $this->orderFacade;
} else{
return new OrderFacade();
}
}
public function paymentFacade()
{
if (!emtpy($this->paymentFacade)) {
return $this->paymentFacade;
} else{
return new PaymentFacade();
}
}
public function userFacade()
{
if (!emtpy($this->userFacade)) {
return $this->userFacade;
} else{
return new UserFacade();
}
}
public function productFacade()
{
if (!emtpy($this->productFacade)) {
return $this->productFacade;
} else{
return new ProductFacade();
}
}
public function createOrder($data)
{
$user = $this->userFacade()->find($data);
$products = $this->productFacade()->find($data);
$order = $this->orderFacade()->create($data);
if ($user->phone) {
$this->contractFacade()->sendSms($order, $user);
} else {
$this->contractFacade()->sendEmail($order, $user);
}
return 'order created';
}
}
Như bạn thấy phía Client chỉ sử dụng một phương thức duy nhất là có thể mua được sản phẩm mặc dù bên dưới hệ thống có rất nhiều dịch vụ xử lý khác nhau. Nếu không có Facade, phía Client sẽ không biết sử dụng những dịch vụ nào để có thể mua được sản phẩm. Khi phát sinh thêm một dịch vụ sẽ rất khó khăn khi sửa đổi và code phía Client cũng sẽ bị ảnh hưởng.
3. Lợi ích của Facade Pattern là gì?
- Giúp cho hệ thống của bạn trở nên đơn giản hơn trong việc sử dụng và trong việc hiểu nó, vì một mẫu Facade có các phương thức tiện lợi cho các tác vụ chung.
- Giảm sự phụ thuộc của các mã code bên ngoài với hiện thực bên trong của thư viện, vì hầu hết các code đều dùng Facade, vì thế cho phép sự linh động trong phát triển các hệ thống.
- Đóng gói tập nhiều hàm API được thiết kế không tốt bằng một hàm API đơn có thiết kế tốt hơn.
4. Sử dụng Facade Pattern khi nào?
- Khi hệ thống có rất nhiều lớp làm người sử dụng rất khó để có thể hiểu được quy trình xử lý của chương trình. Và khi có rất nhiều hệ thống con mà mỗi hệ thống con đó lại có những giao diện riêng lẻ của nó nên rất khó cho việc sử dụng phối hợp. Khi đó có thể sử dụng Facade Pattern để tạo ra một giao diện đơn giản cho người sử dụng một hệ thống phức tạp.
- Khi người sử dụng phụ thuộc nhiều vào các lớp cài đặt. Việc áp dụng Façade Pattern sẽ tách biệt hệ thống con của người dùng và các hệ thống con khác, do đó tăng khả năng độc lập và khả chuyển của hệ thống con, dễ chuyển đổi nâng cấp trong tương lai.
- Khi bạn muốn phân lớp các hệ thống con. Dùng Facade Pattern để định nghĩa cổng giao tiếp chung cho mỗi hệ thống con, do đó giúp giảm sự phụ thuộc của các hệ thống con vì các hệ thống này chỉ giao tiếp với nhau thông qua các cổng giao diện chung đó.
- Khi bạn muốn bao bọc, che giấu tính phức tạp trong các hệ thống con đối với phía Client.









(3 lượt thả tim)



