copyright from: diendan.congdongcviet.com
Vậy là bạn đã bao bọc đối tượng computer, và khi bạn gọi phương thức description của đối tượng disk này, nó sẽ gọi phương thức description của lớp computer, đồng thời thêm vào dòng chữ “and a disk”. Kết quả bạn sẽ có “computer and a disk”
Thêm vào một ổ CD
Bạn cũng có thể thêm vào một ổ CD theo cùng cách trên. Đây là mã nguồn

Thêm vào một màn hình monitor
Tất nhiên bạn cũng có thêm vào một màn hình theo cùng một cách như sau:

OK. Bạn đã có đầy đủ các lớp. Giờ là lúc chạy thử nghiệm chương trình.
Đầu tiên bạn tạo đối tượng computer như sau:

Sau đó bạn bao bọc đối tượng computer để thêm vào một đĩa cứng

Bây giờ hãy thêm vào một monitor:

Sau đó, bạn có thêm vào không chỉ một ổ CD, mà là hai ổ CD chẳng hạn. Không vấn đề gì khó khăn cả. Cuối cùng bạn gọi phương thức description của lớp bao bọc để xem kết quả:

OK. Khi chạy chương trình bạn nhận được kết quả.

Không tồi. Bạn đã mở rộng một đối tượng gốc thật đơn giản bằng cách bao bọc nó trong nhiều lớp trang trí decorator khác nhau, tránh việc phải chỉnh sửa trong mã nguồn gốc. Và đó là Mẫu Thiết Kế Trang Trí Decorator.
CẢI TIẾN TOÁN TỬ NEW VỚI MẪU THIẾT KẾ NHÀ MÁY FACTORY
Tại đây, công ty MegaGigaCo, bạn được trả giá cao cho kỹ năng thiết kế mẫu chuyên nghiệp của mình, bạn đang tạo một đối tượng kết nối cơ sở dữ liệu mới. Hãy xem toán tử new trong Java làm việc này như thế nào?

“Không tồi,” bạn nghĩ, sau khi hoàn thành đoạn mã việc lớp OracleConnection. Bây giờ bạn đã có thể kết nối với cơ sở dữ liệu Oracle.
“Nhưng,” Giám đốc điều hành la lên ,”làm thế nào để kết với máy chủ cơ sở dữ liệu Microsof SQL Server?”
“Được”, bạn nói “Bình tĩnh, để tôi suy nghĩ một lát”. Bạn ra khỏi phòng để ăn trưa và sau đó quay lại tìm giám đốc và ban quản trị. Mọi người nóng lòng chờ đợi và hỏi “Mọi việc đã xong chưa?”
Bạn trở lại làm việc và tạo ra một lớp mới dùng để kết nối cơ sở dữ liệu, lớp SQLServerConnection.

“Tốt lắm” Vị giám đốc nói. “Umh, vậy làm sao để kết nối với MySQL? Chúng ta muốn nó là kết nối mặc định”. “Woa”, bạn hơi bối rối. Tuy nhiên bạn vẫn làm thêm một kết nối với MySQL như sau:

Hiện tại bạn đã có ba loại kết nối cơ sở dữ liệu như sau: Oracle, SQL Server và MySQL. Vì vậy bạn chỉnh sửa mã nguồn cho phù hợp với các biến như “Oracle”, “SQL Server” hay bất cứ biến nào khác như sau:

Mọi việc đều ổn, bạn nghĩ. Tuy nhiên có tới 200 chỗ trong mã nguồn cần phải tạo kết nối cơ sở dữ liệu. Vì vậy đã tới lúc đưa đoạn mã này vào một phương thức riêng, phương thức createConnection, qua truyền cho nó loại kết nối mà bạn muốn như sau:

Phương thức có thể trả về loại kết nối mong muốn, tùy thuộc vào giá trị tham số truyền vào:

Tuyệt, bạn nghĩ. Không có gì khó khăn ở đây.
“Tin xấu” Vị giám đốc nói lớn trong khi chạy ào vào phòng làm việc của bạn. “Chúng ta cần phải chỉnh sửa lại mã nguồn để xử lý các kết nối an toàn cho tất cả máy chủ cơ sở dữ liệu. Hội đồng quản trị của khu vực Western yêu cầu như vậy”
Bạn đưa vị giám đốc ra khỏi phòng và ngồi suy nghĩ. Tất cả mã nguồn chắc phải chỉnh sửa lại. Phương thức mới createConnection, phần chính của mã nguồn, sẽ phải chỉnh sửa lại.
Trong chương II của quyển sách này. Bạn đã được biết dấu hiệu phải sử dụng mẫu thiết kế: “Đó là tách rời phần mã nguồn dễ thay đổi nhất ra khỏi phần mã chính của bạn. Và cố gắng sử dụng lại những phần này càng nhiều càng tốt.”
Có lẽ đây là lúc nghĩ về việc tách rời phần mã nguồn dễ thay đổi ra khỏi chương trình chính, phần tạo kết nối cơ sở dữ liệu connection, và đóng gói nó vào một đối tượng. Và đối tượng đó chính là mẫu nhà máy Factory. Đối tượng là một nhà máy, được viết trong mã nguồn, nhằm tạo ra các đối tượng kết nối connection.
Vì sao bạn nghĩ tới mẫu thiết kế nhà máy Factory. Đây là những gợi ý:
Chúng ta có thể nói rằng, toán tử new vẫn tốt trong mọi trường hợp, nhưng khi mã tạo dựng đối tượng bị liên tục thay đổi, ta nên nghĩ đến việc đóng gói chúng bằng mẫu thiết kế nhà máy factory.
XÂY DỰNG MẪU NHÀ MÁY FACTORY ĐẦU TIÊN
Nhiều lập trình viên biết cách thức mà đối tượng nhà máy factory làm việc. Họ nghĩ đơn giản rằng, bạn có một đối tượng làm nhiệm vụ tạo ra đối tượng khác. Đó là cách mà đối tượng factory thường được tạo ra và sử dụng, tuy nhiên nó còn làm được nhiều hơn thế. Chúng ta hãy nhìn vào cách thông thường khi tạo một đối tượng nhà máy factory trước, sau đó xem xét định nghĩa chính xác từ sách của GOF, theo định nghĩa mà đối tượng nhà máy factory sẽ có nhiều điểm khác, nhiều sự uyển chuyển hơn.
Tạo dựng đối tượng nhà máy Factory
Ví dụ đầu tiên, FirstFactory, sẽ làm việc theo cách hiểu thông thường nhất. Lớp FirstFactory đóng gói đối tượng xây dựng connection, và bạn truyền giá trị tham số theo đúng loại muốn tạo đó là “Oracle” hay “SQL Server” hay loại gì khác. Đây là cách bạn tạo một đối tượng sử dụng nhà máy factory :

Bây giờ, bạn có thể sử dụng đối tượng nhà máy factory mới tạo này, để tạo đối tượng kết nối connection, bằng cách gọi phương thức tên createConnection như sau:

Vậy bạn đã tạo lớp nhà máy FirstFactory như thế nào? Hãy xem mã sau:

Đầu tiên bạn truyền kiểu kết nối vào phương thức khởi tạo của lớp FirstFactory.
Lớp FirstFactory chứa đựng một phương thức createConnection dùng để tạo ra một đối tượng kết nối connection thật sự. Đây là nơi bạn phải chỉnh sửa mã nguồn nhiều nhất tùy theo loại kết nối muốn tạo, mã như sau:

Kết quả, bạn đã có một lớp nhà máy factory.
Tạo một lớp kết nối Connection trừu tượng
Hãy nhớ rằng một trong những mục tiêu của chúng ta khi viết mã, là làm sao việc thay đổi phần chính của mã nguồn càng ít càng tốt. Với mục tiêu đó, hãy nhìn đoạn mã sau làm việc, khi ta sử dụng một đối tượng connection được tạo bởi đối tượng nhà máy factory:

Bạn có thể thấy rằng, đối tượng kết nối connection được tạo bởi nhà máy factory, được sử dụng khắp nơi trong mã nguồn. Để sử dụng cùng một đoạn mã cho tất cả các loại kết nối khác nhau (Oracle,MySQL...), đoạn mã cần phải được viết theo tính “đa hình”, có nghĩa là tất cả các đối tượng connection, đều có cùng một giao diện interface, hay cùng kế thừa từ một lớp cơ sở. Theo cách đó, bạn có thể sử dụng cùng một biến cho mọi loại đối tượng kết nối.
Trong ví dụ, tôi tạo một lớp trừu tượng connection, để các lớp khác kế thừa nó. Lớp này gồm một phương thức khởi dựng, và một phương thức description ( trả về mô tả của loại đối tượng ). Mã như sau:

OK. Mọi việc có vẻ tốt đẹp. Bây giờ bạn đã tạo một lớp trừu tượng cơ sở cho các lớp kết nối khác kế thừa. Bạn cần phải kế thừa tất cả các đối tượng kết nối connection tạo ra từ lớp nhà máy factory.
Tạo lớp kế nối connection
Có ba lớp kết nối connection mà nhà máy Factory có thể tạo ra, phù hợp với loại kết nối mà Vị giám đốc mong muốn: OracleConnection,SqlServerConnection,MySQLConnecti on. Như chúng ta vừa nói, cần phải kế thừa từ lớp trừu tượng vừa tạo. Và mỗi loại trong chúng đều có phương thức decription trả về mô tả của từng loại kết nối một. Đây là mã nguồn của lớp OracleConnection:

Đây là lớp SqlServerConnection, cũng kế thừa từ lớp trừu tượng Connection:

Và lớp MySqlConnection cũng tương tự:

Tuyệt với. Mọi việc hoàn tất. Giờ là lúc thử nghiệm chúng. Đầu tiên ta tạo lớp nhà máy, truyền tham số khởi dựng là Oracle:


Để kiểm tra lại đối tượng connection được tạo có phải là Oracle không, ta gọi phương thức description như sau:

Kết quả bạn nhận được

Không tồi. Đó là những gì bạn mong đợi.
Ghi nhớ:Theo sách GoF, mẫu thiết kế phương thức nhà máy Factory Method được định nghĩa “Định nghĩa một giao diện để tạo một đối tượng, nhưng cho phép các lớp con quyết định cách thức thể hiện nó. Phương thức nhà máy Factory cho phép một lớp trì hoãn việc hiện thực của nó qua các lớp con”
Điểm mấu chốt ở đây là phần “để lớp con quyết định”. Cho tới bây giờ, lớp nhà máy Factory mà bạn vừa tạo, vẫn chưa cho phép các lớp con quyết định cách thể hiện, trừ việc cho kế thừa và ghi đè lại phương thức của lớp Connection cơ sở.
Mẫu thiết kế phương thức nhà máy Factory Method của GoF đem đến cho bạn khả năng uyển chuyển hơn phương pháp truyền thống rất nhiều. Cách làm của GoF là: bạn định nghĩa cách phương thức nhà máy Factory làm việc, và cho phép các lớp con hiện thực implement một nhà máy factory thật sự.
Chúng ta đã nói rằng, Hội đồng quản trị khu vực Western bất ngờ gọi điện và yêu cầu họ không thích lớp nhà máy FirstFactory, họ muốn có thể tạo ra các kết nối bảo mật đến máy chủ cơ sở dữ liệu, không chỉ là một kết nối thông thường. Điều này có nghĩa là họ phải viết lại lớp nhà máy FirstFactory mỗi khi bạn thay đổi nó, để họ có thể tạo ra một kết nối bảo mật.
Đây là vấn đề của các lập trình viên. Mỗi khi bạn cập nhật lại lớp FirstFactory, các lập trình viên khác phải viết lại mã của họ để thích hợp với yêu cầu của họ. Họ đang gọi và yêu cầu rằng họ muốn kiểm soát được quá trình nhiều hơn.
Tốt thôi, bạn nói. Đó chính là vấn đề mẫu thiết kế Factory áp dụng, giao quyền kiểm soát cho các lớp con. Để thấy cách mẫu này hoạt động, bạn thay đổi cách tạo đối tượng kết nối connection, sử dụng kỹ thuật của GoF, bạn sẽ làm cho khu vực Western của công ty MegaGigaCo hài lòng.
Gợi ý: Bạn vẫn còn băn khoăn về cách sử dụng của mẫu nhà máy Factory của GoF? Mẫu Factory được sử dụng khi bạn muốn chuyển giao toàn bộ quyền điều khiển các lớp con cho các lập trình viên khác.
TẠO MỘT NHÀ MÁY FACTORY THEO CÁCH CỦA GoF
Làm cách nào để “cho phép các lớp con toàn quyền hiện thực cách lớp con thể hiện” khi tạo một đối tượng nhà máy factory. Cách mà bạn phải làm là định nghĩa lớp nhà máy factory như là một lớp trừu tượng abstract hay giao diện interface, và để cho các lớp con hiện thực implement nó.
Nói cách khác, bạn tạo ra một khung sườn cho lớp nhà máy Factory tại trụ sở của MegaGigaCo, và việc hiện thực lớp này sẽ do các lớp con đảm nhiệm.
Tạo lớp nhà máy trừu tượng factory
Việc tạo lớp trừu tượng factory rất dễ dàng. Lớp này được gọi là ConnectionFactory

Bên cạnh một phương thức khởi dựng rỗng, phương thức quan trọng nhất ở đây là phương thức nhà máy createConnection. Ta phải làm cho phương thức mang tính trừu tượng, để các lớp con hiện thực nó. Phương thức này nhận một đối số, đó là loại kết nối cần tạo:

Và đó là tất cả những gì bạn cần. Sự đặc tả cho đối tượng nhà máy factory. Bây giờ khu vựa Western sẽ hài lòng vì họ có thể hiện thực một đối tượng nhà máy cụ thể thích hợp với họ từ lớp trừu tượng trên.
Tạo một lớp nhà máy factory cụ thể
Bạn đã bay tới khu vực Western của công ty MegaGigaCo, để giúp họ xử lý vấn đề tạo đối tượng. Bạn giải thích ”Tôi hiểu rằng các anh muốn được quyền điều khiển nhiều hơn đối với các đối tượng kết nối”
“Vâng” các lập trình viên của Western nói. “Chúng tôi muốn có thể làm việc với các kết nối bảo mật. Chúng tôi đã tạo một vài lớp mới, lớp SecureOracleConnection, SecureSqlServerConnection và SecureMySqlConnection để tạo ra các kết nối bảo mật.
“OK” bạn nói. “tất cả những gì các bạn phải làm là mở rộng lớp trừu tượng mới của tôi, tên là ConnectionFactory khi các bạn muốn tạo đối tượng nhà máy factory cho các bạn. Hãy chắc chắn là các bạn sẽ hiện thực phương thức createConnection. Sau đó bạn có thể tùy ý viết mã cho phương thức createConnection để tạo đối tượng theo đúng cách bảo mật mà bạn muốn”
Các lập trình viên của Western nói. “Wa, thật dễ dàng. Chúng tôi sẽ tạo lớp factory mới với tên SecureFactory, và nó sẽ kế thừa từ ConnectionFactory như sau:

“Tiếp theo,” các lập viên của khu vực Western nói “Chúng chỉ cần hiện thực lớp createConnection mà lớp trừu tượng ConnectionFactory yêu cầu:

“Cuối cùng,” các lập trình viên nói “chúng ta chỉ cần tạo các đối tượng từ các lớp vừa tạo, lớp SecureOracleConnection, SecureSqlServerConnection và SecureMySqlConnection, tùy thuộc vào kiểu dữ liệu được truyền vào hàm createConnection:

“Thật đơn giản” Họ nói.
Sự khác biệt giữa cách tạo mẫu nhà máy factory thông thường và cách của GoF là cách của GoF chỉ đặc tả lớp nhà máy factory và để cho các lớp con xử lý nội dung chi tiết.
Tạo các lớp kết nối bảo mật
Để hiểu rõ cách thức GoF tạo mẫu factory, bạn cần tạo các lớp cụ thể cho đối tượng nhà máy connect mới, lớp SecureOracleConnection, SecureSqlServerConnection và lớp SecureMySqlConnection. Thật dễ dàng để tạo chúng ,bắt đầu từ lớp SecureOracleConnection, với hàm description trả về văn bản “Oracle Secure”:

Tiếp theo là lớp SecureSqlServerConnection, với hàm description trả về văn bản “SQL Server Secure”

Và lớp SecureMySqlConnection, với hàm description trả về văn bản “MySql Secure”:

Vậy là đã hoàn tất phần mã nguồn. Giờ là lúc cho chương trình chạy.
Thực thi chương trình
Để kiểm tra mã nguồn, hãy tạo đối tượng SecureFactory và sử dụng nó để tạo đối tượng SecureOracleConnection. Mã như sau:

Tất cả những gì bạn cần phải làm là sử dụng hàm createConnection của đối tượng nhà máy factory để tạo các kết nối an toàn. Mã như sau:

Khi chạy chương trình, đúng như mong đợi, bạn nhận được văn bản sau, chứng tỏ rằng bạn đang sử dụng một kết nối Oracle bảo mật:

Đây cũng là kết quả mà bạn nhận được từ ví dụ FirstFactory mà chúng ta đã nói trong phần trước, ngoại trừ một điều là bạn cho phép khu vựa Western tự mình hiện thực loại nhà máy factory mà họ mong muốn. Bạn đặc tả một lớp nhà máy bằng cách tạo ra một lớp trừu tượng hay một giao diện interface để các lớp con sử dụng, và người khác sẽ tự mình quyết định lớp đó thực hiện như thế nào. Không còn việc sử dụng một đối tượng nhà máy cụ thể, nay tập hợp các lớp con quyết định việc thể hiện chúng như thế nào.
Vậy là bạn đã bao bọc đối tượng computer, và khi bạn gọi phương thức description của đối tượng disk này, nó sẽ gọi phương thức description của lớp computer, đồng thời thêm vào dòng chữ “and a disk”. Kết quả bạn sẽ có “computer and a disk”
Thêm vào một ổ CD
Bạn cũng có thể thêm vào một ổ CD theo cùng cách trên. Đây là mã nguồn

Thêm vào một màn hình monitor
Tất nhiên bạn cũng có thêm vào một màn hình theo cùng một cách như sau:

OK. Bạn đã có đầy đủ các lớp. Giờ là lúc chạy thử nghiệm chương trình.
Đầu tiên bạn tạo đối tượng computer như sau:

Sau đó bạn bao bọc đối tượng computer để thêm vào một đĩa cứng

Bây giờ hãy thêm vào một monitor:

Sau đó, bạn có thêm vào không chỉ một ổ CD, mà là hai ổ CD chẳng hạn. Không vấn đề gì khó khăn cả. Cuối cùng bạn gọi phương thức description của lớp bao bọc để xem kết quả:

OK. Khi chạy chương trình bạn nhận được kết quả.

Không tồi. Bạn đã mở rộng một đối tượng gốc thật đơn giản bằng cách bao bọc nó trong nhiều lớp trang trí decorator khác nhau, tránh việc phải chỉnh sửa trong mã nguồn gốc. Và đó là Mẫu Thiết Kế Trang Trí Decorator.
CẢI TIẾN TOÁN TỬ NEW VỚI MẪU THIẾT KẾ NHÀ MÁY FACTORY
Tại đây, công ty MegaGigaCo, bạn được trả giá cao cho kỹ năng thiết kế mẫu chuyên nghiệp của mình, bạn đang tạo một đối tượng kết nối cơ sở dữ liệu mới. Hãy xem toán tử new trong Java làm việc này như thế nào?

“Không tồi,” bạn nghĩ, sau khi hoàn thành đoạn mã việc lớp OracleConnection. Bây giờ bạn đã có thể kết nối với cơ sở dữ liệu Oracle.
“Nhưng,” Giám đốc điều hành la lên ,”làm thế nào để kết với máy chủ cơ sở dữ liệu Microsof SQL Server?”
“Được”, bạn nói “Bình tĩnh, để tôi suy nghĩ một lát”. Bạn ra khỏi phòng để ăn trưa và sau đó quay lại tìm giám đốc và ban quản trị. Mọi người nóng lòng chờ đợi và hỏi “Mọi việc đã xong chưa?”
Bạn trở lại làm việc và tạo ra một lớp mới dùng để kết nối cơ sở dữ liệu, lớp SQLServerConnection.

“Tốt lắm” Vị giám đốc nói. “Umh, vậy làm sao để kết nối với MySQL? Chúng ta muốn nó là kết nối mặc định”. “Woa”, bạn hơi bối rối. Tuy nhiên bạn vẫn làm thêm một kết nối với MySQL như sau:

Hiện tại bạn đã có ba loại kết nối cơ sở dữ liệu như sau: Oracle, SQL Server và MySQL. Vì vậy bạn chỉnh sửa mã nguồn cho phù hợp với các biến như “Oracle”, “SQL Server” hay bất cứ biến nào khác như sau:

Mọi việc đều ổn, bạn nghĩ. Tuy nhiên có tới 200 chỗ trong mã nguồn cần phải tạo kết nối cơ sở dữ liệu. Vì vậy đã tới lúc đưa đoạn mã này vào một phương thức riêng, phương thức createConnection, qua truyền cho nó loại kết nối mà bạn muốn như sau:

Phương thức có thể trả về loại kết nối mong muốn, tùy thuộc vào giá trị tham số truyền vào:

Tuyệt, bạn nghĩ. Không có gì khó khăn ở đây.
“Tin xấu” Vị giám đốc nói lớn trong khi chạy ào vào phòng làm việc của bạn. “Chúng ta cần phải chỉnh sửa lại mã nguồn để xử lý các kết nối an toàn cho tất cả máy chủ cơ sở dữ liệu. Hội đồng quản trị của khu vực Western yêu cầu như vậy”
Bạn đưa vị giám đốc ra khỏi phòng và ngồi suy nghĩ. Tất cả mã nguồn chắc phải chỉnh sửa lại. Phương thức mới createConnection, phần chính của mã nguồn, sẽ phải chỉnh sửa lại.
Trong chương II của quyển sách này. Bạn đã được biết dấu hiệu phải sử dụng mẫu thiết kế: “Đó là tách rời phần mã nguồn dễ thay đổi nhất ra khỏi phần mã chính của bạn. Và cố gắng sử dụng lại những phần này càng nhiều càng tốt.”
Có lẽ đây là lúc nghĩ về việc tách rời phần mã nguồn dễ thay đổi ra khỏi chương trình chính, phần tạo kết nối cơ sở dữ liệu connection, và đóng gói nó vào một đối tượng. Và đối tượng đó chính là mẫu nhà máy Factory. Đối tượng là một nhà máy, được viết trong mã nguồn, nhằm tạo ra các đối tượng kết nối connection.
Vì sao bạn nghĩ tới mẫu thiết kế nhà máy Factory. Đây là những gợi ý:
- Bạn sử dụng toán tử new để tạo đối tượng OracleConnection
- Sau đó lại sử dụng tiếp toán tử new để tạo đối tượng SQLServerConnection, và sau đó là MySQLConnection. Nói cách khác, bạn đã sử dụng toán tử new để tạo nhiều đối tượng thuộc các lớp khác nhau, điều này làm mã nguồn của bạn trở nên lớn hơn và bạn buộc phải lặp lại điều này nhiều lần trong toàn bộ mã nguồn.
- Sau đó bạn đưa đoạn mã đó vào trong một phương thức
- Bởi vì yêu cầu vẫn còn có thể thay đổi nhanh chóng, nên cách tốt nhất là đóng gói chúng vào một đối tượng nhà máy factory. Theo cách làm này, bạn đã tách phần mã dễ thay đổi riêng biệt ra và giúp phần mã nguồn còn lại giữ vững nguyên tắc “đóng cho việc sửa đổi”
Chúng ta có thể nói rằng, toán tử new vẫn tốt trong mọi trường hợp, nhưng khi mã tạo dựng đối tượng bị liên tục thay đổi, ta nên nghĩ đến việc đóng gói chúng bằng mẫu thiết kế nhà máy factory.
XÂY DỰNG MẪU NHÀ MÁY FACTORY ĐẦU TIÊN
Nhiều lập trình viên biết cách thức mà đối tượng nhà máy factory làm việc. Họ nghĩ đơn giản rằng, bạn có một đối tượng làm nhiệm vụ tạo ra đối tượng khác. Đó là cách mà đối tượng factory thường được tạo ra và sử dụng, tuy nhiên nó còn làm được nhiều hơn thế. Chúng ta hãy nhìn vào cách thông thường khi tạo một đối tượng nhà máy factory trước, sau đó xem xét định nghĩa chính xác từ sách của GOF, theo định nghĩa mà đối tượng nhà máy factory sẽ có nhiều điểm khác, nhiều sự uyển chuyển hơn.
Tạo dựng đối tượng nhà máy Factory
Ví dụ đầu tiên, FirstFactory, sẽ làm việc theo cách hiểu thông thường nhất. Lớp FirstFactory đóng gói đối tượng xây dựng connection, và bạn truyền giá trị tham số theo đúng loại muốn tạo đó là “Oracle” hay “SQL Server” hay loại gì khác. Đây là cách bạn tạo một đối tượng sử dụng nhà máy factory :

Bây giờ, bạn có thể sử dụng đối tượng nhà máy factory mới tạo này, để tạo đối tượng kết nối connection, bằng cách gọi phương thức tên createConnection như sau:

Vậy bạn đã tạo lớp nhà máy FirstFactory như thế nào? Hãy xem mã sau:

Đầu tiên bạn truyền kiểu kết nối vào phương thức khởi tạo của lớp FirstFactory.
Lớp FirstFactory chứa đựng một phương thức createConnection dùng để tạo ra một đối tượng kết nối connection thật sự. Đây là nơi bạn phải chỉnh sửa mã nguồn nhiều nhất tùy theo loại kết nối muốn tạo, mã như sau:

Kết quả, bạn đã có một lớp nhà máy factory.
Tạo một lớp kết nối Connection trừu tượng
Hãy nhớ rằng một trong những mục tiêu của chúng ta khi viết mã, là làm sao việc thay đổi phần chính của mã nguồn càng ít càng tốt. Với mục tiêu đó, hãy nhìn đoạn mã sau làm việc, khi ta sử dụng một đối tượng connection được tạo bởi đối tượng nhà máy factory:

Bạn có thể thấy rằng, đối tượng kết nối connection được tạo bởi nhà máy factory, được sử dụng khắp nơi trong mã nguồn. Để sử dụng cùng một đoạn mã cho tất cả các loại kết nối khác nhau (Oracle,MySQL...), đoạn mã cần phải được viết theo tính “đa hình”, có nghĩa là tất cả các đối tượng connection, đều có cùng một giao diện interface, hay cùng kế thừa từ một lớp cơ sở. Theo cách đó, bạn có thể sử dụng cùng một biến cho mọi loại đối tượng kết nối.
Trong ví dụ, tôi tạo một lớp trừu tượng connection, để các lớp khác kế thừa nó. Lớp này gồm một phương thức khởi dựng, và một phương thức description ( trả về mô tả của loại đối tượng ). Mã như sau:

OK. Mọi việc có vẻ tốt đẹp. Bây giờ bạn đã tạo một lớp trừu tượng cơ sở cho các lớp kết nối khác kế thừa. Bạn cần phải kế thừa tất cả các đối tượng kết nối connection tạo ra từ lớp nhà máy factory.
Tạo lớp kế nối connection
Có ba lớp kết nối connection mà nhà máy Factory có thể tạo ra, phù hợp với loại kết nối mà Vị giám đốc mong muốn: OracleConnection,SqlServerConnection,MySQLConnecti on. Như chúng ta vừa nói, cần phải kế thừa từ lớp trừu tượng vừa tạo. Và mỗi loại trong chúng đều có phương thức decription trả về mô tả của từng loại kết nối một. Đây là mã nguồn của lớp OracleConnection:

Đây là lớp SqlServerConnection, cũng kế thừa từ lớp trừu tượng Connection:

Và lớp MySqlConnection cũng tương tự:

Tuyệt với. Mọi việc hoàn tất. Giờ là lúc thử nghiệm chúng. Đầu tiên ta tạo lớp nhà máy, truyền tham số khởi dựng là Oracle:


Để kiểm tra lại đối tượng connection được tạo có phải là Oracle không, ta gọi phương thức description như sau:

Kết quả bạn nhận được

Không tồi. Đó là những gì bạn mong đợi.
Ghi nhớ:Theo sách GoF, mẫu thiết kế phương thức nhà máy Factory Method được định nghĩa “Định nghĩa một giao diện để tạo một đối tượng, nhưng cho phép các lớp con quyết định cách thức thể hiện nó. Phương thức nhà máy Factory cho phép một lớp trì hoãn việc hiện thực của nó qua các lớp con”
Điểm mấu chốt ở đây là phần “để lớp con quyết định”. Cho tới bây giờ, lớp nhà máy Factory mà bạn vừa tạo, vẫn chưa cho phép các lớp con quyết định cách thể hiện, trừ việc cho kế thừa và ghi đè lại phương thức của lớp Connection cơ sở.
Mẫu thiết kế phương thức nhà máy Factory Method của GoF đem đến cho bạn khả năng uyển chuyển hơn phương pháp truyền thống rất nhiều. Cách làm của GoF là: bạn định nghĩa cách phương thức nhà máy Factory làm việc, và cho phép các lớp con hiện thực implement một nhà máy factory thật sự.
Chúng ta đã nói rằng, Hội đồng quản trị khu vực Western bất ngờ gọi điện và yêu cầu họ không thích lớp nhà máy FirstFactory, họ muốn có thể tạo ra các kết nối bảo mật đến máy chủ cơ sở dữ liệu, không chỉ là một kết nối thông thường. Điều này có nghĩa là họ phải viết lại lớp nhà máy FirstFactory mỗi khi bạn thay đổi nó, để họ có thể tạo ra một kết nối bảo mật.
Đây là vấn đề của các lập trình viên. Mỗi khi bạn cập nhật lại lớp FirstFactory, các lập trình viên khác phải viết lại mã của họ để thích hợp với yêu cầu của họ. Họ đang gọi và yêu cầu rằng họ muốn kiểm soát được quá trình nhiều hơn.
Tốt thôi, bạn nói. Đó chính là vấn đề mẫu thiết kế Factory áp dụng, giao quyền kiểm soát cho các lớp con. Để thấy cách mẫu này hoạt động, bạn thay đổi cách tạo đối tượng kết nối connection, sử dụng kỹ thuật của GoF, bạn sẽ làm cho khu vực Western của công ty MegaGigaCo hài lòng.
Gợi ý: Bạn vẫn còn băn khoăn về cách sử dụng của mẫu nhà máy Factory của GoF? Mẫu Factory được sử dụng khi bạn muốn chuyển giao toàn bộ quyền điều khiển các lớp con cho các lập trình viên khác.
TẠO MỘT NHÀ MÁY FACTORY THEO CÁCH CỦA GoF
Làm cách nào để “cho phép các lớp con toàn quyền hiện thực cách lớp con thể hiện” khi tạo một đối tượng nhà máy factory. Cách mà bạn phải làm là định nghĩa lớp nhà máy factory như là một lớp trừu tượng abstract hay giao diện interface, và để cho các lớp con hiện thực implement nó.
Nói cách khác, bạn tạo ra một khung sườn cho lớp nhà máy Factory tại trụ sở của MegaGigaCo, và việc hiện thực lớp này sẽ do các lớp con đảm nhiệm.
Tạo lớp nhà máy trừu tượng factory
Việc tạo lớp trừu tượng factory rất dễ dàng. Lớp này được gọi là ConnectionFactory

Bên cạnh một phương thức khởi dựng rỗng, phương thức quan trọng nhất ở đây là phương thức nhà máy createConnection. Ta phải làm cho phương thức mang tính trừu tượng, để các lớp con hiện thực nó. Phương thức này nhận một đối số, đó là loại kết nối cần tạo:

Và đó là tất cả những gì bạn cần. Sự đặc tả cho đối tượng nhà máy factory. Bây giờ khu vựa Western sẽ hài lòng vì họ có thể hiện thực một đối tượng nhà máy cụ thể thích hợp với họ từ lớp trừu tượng trên.
Tạo một lớp nhà máy factory cụ thể
Bạn đã bay tới khu vực Western của công ty MegaGigaCo, để giúp họ xử lý vấn đề tạo đối tượng. Bạn giải thích ”Tôi hiểu rằng các anh muốn được quyền điều khiển nhiều hơn đối với các đối tượng kết nối”
“Vâng” các lập trình viên của Western nói. “Chúng tôi muốn có thể làm việc với các kết nối bảo mật. Chúng tôi đã tạo một vài lớp mới, lớp SecureOracleConnection, SecureSqlServerConnection và SecureMySqlConnection để tạo ra các kết nối bảo mật.
“OK” bạn nói. “tất cả những gì các bạn phải làm là mở rộng lớp trừu tượng mới của tôi, tên là ConnectionFactory khi các bạn muốn tạo đối tượng nhà máy factory cho các bạn. Hãy chắc chắn là các bạn sẽ hiện thực phương thức createConnection. Sau đó bạn có thể tùy ý viết mã cho phương thức createConnection để tạo đối tượng theo đúng cách bảo mật mà bạn muốn”
Các lập trình viên của Western nói. “Wa, thật dễ dàng. Chúng tôi sẽ tạo lớp factory mới với tên SecureFactory, và nó sẽ kế thừa từ ConnectionFactory như sau:

“Tiếp theo,” các lập viên của khu vực Western nói “Chúng chỉ cần hiện thực lớp createConnection mà lớp trừu tượng ConnectionFactory yêu cầu:

“Cuối cùng,” các lập trình viên nói “chúng ta chỉ cần tạo các đối tượng từ các lớp vừa tạo, lớp SecureOracleConnection, SecureSqlServerConnection và SecureMySqlConnection, tùy thuộc vào kiểu dữ liệu được truyền vào hàm createConnection:

“Thật đơn giản” Họ nói.
Sự khác biệt giữa cách tạo mẫu nhà máy factory thông thường và cách của GoF là cách của GoF chỉ đặc tả lớp nhà máy factory và để cho các lớp con xử lý nội dung chi tiết.
Tạo các lớp kết nối bảo mật
Để hiểu rõ cách thức GoF tạo mẫu factory, bạn cần tạo các lớp cụ thể cho đối tượng nhà máy connect mới, lớp SecureOracleConnection, SecureSqlServerConnection và lớp SecureMySqlConnection. Thật dễ dàng để tạo chúng ,bắt đầu từ lớp SecureOracleConnection, với hàm description trả về văn bản “Oracle Secure”:

Tiếp theo là lớp SecureSqlServerConnection, với hàm description trả về văn bản “SQL Server Secure”

Và lớp SecureMySqlConnection, với hàm description trả về văn bản “MySql Secure”:

Vậy là đã hoàn tất phần mã nguồn. Giờ là lúc cho chương trình chạy.
Thực thi chương trình
Để kiểm tra mã nguồn, hãy tạo đối tượng SecureFactory và sử dụng nó để tạo đối tượng SecureOracleConnection. Mã như sau:

Tất cả những gì bạn cần phải làm là sử dụng hàm createConnection của đối tượng nhà máy factory để tạo các kết nối an toàn. Mã như sau:

Khi chạy chương trình, đúng như mong đợi, bạn nhận được văn bản sau, chứng tỏ rằng bạn đang sử dụng một kết nối Oracle bảo mật:

Đây cũng là kết quả mà bạn nhận được từ ví dụ FirstFactory mà chúng ta đã nói trong phần trước, ngoại trừ một điều là bạn cho phép khu vựa Western tự mình hiện thực loại nhà máy factory mà họ mong muốn. Bạn đặc tả một lớp nhà máy bằng cách tạo ra một lớp trừu tượng hay một giao diện interface để các lớp con sử dụng, và người khác sẽ tự mình quyết định lớp đó thực hiện như thế nào. Không còn việc sử dụng một đối tượng nhà máy cụ thể, nay tập hợp các lớp con quyết định việc thể hiện chúng như thế nào.
No comments:
Post a Comment