() translation by (you can also view the original English article)
Khi mới bắt đầu với Design Patterns, bạn có những câu hỏi:
Tại sao chúng ta nên dùng Design patterns trong chương trình? Ứng dụng của bạn có thể chạy bình thường mà không cần nó.
Chưa cần quan tâm tới nó, đây là câu hỏi tiếp theo: "Bạn muốn sống trong một ngôi nhà với tiên nghi sang trọng, hay trong một căn phòng tồi tàn với bốn bức tường?" Cuối cùng, cả hai câu hỏi đều phục cho mục đích của chúng ta.
Thông thường, chúng ta thích một ngôi nhà sang trọng bởi vì nó cung cấp đầy đủ tiện nghi hơn và ít yêu câu bảo dưỡng hơn, và sự bảo dưỡng có thể làm với rắc rốt ít hơn chính bở vì nền tảng cơ bản đã có sẵn.
Giống như mọi thứ được áp dụng trong lập trình: Mã nguồn có sử dụng Design Patterns thì dễ hiểu, dễ bảo trì và dễ dàng mở rộng.
Trong loạt bài hướng dẫn này. Chúng ta sẽ bao quát các Desing Patterns khác nhau sẵn sàng sử dụng trong lập trình. Bạn sẽ học về các ưu điểm và nhược điểm, và các nhân tố chỉ rõ ở đâu bạn nên sử dụng chúng.
Trong suốt những bài hướng dẫn này, tôi sẽ lấy PHP như một ngôn ngữ nền tảng để chúng minh về Design Patterns; Tuy nhiên, chúng thực sự là một khái niệm có thể được áp dụng cho bất kỳ ngôn ngữ lập trình nào - chỉ bằng cách thay đổi cú pháp theo ngôn ngữ yêu thích của bạn
Quy tắc Design được chia ra làm bốn loại:
- Creational Patterns
- Structural Patterns
- Behavioral Patterns
- Concurrency Patterns
Trong hướng dẫn này chúng ta sẽ khái quát về [Face Design Patterns] Nó rơi vào mục của [Structural Patterns] bở vì nó thảo thuyết về cấu trúc mã nguồn của bạn nên như thế nào để dễ hiểu và bảo toàn nó trong suốt thời gian bảo trì.
Facede Design Pattern
Mô hình UML



Vấn đề
Nào hãy giả định rằng bạn có một vài thao tác được làm theo một trình tự, và hành động tượng tự được yêu cầu ở nhiều nơi trong ứng dụng của bạn. Bạn phải đặt đoạn mã lặp đi lặp lại ở nhiều nơi khác nhau. Bạn đã làm điều đó nhưng sau vài ngày bạn thấy một vài thứ cần tahy đổi trong mã nguồn.
Bạn có nhìn thấy vấn đề không? Chúng ta phải thay đổi ở những chỗ tồn tại mã nguồn. Đau thật phải không nào?
Giải pháp
Như một giải pháp, bạn nên làm cái gì để tạo một controller điều phối kiểm soát tất cả các mã nguồn lặp lại này. Từ góc nhìn này chúng ta sẽ gọi một controller điều điều phối để thực hiện hành động dựa trên sự cung cấp parameters.
Nào bây giờ nếu chúng ta cần trình bất kể sự thay đổi nào trong xử lý chúng ta chỉ cần thay đổi controller điều hướng thay vì thay đổi tất cả ở những nơi chúng ta đã sử dụng đoạn mã nguồn đó.
Ví dụ
Trong bài học này, hãy chọn một bài học để làm cho mọi thứ dễ xem hơn. Hãy nói rằng bạn đã có một nhiệm vụ lên kế hoạch cho ngày cưới của người bạn. Nếu bạn tự làm mọi thứ, sau đó tưởng tượng mọi thứ bạn cần bao quát. Nó có khả năng gây ra lỗi cao hơn, và làm tăng sự khả năng thiếu sót có thể ảnh hưởng dữ dội đến đám cưới của người bạn.
Trong trường hợp này, thay vì bạn làm mọi thứ, bạn nên sử dụng người lên kế hoạch cưới và chắc chắn công việc được thực hiện quản lý tốt với ít cơ hội rủ ro thấp nhất.
Ở đây, bạn đang có hành vi như một "Client" người bắt đầu quá trình, và người tổ chức đám cưới đang làm việc như một "Facade" cho bạn, hoàn thành công việc dựa trên sự chỉ đạo của bạn.
Ví dụ mã nguồn
Trong phần này bạn sẽ thấy một ví dụ khác, điều này rất phổ biến trong nhiều trang web, dĩ nhiên là với một ví dụ mã nguồn. Chúng ta sẽ nhìn thấy sự thực thi của "Facede Design Pattern" dùng xử lý thanh toán một sản phẩm. Nhưng trước khi kiểm tra đoạn mã hoàn hảo với "Facede pattern" hãy xem qua một vài đoạn mã có vấn đề.
Một xử lý thanh toán đơn giản bao gồm các bước như sau:
- Đưa sản phẩn đến giỏ hàng
- Tính toán chi phí vận chuyển.
- Tính toán ưu đãi.
- Tạo đơn đặt hàng.
Vấn đề
1 |
// Simple CheckOut Process |
2 |
$productID = $_GET['productId']; |
3 |
|
4 |
$qtyCheck = new productQty(); |
5 |
|
6 |
if($qtyCheck->checkQty($productID) > 0) { |
7 |
|
8 |
// Add Product to Cart |
9 |
$addToCart = new addToCart($productID); |
10 |
|
11 |
// Calculate Shipping Charge |
12 |
$shipping = new shippingCharge(); |
13 |
$shipping->updateCharge(); |
14 |
|
15 |
// Calculate Discount Based on |
16 |
$discount = new discount(); |
17 |
$discount->applyDiscount(); |
18 |
|
19 |
$order = new order(); |
20 |
$order->generateOrder(); |
21 |
}
|
Trong đoạn code ở trên, bạn sẽ tìm thấy thủ tục thanh toán bao gồm các đối tượng khác nhau cần xử lý để hoàn thành hóa đơn thanh toán. Tưởng tượng rằng bạn cần phải thực thi đoạn xử lý thanh toán này ở nhiều nơi. Nếu trong trương hợp nó là vấn đền khi đoạn mã cần được chỉnh sửa. Nó trở nên tốt hơn khi tất cả sự thay đổi chỉ đặt ở một chỗ.
Giải pháp
Chúng ta sẽ viết mọi thứ giống với "Facade pattern", việc này làm đoạn mã dễ bảo trì và mở rộng hơn.
1 |
class productOrderFacade { |
2 |
|
3 |
public $productID = ''; |
4 |
|
5 |
public function __construct($pID) { |
6 |
$this->productID = $pID; |
7 |
}
|
8 |
|
9 |
public function generateOrder() { |
10 |
|
11 |
if($this->qtyCheck()) { |
12 |
|
13 |
// Add Product to Cart
|
14 |
$this->addToCart(); |
15 |
|
16 |
// Calculate Shipping Charge
|
17 |
$this->calulateShipping(); |
18 |
|
19 |
// Calculate Discount if any
|
20 |
$this->applyDiscount(); |
21 |
|
22 |
// Place and confirm Order
|
23 |
$this->placeOrder(); |
24 |
|
25 |
}
|
26 |
|
27 |
}
|
28 |
|
29 |
private function addToCart () { |
30 |
/* .. add product to cart .. */
|
31 |
}
|
32 |
|
33 |
private function qtyCheck() { |
34 |
|
35 |
$qty = 'get product quantity from database'; |
36 |
|
37 |
if($qty > 0) { |
38 |
return true; |
39 |
} else { |
40 |
return true; |
41 |
}
|
42 |
}
|
43 |
|
44 |
|
45 |
private function calulateShipping() { |
46 |
$shipping = new shippingCharge(); |
47 |
$shipping->calculateCharge(); |
48 |
}
|
49 |
|
50 |
private function applyDiscount() { |
51 |
$discount = new discount(); |
52 |
$discount->applyDiscount(); |
53 |
}
|
54 |
|
55 |
private function placeOrder() { |
56 |
$order = new order(); |
57 |
$order->generateOrder(); |
58 |
}
|
59 |
}
|
Bây giờ, chúng ta có hóa đơn sản phẩm "Facade". Mọi thứ chúng ta phải làm là sử dụng nó với một vài kênh truyền thông của mã nguồn, thay vì là một nhóm mã nguồn như đã thể hiện trong phần trước.
Vui lòng kiểm tra mã nguồn dưới đây, cái bạn cần đầu tư trong xử lý hóa đơn thanh toán tại nhiều điểm.
1 |
// Note: We should not use direct get values for Database queries to prevent SQL injection
|
2 |
$productID = $_GET['productId']; |
3 |
|
4 |
// Just 2 lines of code in all places, instead of a lengthy process everywhere
|
5 |
$order = new productOrderFacade($productID); |
6 |
$order->generateOrder(); |
Nào bây giờ tưởng tượng bạn cần thay đổi trong xử lý thanh toán của bạn. Bây giờ đơn giản là bạn thay đổi trong lớp "Facade" chúng ta đã tạo, khá hơn là thay đổi trong mỗi nơi mà nó đã áp dụng.
Lợi ích
Điều đơn giản chúng ta có thể nói rằng "Facade Pattern" được thực hiện trong một tình huống nơi bạn cần một "Single Interface" để hoàn thành nhiều xử lý, như ví dụ về người tổ chức đám cưới, người đó làm việc như một "facade" giúp bạn hoàn thành nhiều xử lý.
Xin vui lòng để lại bất cứ comments hay câu hỏi trong phần cung cấp dưới đây.