Design Pattern - Factory Method
Bài đăng này đã không được cập nhật trong 3 năm
Để hiểu hơn về factory, hãy cùng bắt đầu với một vấn đề trong lập trình. Hãy tưởng tượng bạn được yêu cầu build một mô hình cuộc sống trong một cái ao, với những chú vịt. Bạn sẽ làm thế nào ?
Đầu tiên hãy xây dựng class cho chú vịt Duck
class Duck
def initialize(name)
@name = name
end
def eat
puts("Duck #{@name} is eating.")
end
def speak
puts("Duck #{@name} says Quack!")
end
def sleep
puts("Duck #{@name} sleeps quietly.")
end
end
Tiếp theo là cái ao Pond với nhiều vịt Duck:
class Pond
def initialize(number_ducks)
@ducks = []
number_ducks.times do |i|
duck = Duck.new("Duck#{i}")
@ducks << duck
end
end
def simulate_one_day
@ducks.each {|duck| duck.speak}
@ducks.each {|duck| duck.eat}
@ducks.each {|duck| duck.sleep}
end
end
Nếu giờ chúng ta có thêm yêu cầu xây dựng thêm object con ếch Frog ở vũng nước Puddle thì phải làm sao ? Sẽ rất dễ để tạo 1 class Frog vì nó khá giống với interface của con vịt Duck.
class Frog
def initialize(name)
@name = name
end
def eat
puts("Frog #{@name} is eating.")
end
def speak
puts("Frog #{@name} says Crooooaaaak!")
end
def sleep
puts("Frog #{@name} doesn't sleep; he croaks all night!")
end
end
Nhưng với class Pond thì hiện chúng ta đang implement chỉ khởi tạo cho Duck. Nếu muốn thêm Frog thì cần tách riêng các sinh vật sống trong ao, cụ thể là Duck hoặc Frog. Nếu bạn bằng cách nào đó có thể khiến class Pond hỗ trợ cả Duck và Frog thì cũng rất khó nếu muốn gọi ra các method của từng object vì chúng ta không thể biết chúng ta đang gọi object thuộc class nào.
Có một cách để giải quyết vấn đề chọn class phù hợp đó là tách thành các subclass thông qua một base class.
class Pond
def initialize(number_animals)
@animals = []
number_animals.times do |i|
animal = new_animal("Animal#{i}")
@animals << animal
end
end
def simulate_one_day
@animals.each {|animal| animal.speak}
@animals.each {|animal| animal.eat}
@animals.each {|animal| animal.sleep}
end
end
Chúng ta cần build 2 subclass của Pond, một cho Duck và một cho loại khác (Frog).
class DuckPond < Pond
def new_animal(name)
Duck.new(name)
end
end
class FrogPond < Pond
def new_animal(name)
Frog.new(name)
end
end
GoF gọi kỹ thuật giải quyết việc chọn class bằng cách chia thành các subclass là Factory Method pattern
.
UML diagram của pattern này như sau:
Trong ví dụ phía trên thì:
- Creator chính là Pond class
- Hai loại pond (DuckPond, FrogPond) chính là
ConcreteCreator
- Và 2 products là Duck class và Frog class.
Kết luận
Factory Method pattern
là một trong những design pattern được sử dụng phổ biến, nó cung cấp một trong những cách tốt nhất để tạo ra một object.
Trong Factory Method pattern
, chúng ta tạo ra object mà không lộ logic với client mà tham chiếu tới một đối tượng mới sử dụng một common interface.
Tham khảo
Github (updating):https://github.com/ducnhat1989/design-patterns-in-ruby
Sách: “DESIGN PATTERNS IN RUBY” của tác giả Russ Olsen
Bài viết liên quan:
All rights reserved