Tải bản đầy đủ (.doc) (23 trang)

THIẾT KẾ PHẦN MỀM HƯỚNG ĐỐI TƯỢNG BUILDER PATTERN

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (340.61 KB, 23 trang )

Trường đại học sư phạm kỹ thuật thành phố HCM
Khoa Công Nghệ Thông Tin

Môn:
Đề tài:
 Đặt vấn đề:
GVHD: Nguyễn Trần Thi Văn
Nhóm 03: Vũ Văn Đoan 07110030
Phan Đức Linh 07110065
Nguyễn Văn Phong 07110089
Nguyễn Thị Thanh Quyên 07110099
Thiết kế phần mềm hướng đối tượng
Trong những ứng dụng lớn, với nhiều các chức năng phức tạp và mô hình giao diện đồ
sộ.Việc khởi tạo ứng dụng thường gặp nhiều khó khăn. Chúng ta không thể dồn tất cả công
việc khởi tạo này cho một hàm khởi tạo .Vì như thế sẽ rất khó kiểm soát hết, và hơn nữa
không phải lúc nào các thành phần của ứng dụng cũng được khởi tạo một cách đồng bộ. Có
thành phần được tạo ra vào lúc dịch chương trình nhưng cũng có thành phần tuỳ theo từng
yêu cầu của người dùng, tuỳ vào hoàn cảnh của ứng dụng, mà nó sẽ được tạo ra. Do vậy
người ta giao công việc này cho một đối tượng chịu trách nhiêm khởi tạo, và chia việc khởi
tạo ứng dụng riêng rẽ, để có thể tiến hành khởi tạo riêng biệt ở các hoàn cảnh khác nhau. Hãy
tưởng tượng việc tạo ra đối tượng của ta giống như như việc chúng ta tạo ra chiếc xe đạp.
Đầu tiên ta tạo ra khung xe, sau đó tạo ra bánh xe, chúng ta tạo ra buđông xe, xích, líp, Việc
tạo ra các bộ phận này không nhất thiết phải đựơc thực hiện một cách đồng thời hay theo một
trật tự nào cả, và nó có thể được tạo ra một cách độc lập bởi nhiều người. Nhưng trong một
mô hình sản xuất như vậy, bao giờ việc tạo ra chiếc xe cũng được khép kín để tạo ra chiếc xe
hoàn chỉnh, đó là nhà máy sản xuất xe đạp.Ta gọi đối tượng nhà máy sản xuất xe đạp này là
builder ( người xây dựng).
Builder Pattern Page 2
Thiết kế phần mềm hướng đối tượng
BUILDER PATTERN
Nội dung báo cáo:


1. Ý nghĩa Builder Pattern
2. Mục đích sử dụng Builder
3. Tình huống áp dụng
4. Cấu trúc Builder
5. Ví dụ áp dụng
6. Ứng dụng và hệ quả
7. Cách thực hiện
8. Ưu điểm và khuyết điểm của Builder
9. Các mẫu liên quan
10.Một số ví dụ minh họa
11.Demo
Builder Pattern Page 3
Thiết kế phần mềm hướng đối tượng
1. Ý nghĩa Builder Pattern.
Builder là mẫu thiết kế hướng đối tượng được tạo ra để chia một công việc khởi tạo
một đối tượng phức tạp ra riêng rẽ từ đó có thể tiến hành khởi tạo đối tượng ở các hoàn cảnh
khác nhau.
2. Mục đích sử dụng Builder.
Dùng để chia việc khởi tạo một đối tượng phức tạp ra thành nhiều phần riêng rẽ để có
thể khởi tạo đối tượng đó ở các hoàn cảnh khác nhau.
Tạo nhiều đại diện khác nhau cho cùng một đối tượng.
Ví dụ: Muốn xây dựng một ngôi nhà thì ta phải xây dựng từng bước, chia ra làm nhiều
giai đoạn. Trước hết phải đổ móng, xây nền, xây khung, …… Cùng mục đích là xây nhà
nhưng muốn xây một ngôi nhà ở đồng bằng hoặc một ngôi nhà ở miền núi thì ta sẽ có những
cách thức và nguyên tắc xây dựng riêng.
3. Tình huống áp dụng.
Có cấu trúc bên trong phức tạp (đặc biệt là một biến là một tập các đối
tượng liên quan với nhau).
Có các thuộc tính phụ thuộc vào các thuộc tính khác.
Sử dụng các đối tượng khác trong hệ thống mà có thể khó khởi tạo

hoặc khởi tạo phức tạp.
4. Cấu trúc Builder:
 Sơ đồ lớp.
Builder Pattern Page 4
Thiết kế phần mềm hướng đối tượng
uc Use Case Vi
Director
+ Construct()
for all objects in
structure {
builder->BuildPart()
}
Builder
+ BuildPart()
ConcreteBuilder
+ BuildPart()
+ GetResult() : void
Product
-builder
 Các thành phần tham gia vào cấu trúc:
o Director: Khởi dựng một đối tượng thông qua Builder.
o Builder: Là abstract interface dùng để tạo ra các phần của sản phẩm.
o Concretebuilder:
- Xây dựng và tập hợp các phần của Product bằng cách cài đặt Builder interface.
- Cung cấp một giao diện cho Product .
- Định nghĩa và duy trì đại điện mà nó tạo ra.
o Product:
- Đại diện cho các đối tượng phức tạp được xây dựng. ConcreteBuilder xây dựng
đại diện nội bộ của sản phẩm và xác định quá trình mà nó được lắp ráp.
- Gồm các lớp định nghĩa các thành phần, gồm tập hợp các phần bên trong của

kết quả cuối cùng.
 Sự phối hợp giữa các lớp:
o Client sẽ tạo ra các đối tượng Director và cấu hình nó với các đối tượng Builder
mong muốn.
Builder Pattern Page 5
Thiết kế phần mềm hướng đối tượng
o Director thông báo cho Builder bất cứ khi nào một phần của Product cần được
xây dựng.
o Builder xử lý các yêu cầu của Director và bổ sung thêm các bộ phận cho
Product.
o Client lấy Product từ Builder
 Sơ đồ tương tác sau đây minh họa cách Builder và Director hợp tác với Client.
sd Use Case Vi
aClient
aConcreteBuilder
aDirector
new ConcreteBuilder()
new Director(aConcreteBuilder)
Construct()
BuildPartA()
BuidPartB()
BuildPartC()
GetResult()
5. Ví dụ áp dụng:
Ta cần xây dựng đối tượng Address gồm các thành phần: City, Street, Region. Ta chia
việc xây dựng Address thành các phần nhỏ: buildCity(), buildRegion(), buildStreet(). Tương
ứng với mỗi USAddressBuilder hoặc VNAddressBuilder ta sẽ có cách xây dựng khác nhau
trên cơ sở kế thừa AddressBuider.
Builder Pattern Page 6
Thiết kế phần mềm hướng đối tượng

o Lược đồ lớp cho ví dụ trên:
class Use Case Vi
AddressDirector
+ constructAddress() : voi d
AddressBuilder
+ buildCity() : void
+ buildRegi on() : void
+ buildStreet() : void
+ getAddress() : Address
USAddress
- City: String
- Region: String
- Street: String
USAddressBuilder
+ buildCity() : void
+ buildRegion() : void
+ buildStreet() : void
+ getAddress() : Address
VNAddressBuilder
+ buildCity() : void
+ buildStreet() : void
+ getAddress() : Address
VNAddress
- City: String
- Street: String
 Các thành phần trong lược đồ:
o AddressBuilder (Builder): là lớp trừu tượng cho phép tạo ra đối tượng Address
bằng các phương thức khởi tạo từng thành phần của Address.
o AddressDirector (Dierctor): Tạo ra đối tượng Address.
o USAddressBuilder (ConcreteBuilder): tạo ra các Address theo tiêu chuẩn của

USA.
o VNAddressBuilder (ConcreteBuilder): tạo ra các Address theo tiêu chuẩn của
VN.()
o USAddress, VNAdress (Product): sản phẩm tương ứng được tạo ra bởi
USAddressBuilder và VNAddressBuilder
Builder Pattern Page 7
Thiết kế phần mềm hướng đối tượng
 Lược đồ tuần tự:
sd Use Case Vi
Client
aUSAddressBuilder
aAddressDirector
new USAdressBuilder()
new AddressDirector(aUSAddressBuilder)
contructAddress()
buildStreet()
buildCity()
buildRegion()
getAddress()
6. Ứng dụng và hệ quả:
 Ứng dụng:
o Tạo nên một đối tượng phức hợp độc lập với thành phần.
o Tiến trình khởi tạo phải cho phép nhiều đại diện khác nhau của đối tượng
cũng được khởi tạo.
 Hệ quả:
o Nó cho phép bạn thay đổi đại diện nội bộ của một sản phẩm. Các đối
tượng Builder cung cấp các Director với một giao diện trừu tượng để xây
dựng các sản phẩm. Giao diện này cho phép các nhà xây dựng ẩn cấu trúc
đại diện và nội bộ của sản phẩm. Nó cũng ẩn làm thế nào sản phẩm được
lắp ráp. Bởi vì sản phẩm được xây dựng thông qua một giao diện trừu

tượng.
Builder Pattern Page 8
Thiết kế phần mềm hướng đối tượng
o Nó phân lập mã cho xây dựng và diễn tả. Các mẫu Builder cải thiện mô
đun bằng cách tóm gọn một đối tượng phức tạp được xây dựng và đại
diện. Khách hàng không cần phải biết gì về các lớp để xác định cấu trúc
bên trong của sản phẩm, các lớp đó không xuất hiện trong giao diện
Builder. Mỗi ConcreteBuilder chứa tất cả các mã để tạo và lắp ráp một
loại đặc biệt của sản phẩm. Mã này được viết một lần, sau đó Director có
thể tái sử dụng nó để xây dựng các sản phẩm biến thể từ cùng một bộ
phận. Trong ví dụ trên từ AddressBuilder ta có thể xây dựng được
USAddressBuilder hoặc VNAddressBuilder.
o Nó cho phép bạn kiểm soát tốt hơn trong quá trình xây dựng. Không
giống như các mẫu creational khác xây dựng sản phẩm trong một shot,
mô hình Builder cấu trúc sản phẩm từng bước dưới sự kiểm soát của
Director. Chỉ khi sản phẩm được hoàn thành thì Director lấy nó từ
Builder. Do đó giao diện Builder phản ánh quá trình xây dựng các sản
phẩm nhiều hơn các mẫu creational khác. Điều này cho phép bạn kiểm
soát tốt hơn trong quá trình xây dựng và do đó các cấu trúc bên trong của
sản phẩm đươc tạo ra.
7. Cách thực hiện:
Thông thường có một lớp trừu tượng Builder định nghĩa các thao tác cho mỗi thành
phần, có một Director có thể yêu cầu nó tạo ra đối tượng. Các phương thức mặc định không
làm gì cả. Một lớp ConcreteBuilder ghi đè lên các phương thức vừa được khởi tạo để tạo ra
các phần của đối tượng.
 Dưới đây là vấn đề cần xem xét khi thực hiện :
Lắp ráp và xây dựng giao diện. Builders xây dựng các sản phẩm của chúng trong từng
bước. Do đó giao diện lớp Builder phải được tổng hợp đủ để cho phép việc xây dựng các sản
phẩm cho tất cả các loại ConcreteBuilder.Vấn đề chính một mô hình thiết kế cần quan tâm là
quá trình xây dựng và lắp ráp. Một mô hình kết quả của yêu cầu xây dựng thường chỉ đơn

Builder Pattern Page 9
Thiết kế phần mềm hướng đối tượng
giản là gắn vào sản phẩm là đủ. Nhưng đôi khi bạn có thể cần truy cập đến các bộ phận của
sản phẩm xây dựng trước đó.
Tại sao không có lớp trừu tượng cho Product? Trong trường hợp thông thường, các
Product được sản xuất bởi các ConcreteBuilder cụ thể khác nhau vì vậy các đại diện của
chúng cho thấy có rất ít các Product khác nhau có từ một lớp cha chung. Trong ví dụ
Address, các USAddressBuilder và VNAddressBuilder không có khả năng có cùng một giao
diện. Bởi vì Client thường yêu cầu Director một ConcreteBuilder cụ thể phù hợp, Client biết
được lớp Concrete con nào cần phải được sử dụng và có thể xử lý sản phẩm của mình cho
phù hợp.
Phương pháp Empty như là mặc định trong Builder. Trong C + +, phương thức xây
dựng này là cố tình không khai báo các hàm thành viên ảo. Chúng được đinh nghĩa như là
phương thức Empty, chỉ cho phép Clent ghi đè lên các hoạt động mà họ bao hàm.
8. Ưu điểm và khuyết điểm của Builder:
 Ưu điểm:
- Xây dựng một đối tượng phức tạp theo từng bước, tạo ra nhiều đối tượng khác nhau
tương ứng với các bước thực hiện khác nhau.
- Làm giảm số lượng đối tượng mà người dùng cần xử lý và hệ thống dễ sử dụng
hơn.
- Người dùng chỉ thấy được giao diện ảo bên ngoài mà không nhìn thấy được sự
trình bày bên trong sản phẩm.
- Làm giảm sự “coupling” giữa các đối tượng.
 Khuyết điểm:
- Chỉ áp dụng với những đối tượng phức hợp.
- Có nhiều kiến thức về đối tượng khởi tạo.
- Các đối tượng phải cùng loại.
9. Các mẫu liên quan
Builder Pattern Page 10
Thiết kế phần mềm hướng đối tượng

Builder thường được cài đặt cùng với các mẫu như Abstract Factory .Tầm quan trọng
của Abstract Factory là tạo ra một dòng các đối tượng dẫn xuất (cả đơn giản và phức
tạp).Ngoài ra Builder còn thường được cài đặt kèm với Composite pattern. Composite
pattern thường là những gì mà Builder tạo ra.
 Sự khác biệt giữa Builder Pattern và Abstract Factory:
- Cả hai mẫu đều có các hàm khởi dựng và phương thức ảo, đều tao ra các đối
tượng phức hợp.
- Điểm khác biệt chính là builder khởi tạo đối tượng từng bước, còn abstract
factory chú
- trọng vào việc tạo ra những nhóm đối tượng.
- Builder trả về sản phẩm ở bước hoàn thành, còn abstract factory trả về sản
phẩm ngay tức thời.
- Không có lớp ảo cho Product, vì nó được tạo ra từ rất nhiều định dạng khác
nhau của ConcreteBuilder.
10. Một số ví dụ minh họa:
Ví dụ 1: Bánh Pizza.
Sơ đồ lớp:
Builder Pattern Page 11
Thiết kế phần mềm hướng đối tượng
class Use Case Vi
Cook
- pizzaBuilder: PizzaBuilder
+ ContructPizza() : Pizza
PizzaBuilde r
+ pizza: Pizza
+ BuildNewPizza() : void
+ buildShape() : void
+ buildSize() : void
+ buildTopping() : void
+ getPizza() : void

ItalyPizzaBuilder
+ buildShape() : void
+ buildSize() : void
+ buildTopping() : void
VietNamPizzaBuilder
+ buildShape() : void
+ buildSize() : void
+ buildTopping() : void
PizzaVietNam
- Shape: String
- Size: String
- Topping: String
PizzaItaly
- Shape: String
- Size: String
- Topping: String
pizzaBuilder.BuildNewPizza();
pizzaBuilder.buildShape();
pizzaBuilder.buildSize();
pizzaBuilder.buildTopping();
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ProducePizza
{
/* "Product" */
class Pizza
{
Builder Pattern Page 12

Thiết kế phần mềm hướng đối tượng
private String shape = "";
private String size = "";
private String topping = "";
public void setShape(String shape)
{
this.shape = shape;
}
public void setSize(String size)
{
this.size = size;
}
public void setTopping(String topping)
{
this.topping = topping;
}
public void Show(PizzaBuilder pb)
{
System.Console.WriteLine("\n ");
System.Console.WriteLine(" Type of Pizza: " + pb.ToString());
System.Console.WriteLine(" Shape: " + shape.ToString());
System.Console.WriteLine(" Size: " + size.ToString());
System.Console.WriteLine(" Topping: " + topping.ToString());
}
}
/* "Abstract Builder" */
abstract class PizzaBuilder
Builder Pattern Page 13
Thiết kế phần mềm hướng đối tượng
{

protected Pizza pizza;
public Pizza getPizza()
{
return pizza;
}
public void BuildNewPizza()
{
pizza = new Pizza();
}
public abstract void buildShape(String shape);
public abstract void buildSize(String size);
public abstract void buildTopping(String topping);
}

/* "ConcreteBuilder" */
class ItalyPizzaBuilder : PizzaBuilder
{
public override void buildShape(String shape)
{
pizza.setShape(shape);
}
public override void buildSize(String size)
{
Builder Pattern Page 14
Thiết kế phần mềm hướng đối tượng
pizza.setSize(size);
}
public override void buildTopping(String topping)
{
pizza.setTopping(topping);

}
}

/* "ConcreteBuilder" */
class VietnamPizzaBuilder : PizzaBuilder
{
public override void buildShape(String shape)
{
pizza.setShape(shape);
}
public override void buildSize(String size)
{
pizza.setSize(size);
}
public override void buildTopping(String topping)
{
pizza.setTopping(topping);
}
}
/* "Director" */
Builder Pattern Page 15
Thiết kế phần mềm hướng đối tượng
class Cook
{
private PizzaBuilder pizzabuilder;
public void setPizzaBuilder(PizzaBuilder pb)
{
pizzabuilder = pb;
}
public Pizza getPizza()

{
return pizzabuilder.getPizza();
}
public void constructPizza(String shape, String size, String topping)
{
pizzabuilder.BuildNewPizza();
pizzabuilder.buildShape(shape);
pizzabuilder.buildSize(size);
pizzabuilder.buildTopping(topping);
}
}
class Program
{
static void Main(string[] args)
{
Cook cook = new Cook();
PizzaBuilder italypizzabuilder = new ItalyPizzaBuilder();
Builder Pattern Page 16
Thiết kế phần mềm hướng đối tượng
cook.setPizzaBuilder(italypizzabuilder);
cook.constructPizza("Thin", "Regular", "chicken + pineapple + cheese");
Pizza pizza = cook.getPizza();
pizza.Show(italypizzabuilder);
PizzaBuilder vietnampizzabuilder = new VietnamPizzaBuilder();
cook.setPizzaBuilder(vietnampizzabuilder);
cook.constructPizza("Pan", "Large", "shrimp + mushroom + cheese");
pizza = cook.getPizza();
pizza.Show(vietnampizzabuilder);
System.Console.WriteLine("");
}

}
}
/* Shape: Thin và Pan.
* Size: Personnal, Regular và Large.
* Topping: chicken + pineapple + cheese, capsicum + mushroom + cheese, shrimp +
mushroom + cheese. */
Ví dụ:
Muốn xây một ngôi nhà, bạn phải làm những bước sau
1. Xây nền ( build foundation)
2. Xây phần khung ( build frame)
3. Xây nội thất (build exterior)
4. Xây ngoại thất (build interior)
Builder Pattern Page 17
Thiết kế phần mềm hướng đối tượng
Tạo một lớp trừu tượng (abstract class) HouseBuilder và định nghĩa 4 bước trên.Bất kỳ lớp
con (subclass) nào của HouseBuilder đều phải theo 4 bước trên để xây nhà ( có nghĩa là thi
công 4 phương thức trên trong lớp con).Sau đó chúng ta sử dụng lớp Workshop để yêu cầu
thực hiện 4 phương thức trên ( tiết kiệm nhiều dòng code ).Lớp TestBuilder được dùng để
kiểm tra sự kết hợp của các lớp trên và kiểm tra tiến trình xây dựng nhà.
Sơ đồ lớp
class House
WorkShop
+ Construct(HouseBuilder) : void
HouseBuilder
# house: HouseBuilder
+ buildExterior() : void
+ buildFoundation() : void
+ buildFrame() : void
+ buildInterior() : void
# showProgress() : String

OneStoryHouse
+ buildExterior() : void
+ buildFoundation() : void
+ buildFrame() : void
+ buildInterior() : void
House1
hb.buildFoundation();
hb.buildFrame();
hb.buildExterior();
hb.buildInterior();
TwoStoryHouse
+ buildExterior() : void
+ buildFoundation() : void
+ buildFrame() : void
+ buildInterior() : void
House2
//Lớp HouseBuilder
//set steps for building a house
abstract class HouseBuilder {
protected House house = new House();
protected String showProgress() {
Builder Pattern Page 18
Thiết kế phần mềm hướng đối tượng
return house.toString();
}
abstract public void buildFoundation();
abstract public void buildFrame();
abstract public void buildExterior();
abstract public void buildInterior();
}

//Lớp House
class House {
private String type = null;
private List features = new ArrayList();
public House() {
}
public House(String type) {
this.type = type;
}
public void setType(String type) {
this.type = type;
}
public String getType() {
return type;
}
public void setProgress(String s) {
features.add(s);
}
public String toString() {
StringBuffer ff = new StringBuffer();
Builder Pattern Page 19
Thiết kế phần mềm hướng đối tượng
String t = type.substring(6);
ff.append(t + "\n ");
for (int i = 0; i < features.size(); i ++) {
ff.append(features.get(i) + "\n ");
}
return ff.toString();
}
}

//Lớp OneStoryHouse và TwoStoryHouse
class OneStoryHouse extends HouseBuilder {
public OneStoryHouse(String features) {
house.setType(this.getClass() + " " + features);
}
public void buildFoundation() {
house.setProgress("foundation is done");
}
public void buildFrame() {
house.setProgress("frame is done");
}
public void buildExterior() {
house.setProgress("Exterior is done");
}
public void buildInterior() {
house.setProgress("Interior is under going");
}
}
class TwoStoryHouse extends HouseBuilder {
Builder Pattern Page 20
Thiết kế phần mềm hướng đối tượng
public TwoStoryHouse(String features) {
house.setType(this.getClass() + " " + features);
}
public void buildFoundation() {
house.setProgress("foundation is done");
}
public void buildFrame() {
house.setProgress("frame is under construction");
}

public void buildExterior() {
house.setProgress("Exterior is waiting to start");
}
public void buildInterior() {
house.setProgress("Interior is not started yet");
}
}
//Lớp WorkShop
class WorkShop {
//force the order of building process
public void construct(HouseBuilder hb) {
hb.buildFoundation();
hb.buildFrame();
hb.buildExterior();
hb.buildInterior();
}
}
//Lớp TestBuilder
Builder Pattern Page 21
Thiết kế phần mềm hướng đối tượng
class TestBuilder {
public static void main(String[] args) {
HouseBuilder one =new OneStoryHouse("2 bedrooms, 2.5 baths, 2-car garage, 1500
sqft");
HouseBuilder two =new TwoStoryHouse("4 bedrooms, 4 baths, 3-car garage, 5000
sqft");
WorkShop shop = new WorkShop();
shop.construct(one);
shop.construct(two);
System.out.println("Check house building progress: \n");

System.out.println(one.showProgress());
System.out.println(two.showProgress());
}
}
Kết quả chạy
Check house building progress:
OneStoryHouse 2 bedrooms, 2.5 baths, 2-car garage, 1500 sqft
foundation is done
frame is done
Exterior is done
Interior is under going
TwoStoryHouse 4 bedrooms, 4 baths, 3-car garage, 5000 sqft
foundation is done
frame is under construction
Builder Pattern Page 22
Thiết kế phần mềm hướng đối tượng
Exterior is waiting to start
Interior is not started yet
Builder Pattern Page 23

×