Thứ Năm, 21 tháng 2, 2013

Factory Method

1. Khái niệm

Factory Method định nghĩa 1 interface cho việc tạo ra một object nhưng để cho class con quyết định việc khởi tạo của object.

2. Vấn đề thực tế

Trong lập trình hướng đối tượng, khi có nhu cầu tạo một object, chúng ta thường dùng câu lệnh new để thực hiện. Giả sử có một interface Car, có một class LuxuryCar implement interface Car đó, như vậy việc khai báo để tạo một object LuxuryCar có kiểu Car sẽ như sau:
 
Car lcar = new LuxuryCar();


Câu lệnh trên là đúng về cú pháp lẫn logic. Tuy nhiên, chúng ta hãy suy nghĩ về tính mở rộng của nó. Giả sử trong tương lai, có thêm nhiều class cùng implement interface Car như SportCar, ModernCar, EconomyCar, ...khi đó, để khởi tạo một object kiểu Car, chúng ta cần biết loại class cần khởi tạo, để làm được điều này, chúng ta cần có logic để chọn ra đúng class cần tham gia khởi tạo, logic đó sẽ được thực hiện bởi một khối code (tạm gọi là khối code X). Như vậy, mỗi lần khởi tạo một object kiểu Car, chúng ta phải thực thi khối code X.

Điều gì xảy ra khi việc thực thi khối code X được lặp lại ở nhiều vị trí khác nhau trong chương trình? Điều gì xảy ra khi có sự thay đổi ở khối code X trong tương lai?

Câu trả lời là chúng ta phải tốn nhiều thời gian và phải chấp nhận các rủi ro trong quá trình tìm và chỉnh sửa từng khối code X ở những vị trí khác nhau trong chương trình.

Vậy chúng ta phải làm thế nào để giải quyết vấn đề này?

Factory Method sẽ giúp chúng ta giải quyết những vấn đề liên quan đến tính phức tạp trong quá trình tạo một object.

3. Giải pháp 

Factory Method sẽ dùng các Factory thực tế để tạo nên đối tượng thực tế đúng với kiểu đã được quy ước từ trước. Để làm được điều này, các Factory thực tế được kế thừa từ Factory trừu tượng (dùng interface hoặc abtract class), trong Factory trừu tượng sẽ định nghĩa function trừu tượng có chức năng tạo ra 1 họ class (class family). Class family trừu tượng sẽ định nghĩa chung về các tính năng của class con, các object sẽ được sinh ra từ các class con này.

Khối code X sẽ được đặt trong các Factory thực tế để khởi tạo object dùng các class tương ứng. Khi đó việc tạo một đối tượng sẽ như sau:

AbstractCarFactory car1Factory = new CarFactory();

Car car = carFactory.createCar(car_type);


car_type là kiểu String quy định loại Car cần khởi tạo, khối code X được đặt trong function createCar của class Car1Factory.

4. Mô hình




Các thành phần tham gia vào mô hình Factory Method bao gồm:

- Creator (ProductFactory): đóng vai trò như một mô hình sản xuất các interface Product, không trực tiếp sinh ra các object kiểu Product. Trong AbtractProductFactory phải có abstract function createProduct() dùng để tạo ra object kiểu Product.

- ConcreteCreator (ConcreteProductFactory): đóng vai trò là đối tượng sinh ra các object kiểu Product thực tế. ConcreteProductFactory kế thừa từ ProductFactory để override function createProduct() nhằm tạo đối tượng kiểu Product thực tế. Tùy theo giá trị của các tham số đầu vào mà ConcreteProductFactory có thể tạo ra các đối tượng kiểu Product như Product1 hoặc Product2.

- Product (Product): là 1 interface đóng vai trò định nghĩa các hành vi cho các đối tượng kiểu Product.

- ConcreteProduct (Product1, Product2): là các class kế thừa interface Product, có vai trò hiện thực hóa các đối tượng kiểu Product.

5. Code sample


public interface Product {

 public void display(String msg);

}


public class Product1 implements Product {

 public void display(String msg){
  System.out.println("Product 1 display: "+ msg); 
 }

}


public class Product2 implements Product {

 public void display(String msg){
  System.out.println("Product 2 display: "+ msg); 
 }

}


public class AbtractProductFactory {

 public void doSomething1() {
  Product product = createProduct();
  product.display("do 1");
 }

 public void doSomething2() {
  Product product = createProduct();
  product.display("do 2");

 }

 public abstract Product createProduct();

}


public class Product1Factory extends AbtractProductFactory {

 public Product createProduct() {
  return new Product1();
 }

}


public class Product2Factory extends AbtractProductFactory {

 public Product createProduct() {
  return new Product2();
 }

}


public class FactoryMethod{

 public static void main(String args[]){
  AbstractProductFactory product1Factory = new Product1Factory();
  product1Factory.doSomething1();
  product1Factory.doSomething2();

  AbstractProductFactory product2Factory = new Product2Factory();
  product2Factory.doSomething1();
  product2Factory.doSomething2();
 }

}

6. Mối liên quan với các pattern khác

Không có nhận xét nào:

Đăng nhận xét