Design Patterns: AbstractFactory

Các khóa học qua video:
Python SQL Server PHP C# Lập trình C Java HTML5-CSS3-JavaScript
Học trên YouTube <76K/tháng. Đăng ký Hội viên
Viết nhanh hơn - Học tốt hơn
Giải phóng thời gian, khai phóng năng lực

Thuộc nhóm: Creational

Tần suất sử dụng: cao trung bình

Vấn đề đặt ra

Chúng ta có thể để ý thấy trong các hệ điều hành giao diện đồ hoạ, một bộ công cụ muốn cung cấp một giao diện người dùng dựa trên chuẩn look - and – feel, chẳng hạn như chương trình trình diễn tài liệu power point.Có rất nhiều kiểu giao diện look- and –feel và cả những hành vi giao diện người dùng khác nhau được thể hiện ở đây như thanh cuộn tài liệu (scroll bar), cửa sổ (window), nút bấm (button), hộp soạn thảo (editbox),...Nếu xem chúng là các đối tượng thì chúng ta thấy chúng có một số đặc  điểm và hành vi khá giống nhau về mặt hình thức nhưng lại khác nhau về cách thực hiện. Chẳng hạn đối tượng button và window, editbox có cùng các thuộc tính là chiều rộng, chiều cao,toạ độ,… Có các phương thức là Resize(), SetPosition(),...Tuy nhiên  các đối tượng này không thể gộp chung vào một lớp được vì theo nguyên lý xây dựng lớp thì các đối tượng thuộc lớp phải có các phương thức hoạt động giống nhau. Trong khi ở đây tuy rằng các đối tượng có cùng giao diện nhưng cách thực hiện các hành vi tương ứng lại hoàn toàn khác nhau.

Vấn đề đặt ra là phải xây dựng một lớp tổng quát, có thể chứa hết được những điểm chung của các đối tượng này để từ đó có thể dễ dàng sử dụng lại, ta gọi lớp này là WidgetFactory.Các lớp của các đối tượng window, button,editbox kế thừa từ lớp này.Trong thiết kế hướng đối tượng, xây dựng một mô hình các lớp như thế được tối ưu hoá như sau:

design-patterns-toi-uu-hoa-WidgetFactory.png

Lớp WidgetFactory có 2 phương thức là CreateScrollBar() và CreateWindow()đây là lớp giao diện trừu tượng tổng quát cho tất cả các MotifWidgetFactory và PMWidgetFactory. Các lớp

MotifWidgeFactory và PMWidgetFactory kế thừa trực tiếp từ lớp WidgetFactory. Trong sơ đồ trên còn có 2 nhóm lớp Window và ScrollBar, chúng đều là các lớp trừu tượng. Từ lớp Window sinh ra các lớp con cụ thể là PMWindow và MotifWindow. Từ lớp ScrollBar sinh ra các lớp con cụ thể là PMScrollBar và MotifScrollBar.Các đối tượng thuộc lớp này được các đối tượng thuộc lớp Factory (MotifWidgetFactory và PMWidgetFactory) gọi trong các hàm tạo đối tượng. Đối tượng trong ứng dụng (đối tượng khách - client) chỉ thông qua lớp giao diện của các đối tượng MotifWidgetFactory và PMWidgetFactory và các đối tượng trừu tượng Window và ScrollBar để làm việc với các đối tượng PMWindow, MotifWindow, PMScrollBar,MotifScrollBar. Điều này có được nhờ  cơ  chế binding trong các ngôn ngữ hỗ trợ lập trình hướng đối tượng như C++,C#,Java, Small Talk,…Các đối tượng PMWindow, MotifWindow, PMScrollBar,MotifScrollBar được sinh ra vào thời gian chạy chương trình, nên trình ứng dụng (đối tượng thuộc lớp client) chỉ cần giữ một con trỏ trỏ đến đối tượng thuộc lớp WidgetFactory, và thay đổi địa chỉ trỏ đến nó có thể làm việc với tất cả các đối tượng ở trên.Những tình huống thiết kế như thế này thường có cùng một cách giải quyết đã được chứng tỏ là tối ưu. Nó được tổng quát hoá thành một mẫu thiết kế gọi là AbstractFactory.

Định nghĩa

Mẫu AbstractFactory là một mẫu thiết kế mà cung cấp cho trình khách một giao diện cho một họ hoặc một tập các đối tượng thuộc các lớp khác nhau nhưng có cùng chung giao diện với nhau mà không phải trực tiếp làm việc với từng lớp con cụ thể.

Lược đồ UML

design-patterns-luoc-do-uml-AbstractFactory.png

AbstractFactory (ContinentFactory): Khai báo một giao diện cho các thao tác để tạo ra các dẫn xuất trừu tượng

ConcreteFactory (AfricaFactory, AmericaFactory): Cài đặt các thao tác để tạo ra các đối tượng dẫn xuất chi tiết

AbstractProduct (Herbivore, Carnivore): Khai báo một giao diện cho một kiểu đối tượng dẫn xuất

Product (Wildebeest, Lion, Bison, Wolf): Định nghĩa một đối tượng dẫn xuất được tạo ra bởi một factory cụ thể tương ứng. Cài đặt giao diện AbstractProduct.

Client (AnimalWorld): Sử dụng giao diện được khai báo bởi các lớp AbstractFactory và AbstractProduct

Cài đặt cho lớp WidgetFactory:

class WidgetFactory

{

public:

virtual Window* CreateWindow(); virtual ScrollBar* CreateScrollBar();

};

Cài đặt cho lớp MotifWidgetFactory và PMWidgeFactory như sau:

class MotifWidgetFactory:public WidgetFactory

{

public:

Window* CreateWindow()

{

return new MotifWindow();

}

ScrollBar* CreateScrollBar()

{

return new MotifScrollBar();

}

};

class PMWidgetFactory:public WidgetFactory

{

public:

Window* CreateWindow()

{

return new PMWindow();

}

ScrollBar* CreateScrollBar()

{

return new PMScrollBar();

}

};

Trong đó các lớp đối tượng Window được định nghĩa như sau:

class Window

{

//Các thuộc tính và các phương thức tĩnh và ảo định nghĩa tại đây

};

class MotifWindow : public Window

{

//Các thuộc tính và các phương thức định nghĩa tại đây

};

class PMWindow : public Window

{

//Các thuộc tính và các phương thức định nghĩa tại đây

};

Các lớp thuộc nhóm ScrollBar.

class ScrollBar

{

//Các thuộc tính và các phương thức tĩnh và ảo định nghĩa tại đây

};

class MotifScrollBar:public ScrollBar

{

//Các thuộc tính và các phương thức định nghĩa tại đây

};

class PMScrollBar:public ScrollBar

{

//Các thuộc tính và các phương thức định nghĩa tại đây

};

Để truy cập đến các đối tượng này tại chương trình ứng dụng ta có thể thực hiện như sau:

class Client

{

private:

WidgetFactory* wf;

};

Mẫu liên quan

AbstractFactory thường được cài đặt cùng với singleton, FactoryMethod đôi khi còn dùng cả Prototype. Các lớp con cụ thể (concrete class) thường được cài đặt bằng singleton. Bởi singleton có thể tạo ra những đối tượng đồng nhất cho dù chúng ta gọi nó ở đâu trong chương trình. Các mẫu này sẽ được nói kỹ hơn ở các phần sau.

» Tiếp: Builder
« Trước: Hệ thống các mẫu design pattern
Các khóa học qua video:
Python SQL Server PHP C# Lập trình C Java HTML5-CSS3-JavaScript
Học trên YouTube <76K/tháng. Đăng ký Hội viên
Viết nhanh hơn - Học tốt hơn
Giải phóng thời gian, khai phóng năng lực
Copied !!!