Factory method

Factory method, đầy đủ là Factory method pattern, là thiết kế mẫu hướng đối tượng trong việc thiết kế phần mềm cho máy tính, nhằm giải quyết vấn đề tạo một đối tượng mà không cần thiết chỉ ra một cách chính xác lớp nào sẽ được tạo. Factory method giải quyết vấn đề này bằng cách định nghĩa một phương thức cho việc tạo đối tượng, và các lớp con thừa kế có thể override để chỉ rõ đối tượng nào sẽ được tạo. Nói chung, "factory method" thường được áp dụng cho những phương thức mà nhiệm vụ chính của nó là tạo ra đối tượng.

== Định nghĩa ==
Bản chất của mẫu thiết kế Factory là "Định nghĩa một giao diện (interface) cho việc tạo một đối tượng, nhưng để các lớp con quyết định lớp nào sẽ được tạo. "Factory method" giao việc khởi tạo một đối tượng cụ thể cho lớp con."

== Áp dụng ==
- "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.

=== Tóm lược ===
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.

Ví dụ một chương trình đọc tập tin ảnh và tạo ảnh thumbnail của nó.
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.

public interface ImageReader {
public class GifReader implements ImageReader {

public class JpegReader implements ImageReader {

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:

public class ImageReaderFactory {

Đoạn mã trong ví dụ bên trên sử dụng lệnh switch để chỉ định kết hợp một codice_1 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.

== Giới hạn ==
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:

Complex c = new Complex(-1, 0);

- 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

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ế).

== Ví dụ ==
=== C# ===
Pizza example:

public abstract class Pizza

public class HamAndMushroomPizza: Pizza

public class DeluxePizza: Pizza

public class SeafoodPizza: Pizza

// Somewhere in the code

=== JavaScript ===
Pizza example:

//Our pizzas
function HamAndMushroomPizza(){

function DeluxePizza(){

function SeafoodPizza(){

//Pizza Factory
function PizzaFactory(){

//Sử dụng
var pizzaPrice = new PizzaFactory().createPizza("Ham and Mushroom").getPrice();
alert(pizzaPrice);
== Sử dụng ==
- ADO.NET, IDbCommand.CreateParameter là ví dụ của việc dùng factory method để kết nối những lớp song song.
- Qt, 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 javax.xml.parsers package. e.g. javax.xml.parsers.DocumentBuilderFactory or javax.xml.parsers.SAXParserFactory.

== Xem thêm ==
- Design Patterns, the highly-influential book
- Abstract Factory, a pattern often implemented using factory methods
- Builder pattern, another creational pattern
- Template method pattern, which may call factory methods
- Factory object

== Các tham khảo khác ==
- Factory method in UML and in LePUS3 (a Design Description Language)
- Description from the Portland Pattern Repository
- Jt J2EE Pattern Oriented Framework