Design Pattern - Composite
Bài đăng này đã không được cập nhật trong 3 năm
Xây dựng phần mềm hướng đối tượng là một quá trình thu thập các object đơn giản (các object này chỉ gồm các thành phần đơn giản như integer và string), rồi kết hợp thành những object phức tạp hơn như các hồ sơ nhân sự hay danh sách các bài hát.
Tuy nhiên đôi khi chúng ta lại muốn xây dựng một object phức tạp nhưng object này lại giống hệt những thành phần mà chúng ta sử dụng để xây dựng nó. Nó giống với quy trình làm bánh (Menufacture cake) trong hình sau:
Quy trình Manufacture Cake bao gồm Make Cake và Package Cake. Make Cake và Package Cake gồm nhiều quy trình nhỏ hơn. Những quy trình này chính là các object phức tạp mà chúng ta muốn xây dựng vì những quy trình này đều giống nhau, quy trình mức cao hơn thì chứa các quy trình mức thấp hơn. Ta có thể dễ dàng implement các quy trình trên 1 interface với tên quy trình (name), thời gian hoàn thành (time) và chứa các quy trình con (subtasks).
Xây dựng Composite
GoF gọi design pattern "các hoạt động tổng thể theo các thành phần con" là Composite pattern.
Tức là, khi cần xây dựng 1 hệ thống hoặc một cây các đối tượng mà không muốn khi code phải lo lắng xem liệu nó cần phải giải quyết một đối tượng đơn lẻ hay tổng thể cả một cây đối tượng thì ta cần sử dụng tới Composite pattern
Để xây dựng Composite pattern, ta cần 3 thành phần:
-
Đầu tiên, cần một infterface chung hoặc base class cho toàn bộ các đối tượng. (nó gọi là component). Khi xây dựng component hay nghĩ tới các điểm chung giữa các đối tượng cơ bản và các đối tượng ở mức cao hơn, Giống như việc làm bánh, các task đơn giản như ước lượng bột và task phức tạp như làm bột đều tiêu tốn thời gian.
-
Thứ hai, ta cần một hoặc nhiều leaf class - là các bước không thể phân chia được nữa (là bước ước lượng bột và thêm trứng). Các leaf class nên được implement Component interface.
-
Thứ ba, ta cần ít nhất một class ở mức cao hơn, gọi là composite class. Composite chính là một component, nhưng nó là đối tượng ở mức cao hơn được build từ các subcomponent. Trong ví dụ làm bánh thì composite là những task phức tạo như làm bột hoặc quy trình làm cả chiếc bánh.
#component base class
class Task
attr_reader :name
def initialize(name)
@name = name
end
def get_time_required
0.0
end
end
2 leaf class
class AddDryIngredientsTask < Task
def initialize
super('Add dry ingredients')
end
def get_time_required
1.0
# 1 minute to add flour and sugar
end
end
class MixTask < Task
def initialize
super('Mix that batter up!')
end
def get_time_required
3.0
# Mix for 3 minutes
end
end
Task ở mức cao hơn (composite):
class MakeBatterTask < Task
def initialize
super('Make batter')
@sub_tasks = []
add_sub_task( AddDryIngredientsTask.new )
add_sub_task( AddLiquidsTask.new )
add_sub_task( MixTask.new )
end
def add_sub_task(task)
@sub_tasks << task
end
def remove_sub_task(task)
@sub_tasks.delete(task)
end
def get_time_required
time=0.0
@sub_tasks.each {|task| time +=task.get_time_required}
time
end
end
class MakeBatterTask
chính là 1 task composite, ngoài ra chúng ta còn cần xây dựng các task composite khác như packaging the cake và manufacturing the cake. Các task này cũng giống với MakeBatterTask nhưng nó bao gồm các subclass khác nhưng xử lý trong class là tương đương. Vì thế chúng ta có thể tạo 1 base class cho những task composites
class CompositeTask < Task
def initialize(name)
super(name)
@sub_tasks = []
end
def add_sub_task(task)
@sub_tasks << task
end
def remove_sub_task(task)
@sub_tasks.delete(task)
end
def get_time_required
time=0.0
@sub_tasks.each {|task| time += task.get_time_required}
time
end
end
class MakeBatterTask < CompositeTask
def initialize
super('Make batter')
add_sub_task( AddDryIngredientsTask.new )
add_sub_task( AddLiquidsTask.new )
add_sub_task( MixTask.new )
end
end
class MakeCakeTask < CompositeTask
def initialize
super('Make cake')
add_sub_task( MakeBatterTask.new )
add_sub_task( FillPanTask.new )
add_sub_task( BakeTask.new )
add_sub_task( FrostTask.new )
add_sub_task( LickSpoonTask.new )
end
end
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