Hôm nay chúng ta tiếp tục tìm hiểu một pattern khá phổ biến trong nhóm Creational - Factory Method.

Phương châm

Factory Method cho rằng thay vì tạo mới nhiều loại Objecf, hãy chỉ define duy nhất một interace hoặc một abstract claas và cho các class con hoặc class implementation chịu trách nhiệm thực thi các method chức năng. Hay nói cách khác, chính các class con sẽ làm nhiệm vụ tạo mới các instance.

Factory Method còn được gọi là Virtual Constructor (constructor ảo) bởi hành vi của nó là dùng một constructor cho một class nhưng bên dưới lại tạo mới một class khác, cụ thể hơn. 

Ví dụ: sản phẩm ban đầu bạn phát triển chỉ dành cho một loại sản phẩm duy nhất - ví dụ bán xe đạp, cho một nhà đối tác duy nhất. Và sau đó theo thời gian business của bạn phát triển hơn, bạn dần có thêm những đối tác mới cùng với những mặt hàng mới (tất nhiên là nghiệp vụ xử lý cũng mới) - ví dụ bạn phải bán thêm linh kiện xe đạp, bán thêm xe đạp điện, và các loại xe đạp cao cấp hơn. Business phình ra chúng ta sẽ phải chỉnh sửa lại code khá nhiều cho business mới. Do đó chúng ta cần tổ chức code cho những phần chức năng tương tự để tối ưu cho việc mở rộng và tái sử dụng., hạn chế tối đa việc đập đi làm lại. Factory Method sẽ tỏ ra có ích trong những trường hợp thế này.

Lợi ích

  • Tránh được việc define những class cụ thể trong hàm xử lý, dẫn đến khi cần chỉnh sửa chúng ta sẽ tốn nhiều thời gian, công sức
  • Làm cho code có tính tái sử dụng cao.
  • Tạo nên tính nhất quán cao trong việc tạo và quản lý các object.

 

Khi nào 

Sơ đồ UML:

Code Sample:

// The creator class declares the factory method that must
// return an object of a product class. The creator's subclasses
// usually provide the implementation of this method.
class Dialog is
    // The creator may also provide some default implementation
    // of the factory method.
    abstract method createButton()

    // Note that, despite its name, the creator's primary
    // responsibility isn't creating products. It usually
    // contains some core business logic that relies on product
    // objects returned by the factory method. Subclasses can
    // indirectly change that business logic by overriding the
    // factory method and returning a different type of product
    // from it.
    method render() is
        // Call the factory method to create a product object.
        Button okButton = createButton()
        // Now use the product.
        okButton.onClick(closeDialog)
        okButton.render()


// Concrete creators override the factory method to change the
// resulting product's type.
class WindowsDialog extends Dialog is
    method createButton() is
        return new WindowsButton()

class WebDialog extends Dialog is
    method createButton() is
        return new HTMLButton()


// The product interface declares the operations that all
// concrete products must implement.
interface Button is
    method render()
    method onClick(f)

// Concrete products provide various implementations of the
// product interface.
class WindowsButton implements Button is
    method render(a, b) is
        // Render a button in Windows style.
    method onClick(f) is
        // Bind a native OS click event.

class HTMLButton implements Button is
    method render(a, b) is
        // Return an HTML representation of a button.
    method onClick(f) is
        // Bind a web browser click event.


class Application is
    field dialog: Dialog

    // The application picks a creator's type depending on the
    // current configuration or environment settings.
    method initialize() is
        config = readApplicationConfigFile()

        if (config.OS == "Windows") then
            dialog = new WindowsDialog()
        else if (config.OS == "Web") then
            dialog = new WebDialog()
        else
            throw new Exception("Error! Unknown operating system.")

    // The client code works with an instance of a concrete
    // creator, albeit through its base interface. As long as
    // the client keeps working with the creator via the base
    // interface, you can pass it any creator's subclass.
    method main() is
        this.initialize()
        dialog.render()

Chúc các bạn thành công.

AutoCode.VN

minhnhatict@gmail.com Creational Pattern