Khác biệt giữa bản sửa đổi của “Factory method”
Nội dung được xóa Nội dung được thêm vào
Đang dịch |
Không có tóm lược sửa đổi |
||
Dòng 1:
[[Image:FactoryMethod.svg|thumb|right|300px|Factory method in [[Unified Modeling Language|UML]]]]
[[Image:Factory Method pattern in LePUS3.png|thumb|right|300px|Factory Method in [[Lepus3|LePUS3]]]]
Hàng 20 ⟶ 11:
* "Factory method" thường được dùng trong bộ phát triển (toolkit) hay framework, ở đó, đoạn mã của framework cần thiết phải tạo một đối tượng là những lớp con của ứng dụng sử dụng framework đó.
==Những lợi ích khác và biến thể==
Cho dù động cơ của mẫu thiết kế "Factory method" là cho phép lớp con được chọn lựa kiểu đối tượng nào sẽ được tạo, việc sử dụng factory method cũng có những lợi ích khác. Bởi thế, việc thường xuyên sử dụng "factory method" không chỉ cho việc tạo đối tượng một cách đa dạng mà còn lợi dụng những lợi ích khác. Những hàm như thế thì thường là tĩnh.
===
Factory method gói gọn lại việc tạo đối tượng. Điều này hữu dụng nếu quá trình tạo phức tạp. Ví dụ như nó phụ thuộc vào những điều chỉnh trong tập tin cấu hình hay phụ thuộc vào thông tin của người dùng nhập vào.
Chương trình hỗ trợ nhiều định dạng ảnh khác nhau, và mỗi định dạng ảnh sẽ có một lớp hỗ trợ việc đọc tập tin.
<source lang="java">
public interface ImageReader
Hàng 55 ⟶ 44:
}
</source>
Mỗi khi chương trình đọc một ảnh, nó cần phải tạo một đối tượng phù hợp để đọc ảnh đó dựa vào những thông tin trong tập tin. Việc này có thể gói gọn trong factory method:
<source lang="java">
public class ImageReaderFactory
Hàng 75 ⟶ 64:
</source>
Đoạn mã trong ví dụ bên trên sử dụng lệnh switch để chỉ định kết hợp một <code>imageType</code> với một đối tượng factory cụ thể. Ngoài ra, có thể thay thế câu lệnh switch bằng cách sử dụng một mảng.
==
Có 3 giới hạn đối với việc sử dụng factory method. Một liên quan đến việc sửa đổi (tạm dịch từ refactoring) mã nguồn hiện tại; Hai vấn đề khác liên quan đến thừa kế.
* Giới hạn đầu tiên là việc sửa đổi (refactoring) một lớp đã có sẵn để sử dụng factory sẽ làm hỏng ứng dụng. Ví dụ, nếu lớp Complex là một lớp chuẩn, có thể tồn tại nhiều đoạn mã sử dụng lớp này như sau:
<source lang="java">Complex c = new Complex(-1, 0);</source>
:Một khi chúng ta thấy cần thiết phải có hai factory khác nhau, chúng ta thay đổi lớp này. Tuy nhiên, vì hàm khởi tạo (constructor) bây giờ trở thành ''private'', đoạn mã này sẽ không được dịch nữa.
* Giới hạn thứ hai là do mẫu thiết kế này dựa vào việc sử dụng hàm khởi tạo ''private'', lớp này sẽ không thể được thừa kế và mở rộng. Các lớp con phải thừa kế hàm khởi tạo của lớp cha, nhưng việc này không thực hiện được vì hàm khởi tạo là ''private''.
* Giới hạn thứ ba là, nếu chúng ta mở rộng một lớp (ví dụ: tạo một hàm khởi tạo ''protected'' -- điều này nguy hiểm nhưng chấp nhận được), lớp con phải cung cấp lại tất cả các hàm factory với tất cả thông số phải chính xác (bao gồm tên hàm và tham số). Ví dụ, nếu lớp StrangeComplex thừa kế lớp Complex, trừ khi StrangeComplex cung cấp tất cả các hàm factory, nếu không việc gọi
* The third limitation is that, if we do extend the class (e.g., by making the constructor StrangeComplex.fromPolar(1, pi) sẽ trả ra đối tượng ''Complex'' thay vì đối tượng con (là StrangeComplex).
Những vấn đề trên có thể giải quyết bằng cách sử dụng ngôn ngữ lập trình (thay vì sử dụng mẫu thiết kế).
==
===C#===
Pizza example:
Hàng 188 ⟶ 178:
}
//Sử dụng
var pizzaPrice = new PizzaFactory().createPizza("Ham and Mushroom").getPrice();
alert(pizzaPrice);
</source>
==
*[[ADO.NET]], [http://msdn2.microsoft.com/en-us/library/system.data.idbcommand.createparameter.aspx IDbCommand.CreateParameter] là ví dụ của việc dùng factory method để kết nối những lớp song song.
*[[Qt (toolkit)|Qt]], [http://doc.trolltech.com/4.0/qmainwindow.html#createPopupMenu QMainWindow::createPopupMenu] is a factory method declared in a framework which can be overridden in application code.
* In [[Java (programming language)]] several factories are used in the [http://java.sun.com/j2se/1.4.2/docs/api/javax/xml/parsers/package-summary.html javax.xml.parsers] package. e.g. javax.xml.parsers.DocumentBuilderFactory or javax.xml.parsers.SAXParserFactory.
==
*[[Design Patterns]], the highly-influential book
*[[Abstract factory pattern|Abstract Factory]], a pattern often implemented using factory methods
Hàng 295 ⟶ 195:
*[[Factory object]]
==
*{{cite book
| last = Fowler | first = Martin
Hàng 324 ⟶ 224:
}}
==Các tham khảo khác==
*[http://www.lepus.org.uk/ref/companion/FactoryMethod.xml Factory method in UML and in LePUS3] (a Design Description Language)
*[http://c2.com/cgi/wiki?FactoryMethodPattern Description from the Portland Pattern Repository]
|