Design Pattern là một kỹ thuật dành cho lập trình hướng đối tượng. Nó cung cấp cho ta cách tư duy trong từng tình huống của việc lập trình hướng đối tượng, và phân tích thiết kế hệ thống phần mềm. Nó cần thiết cho cả các nhà lập trình và nhà phân tích thiết kế. Đối với những người chuyên về lập trình thì việc nắm vững công cụ lập trình thôi chưa đủ, họ cần phải có một tư duy, một kỹ năng giải quyết các tình huống nhỏ của công việc xây dựng phần mềm mà họ là người thi hành. Việc giải quyết này phải đảm bảo tính ổn định là họ có thể giải quyết được trong mọi tình huống, với thời gian đúng tiến độ, phương pháp giải quyết hợp lý và đặc biệt là phải theo một chuẩn nhất định. Những nhà phân tích thiết kế mức cao, việc nắm vững công cụ lập trình có thể là không cần thiết, nhưng họ cũng cần phải biết được ở những khâu nhỏ nhất chi tiết nhất của thiết kế của họ đưa ra có thể thực hiện được hay không và nếu thực hiện được thì có thể thực hiện như thế nào, và sẽ theo một chuẩn ra sao. Design pattern được dùng khắp ở mọi nơi, trong các phần mềm hướng đối tượng các hệ thống lớn. Trong các chương trình trò chơi, … Và cả trong các hệ thống tính toán song song,.. Design pattern thể hiện tính kinh nghiệm của công việc lập trình, xây dựng và thiết kế phần mềm.Có thể chúng ta đã gặp design pattern ở đâu đó, trong các ứng dụng, cũng có thể chúng ta đã từng sử dụng những mẫu tương tự như design pattern để giải quyết những tình huống của mình, nhưng chúng ta không có một khái niệm gì về nó cả.
Trang 1BỘ GIÁO DỤC VÀ ĐÀO TẠO
TRƯỜNG ĐẠI HỌC CÔNG NGHIỆP HÀ HỘI
KHOA CÔNG NGHỆ THÔNG TIN
BÀI TẬP LỚN
MÔN HỌC: DESGIN PATTERNS
ĐỀ TÀI: Mẫu Decorator
Lớp: ĐH KTPM CLC – K8
Sinh viên thực hiện:
1 Đỗ Văn Trường - 0841360083
Giáo viên hướng dẫn: Ths PHÙNG ĐỨC HÒA
2015
Trang 2Mục Lục
TỔNG QUAN VỀ DEGSIN PATTERNS 3
Phần I: Giới Thiệu Mẫu Decorator 5
I Vấn đề đặt ra 5
a Định nghĩa 6
b Sơ đồ UML 6
c Mẫu Decorator đươc sử dụng khi nào ? 7
d Decorator, Adapter và Composite: 7
e Ưu - Nhược điểm của mẫu Decorator 8
f Ví dụ 9
TỔNG KẾT 14
Trang 3TỔNG QUAN VỀ DEGSIN PATTERNS
Design Pattern là một kỹ thuật dành cho lập trình hướng đối tượng Nó cung cấp cho ta cách tư duy trong từng tình huống của việc lập trình hướng đối tượng, và phân tích thiết
kế hệ thống phần mềm Nó cần thiết cho cả các nhà lập trình và nhà phân tích thiết kế Đối với những người chuyên về lập trình thì việc nắm vững công cụ lập trình thôi chưa
đủ, họ cần phải có một tư duy, một kỹ năng giải quyết các tình huống nhỏ của công việc xây dựng phần mềm mà họ là người thi hành Việc giải quyết này phải đảm bảo tính ổn định là họ có thể giải quyết được trong mọi tình huống, với thời gian đúng tiến độ, phương pháp giải quyết hợp lý và đặc biệt là phải theo một chuẩn nhất định
Những nhà phân tích thiết kế mức cao, việc nắm vững công cụ lập trình có thể là không cần thiết, nhưng họ cũng cần phải biết được ở những khâu nhỏ nhất chi tiết nhất của thiết
kế của họ đưa ra có thể thực hiện được hay không và nếu thực hiện được thì có thể thực hiện như thế nào, và sẽ theo một chuẩn ra sao
Design pattern được dùng khắp ở mọi nơi, trong các phần mềm hướng đối tượng các hệ thống lớn Trong các chương trình trò chơi, … Và cả trong các hệ thống tính toán song song,
Design pattern thể hiện tính kinh nghiệm của công việc lập trình, xây dựng và thiết kế phần mềm.Có thể chúng ta đã gặp design pattern ở đâu đó, trong các ứng dụng, cũng có thể chúng ta đã từng sử dụng những mẫu tương tự như design pattern để giải quyết những tình huống của mình, nhưng chúng ta không có một khái niệm gì về nó cả
Trang 4Design Pattern là gì?
Design patterns là tập các giải pháp cho cho vấn đề phổ biến trong thiết kế các hệ thống máy tính Đây là tập các giải pháp đã được công nhận là tài liệu có giá trị, những người phát triển có thể áp dụng giải pháp này để giải quyết các vấn đề tương tự.Giống như với các yêu cầu của thiết kế và phân tích hướng đối tượng (nhằm đạt được khả năng sử dụng các thành phần và thư viện lớp), việc sử dụng các mẫu cũng cần phải đạt được khả năng tái sử dụng các giải pháp chuẩn đối với vấn đề thường xuyên xảy ra
Tại sao sử dụng Design Pattern?
Design pattern cung cấp giải pháp ở dạng tổng quát, giúp tăng tốc độ phát triển phần mềm bằng cách đưa ra các mô hình test, mô hình phát triển đã qua kiểm nghiệm Thiết kế phần mềm hiệu quả đòi hỏi phải cân nhắc các vấn đề sẽ nảy sinh trong quá trình hiện thực hóa (implementation) Dùng lại các design pattern giúp tránh được các vấn đề tiềm ẩn có thể gây ra những lỗi lớn, dễ dàng nâng cấp, bảo trì về sau
Một lợi thế lớn để sử dụng một mẫu thiết kế là lập trình viên khác sẽ có thể dễ dàng nhận
ra nó (đặc biệt là nếu bạn sử dụng quy ước đặt tên tốt)
Khi nào nên sử dụng Design pattern?
Đó là khi bạn muốn giữ cho chương trình của mình thực sự đơn giản Việc sử dụng các design pattern sẽ giúp chúng ta giảm được thời gian và công sức suy nghĩ ra các cách giải quyết cho những vấn đề đã có lời giải Bạn có thể đọc qua cuốn “Head First Design Patterns” để có cái nhìn tổng quát hơn về design pattern.Hệ thống các mẫu design pattern hiện có 23 mẫu được định nghĩa trong cuốn “Design patterns Elements of Reusable Object Oriented Software” Các tác giả của cuốn sách là Erich Gamma, Richard Helm, Ralph Johnson và John Vlissides, hay còn được biết đến với các tên “Gang of Four” hay đơn giản là “GoF” Hệ thống các mẫu này có thể nói là đủ và tối ưu cho việc giải quyết hết các vấn đề của bài toán phân tích thiết kế và xây dựng phần mềm trong thời điểm hiện tại Hệ thống các mẫu design pattern được chia thành 3 nhóm: nhóm Creational (5 mẫu), nhóm Structural (7 mẫu) và nhóm Behavioral (11 mẫu)
Trang 5Phần I: Giới Thiệu Mẫu Decorator
I Vấn đề đặt ra
"Hôm nay có món gì?" bạn hỏi tay đầu bếp khó chịu đang đứng sau bếp nướng.
"Cho một cái hamburger," bạn nói và xoay xoay cái khay trong tay.
Người đầu bếp mang cái hamburger đến bàn tính tiền, không quên hỏi lại "Có thêm thịt rán không?"
"Chắc chắn rồi", bạn nói.
Người đầu bếp xóa các phiếu ăn cũ trên máy tính tiền và khởi động lại
"Hamburger và thịt rán" Vừa nói anh ta vừa gõ vào máy tính tiền.
"Cho thêm một ít pho mát" Bạn nói.
Người đầu bếp ném một ánh nhìn khó chịu , xóa cái phiếu ăn, mổ mổ cái bàn phím
và nói "Hamburger với pho mát và thịt nướng Ok Đủ rồi chứ?"
"Hmm", bạn nói, nhìn quét qua cái thực đơn "Hay là thêm một chút thịt xông khói?"
Người đầu bếp nhìn chằm chằm vào bạn và dường như định văng ra một vài câu khó chịu gì đó nhưng vẫn nhập phiếu ăn vào máy
"Này”, bạn nói "Anh chắc chắn là được lợi nhiều hơn từ việc sử dụng mẫu thiết kế trang trí Decorator chứ hả?"
"Vâng", anh đầu bếp nói, ngạc nhiên khi bạn nói về vấn đề này "Tôi đã nói vấn đề này cả ngàn lần rồi"
Bạn cầm cái Hamburger pho mát thịt xông khói với vẻ hạnh phúc và nói "Thêm một vài lát cà chua nữa thì tuyệt!"
Mẫu trang trí Decorator là lựa chọn hoàn hảo cho tình huống tôi vừa nêu ở trên bởi
vì ta đang nói về khả năng mở rộng chức năng cho một lớp có sẵn Sau khi viết một lớp, bạn có thể thêm phần trang trí Decorator (các lớp mở rộng) để mở rộng lớp này Khi đó bạn không phải sửa đổi lên lớp gốc Kết quả là cái Hamburger của bạn trở thành Hamburger pho mát, rồi Hamburger pho mát thịt xông khói, mọi thứ thật dễ dàng
Trang 6a Định nghĩa
Decorator thuộc nhón cấu trúc:
Decorator pattern được sử dụng để mở rộng chức năng của một đối tượng một cách linh hoạt mà không cần phải thay đổi mã nguồn của class gốc
Nó được thực hiện bằng cách tạo ra một đối tượng wrapper, được gọi là decorator (nhà trang trí) “Trang trí” xung quanh đối tượng ban đầu
b Sơ đồ UML
Component: Là thành phần đại diện để chứa các hành vi chung của đối tượng Nó
có thể là abstract class hoặc interface
ConcreteComponent: kế thừa từ component Là đối tượng gốc mà các chức năng
sẽ được bổ sung thêm
Decorator: là một abstract class, chứa một quan hệ HAS A tham chiếu tới
Component và implement các method trong component
Trang 7ConcreteDecorator: kế thừa từ decorator và có thêm các chức năng mở rộng
riêng của nó
Trung tâm của sơ đồ UML là lớp Decorator Nó bao gồm hai loại quan hệ với giao diện Component:
Is-a
Quan hệ is-a thể hiện bởi một mũi tên tam giác Decorator đến Component, chỉ ra rằng Decorator thưc thi giao diện Component Thực tế là Decorator thừa kế
từ Component có nghĩa là đối tượng Decorator có thể được sử dụng bất cứ nơi nào các đối tượng Component được mong đợi Lớp ConcreteComponent cũng là một mối quan hệ is-a với Component.
Has-a
Quan hệ has-a thể hiện bởi hình thoi mở trên Decorator, liên kết với Component Điều này cho thấy rằng các Decorator khởi tạo một hoặc nhiều đối tượng Component và các đối tượng được trang trí có thể sống lâu hơn bản gốc Decorator sử dụng các thuộc tính thành phần (loại Component) để gọi bất kỳ hoạt động thay thế có thể được ghi đè lên Đây là cách mẫu Decorator đạt được
mục tiêu của mình
c Mẫu Decorator đươc sử dụng khi nào ?
Decorator pattern được sử dụng khi:
Khi bạn muốn thay đổi động mà không ảnh hưởng đến người dùng, không phụ thuộc vào giới hạn các class con
Có một số đặc tính phụ thuộc mà bạn muốn ứng dụng một cách linh động và bạn muốn kết hợp chúng vào trong một đối tượng
Khi các class con không còn khả thi, khi mà cần một số lượng lớn các kết hợp trong một đối tượng
d Decorator, Adapter và Composite:
Ta thấy có sự tương đồng giữa 3 mẫu này Apdapter cũng “trang trí” 1 class có sẵn Nhưng nó thay đổi interface của 1 hay nhiều class thành 1 interface chung có
Trang 8lợi cho chương trình Composite giống như 1 decorator duy nhất, nhưng với mục đích khác
e Ưu - Nhược điểm của mẫu Decorator
Ưu điểm:
- Decorator Pattern cung cấp một giải pháp linh hoạt hơn khi thêm các chức năng cho một đối tượng so với cách kế thừa (inheritance) truyền thống
- Các decorator cung cấp giải pháp để dễ dàng thay đổi hành vi của đối tượng
- Ngoài ra, code còn dễ dàng hơn đáng kể Bởi vì bạn sẽ code class chức năng riêng rẽ cụ thể, thay vì gộp chung nhiều chức năng khác nhau vào một class -> Điều này làm cho các thành phần dễ mở rộng hơn trong tương lai
Nhược điểm:
- Nhược điểm chính của việc sử dụng Decorator Pattern là việc bảo trì có thể là một vấn đề vì nó cung cấp rất nhiều loại object của các class chức năng
*So sánh Decorator Pattern - Kế thừa
Được sử dụng để mở rộng chức năng của một
đối tượng cụ thể Được sử dụng để mở rộng chức năng của một lớpcủa các đối tượng
Không yêu cầu class con Yêu cầu class con
Ngăn chặn sự gia tăng của các class con
dẫn đến ít phức tạp và nhầm lẫn
Có thể dẫn đến nhiều class con, làm cho cây phân cấp class trở nên phức tạp
Client có thể lựa chọn linh hoạt các chức năng
mong muốn
Có các class con để kết hợp các chức năng bổ sung,
mà client mong đợi, có thể dẫn đến một sự gia tăng
của lớp con
Trang 9Dễ dàng thêm bất kỳ sự kết hợp của các chức
năng Chức năng tương tự có thể thậm chí
được thêm hai lần hay nhiều lần
Rất khó
f Ví dụ
Bây giờ chúng ta giải quyết vấn đề nêu ra ở trên:
Ta có sơ đồ UML chi tiết như sau:
Thực hiện:
Class Food:
Public abstract class Food
component
Trang 10String description = “”;
public String getDescription()
{ return description;
} public abstract double cost();
}
Class CondimentDecorator
public abstract class CondimentDecorator extends Food
{
public abstract String getDescription();
}
Class Hamburger
public class Hamburger extends Food
{
public Hamburger()
{ description = “Hamburger”;
} public double cost()
{ return 2;
} }
Class Town
Trang 11Food food;
public Mocha(Food food)
{ this.food = food;
} public String getDescription()
{ return food.getDescription() + “, Town”;
} public double cost()
{ return 0.50 + food.cost();
} }
Class Cheese
public class Cheese extends CondimentDecorator
{
Food food;
public Cheese(Food food)
{ this.food = food;
} public String getDescription()
{ return food.getDescription() + “, Chesse”;
} public double cost()
{ return 1 + food.cost();
} }
Trang 12 Class Tomato
public class Tomato extends CondimentDecorator
{
Food food;
public Tomato(Food food)
{ this.food = food;
} public String getDescription()
{ return food.getDescription() + “, Tomato”;
} public double cost()
{ return 0.2 + food.cost();
} }
Class Smokedpork
public class Smokedpork extends CondimentDecorator
{
Food food;
public Smokedpork(Food food)
{ this.food = food;
} public String getDescription()
{ return food.getDescription() + “, Smoked pork”;
} public double cost()
{ return 1.2 + food.cost();
} }
Trang 13 Class LooFood
public class LooFoodDemo {
public static void main(String[] args) {
Food food = new Hamburger();
System.out.println(food.getDescription() + food.cost() + "$");
Food food1 = new Hamburger();
food1 = new Town(food1);
food1 = new Town(food1);
food1 = new Tomato(food1);
food1 = new Smokedpork(food1);
System.out.print(food1.getDescription());
System.out.format("%s",food1.cost()+"$ \n");
}
}
Kết quả :
Trang 14TỔNG KẾT
Sau khi tìm hiểu về mẫu decorator và được sự hướng dẫn của thầy, em đã đưa ra công dụng và các ứng dụng của mẫu Trong quá trình thực hiện, do em cũng chưa nắm vững kiến thức về degsin patterns, việc ứng dụng kiến thức cũng chưa hoàn toàn đạt hiệu quả tốt nhất nên trong bài làm của em còn có những thiếu sót, em sẽ tiếp tục tiếp thu kiến thức để ứng dụng được tốt hơn
Em cảm ơn thầy đã truyền đạt kiến thức và giúp đỡ kiến thức cho em trong thời gian học tập dưới sự dạy dỗ của thầy!
Tài liệu tham khảo:
[1] Head First Design Patterns
Publisher: O'Reilly Media