Design Pattern - Builder
Bài đăng này đã không được cập nhật trong 3 năm
Builder pattern là gì?
Với Factory Pattern, chúng ta có thể dễ dàng tạo ra đúng object cần thiết. Tuy nhiên việc tạo đúng đối tượng chưa hẳn đã là vấn đề chính khi thiết kế phần mềm. Vấn đề chính đôi khi là làm thế nào để lắp ráp các object đó lại với nhau. Công việc lắp ráp, cấu hình các object phức tạp sẽ dễ dàng hơn nếu chúng ta hiểu về Builder Pattern.
Ví dụ
Hãy thử tưởng tượng, chúng ta đang viết một hệ thống hỗ trợ cho một nhà máy sản xuất computer nhỏ. Mỗi máy tính sẽ được tùy chỉnh theo đơn đặt hàng vì thế ta cần theo dõi các thành phần cho mỗi máy. Ở đây, ta có thể giả sử mỗi máy tính sẽ gồm một màn hình (display), một motherboard và một số driver:
class Computer
attr_accessor :display
attr_accessor :motherboard
attr_reader :drives
def initialize(display=:crt, motherboard=Motherboard.new, drives=[])
@motherboard = motherboard
@drives = drives
@display = display
end
end
display
có thể là loại :crt
hoặc :lcd
motherboard
là 1 object, nó có một bộ nhớ memory nhất định với một CPU hoặc TurboCPU
class CPU
# Common CPU stuff...
end
class BasicCPU < CPU
# Lots of not very fast CPU-related stuff...
end
class TurboCPU < CPU
# Lots of very fast CPU stuff...
end
class Motherboard
attr_accessor :cpu
attr_accessor :memory_size
def initialize(cpu=BasicCPU.new, memory_size=1000)
@cpu = cpu
@memory_size = memory_size
end
end
drivers
có 3 loại: hard drive
, CD
, và DVD
class Drive
attr_reader :type # either :hard_disk, :cd or :dvd
attr_reader :size # in MB
attr_reader :writable # true if this drive is writable
def initialize(type, size, writable)
@type = type
@size = size
@writable = writable
end
end
Với những model đơn giản, chúng ta có thể xây dựng một Computer cơ bản:
# Build a fast computer with lots of memory...
motherboard = Motherboard.new(TurboCPU.new, 4000)
# ...and a hard drive, a CD writer, and a DVD
drives = []
drives << Drive.new(:hard_drive, 200000, true)
drives << Drive.new(:cd, 760, true)
drives << Drive.new(:dvd, 4700, false)
computer = Computer.new(:lcd, motherboard, drives)
Xây dựng một Builder như thế nào ?
Tư tưởng của Builder khá đơn giản, đó là đưa tất cả logic và đóng gói chúng vào một Class của riêng nó. Builder class phụ trách lắp ráp các thành phần của một object phức tạp. Mỗi một builder là một interface cho phép bạn chỉ định cấu hình của từng đối tượng theo từng bước.
class ComputerBuilder
attr_reader :computer
def initialize
@computer = Computer.new
end
def turbo(has_turbo_cpu=true)
@computer.motherboard.cpu = TurboCPU.new
end
def display=(display)
@computer.display=display
end
def memory_size=(size_in_mb)
@computer.motherboard.memory_size = size_in_mb
end
def add_cd(writer=false)
@computer.drives << Drive.new(:cd, 760, writer)
end
def add_dvd(writer=false)
@computer.drives << Drive.new(:dvd, 4000, writer)
end
def add_hard_disk(size_in_mb)
@computer.drives << Drive.new(:hard_disk, size_in_mb, true)
end
end
Các bước cấu hình một computer:
builder = ComputerBuilder.new
builder.turbo
builder.add_cd(true)
builder.add_dvd
builder.add_hard_disk(100000)
computer = builder.computer
Ý nghĩa của Builder
Builder không chỉ giảm bớt gánh nặng khi phải xây dựng một object phức tạp mà còn ẩn đi những chi tiết cài đặt một cách hoàn hảo.
Các director không cần phải biết cụ thể về các thành phần tạo nên các object mới. Như khi ta sử dụng ComputerBuilder
ta không cần biết về các Class DVD hay hard disk, ta chỉ cần yêu cầu cấu hình máy tính mình cần.
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