[Design Pattern] Phần 4: Factory Pattern
[Design
Pattern] Phần 4: Factory Pattern
Ở phần 4 này chúng ta sẽ tìm hiểu về
Factory Pattern, với một cách hiểu đơn giản là loại pattern giúp cho chúng ta
không cần phải khởi tạo trực tiếp? Cụ thể nó là thế nào? Vì sao chúng ta lại cần
nó? Đừng nôn nóng, chỉ mới bắt đầu thôi. Nào, chúng ta hãy cùng tìm hiểu nào!
Tình
huống:
Một
công ty công nghệ vừa thành lập đang tuyển người cho các vị trí như sau: Lập
trình viên (Developer), Nhân viên kinh doanh (Sale), Kiểm thử phần mềm
(Tester). Những người muốn vào làm sẽ đăng ký vào công ty. Về cơ bản chúng ta sẽ
thiết kế như sau:
Công
ty sẽ có danh sách các nhân viên. Nhân viên nào vào công ty thì sẽ được thêm
vào danh sách.
Chúng
ta bắt đầu thiết kế các lớp. Đầu tiên là lớp Company
Lớp
Company sẽ có tên và danh sách các Employee. Hàm khởi tạo sẽ gán tên và tạo một
danh sách rỗng, và khi thêm Employee thì sẽ đưa nó vào danh sách công ty.
Tiếp
đến là Employee
Employee
là một abstract class và sẽ có tên. Kèm thêm đó là một hàm khởi tạo.
Ba
class tiếp theo sẽ kế thừa class Employee
Quá
quen thuộc với các bạn rồi nên mình sẽ không giải thích ở đây.
Chúng
ta giờ chú ý tới phần test. Chúng ta sẽ tạo ba đối tượng nhân viên thuộc ba
ngành khác nhau và thêm vào công ty.
Có
vẻ ổn nhỉ.
Nhưng
có đôi lúc bạn không muốn khởi tạo new trực tiếp như thế này (Vì sao thì chúng
ta sẽ tìm hiểu sau). Chúng ta sẽ muốn nó trông thế này cơ.
EmployeeFactory
giống như một “nhà máy” nơi sản xuất ra các employee khi ta gọi phương thức
getEmployee() (các tham số chúng ta đưa vào là các thông tin cần thiết cho
EmployeeFactory này sản xuất). Chúng ta hãy xây dựng class EmployeeFactory nào
EmployeeFactory
sẽ dựa vào job chúng ta nhập vào mà trả về một đối tượng tương ứng.
Bản
chất của Factory Design Pattern là tại vị trí client (người chỉ sử dụng đoạn
code của chúng ta (không chỉnh sửa)) thì họ không quan tâm đến việc đối tượng
đó được tạo ra như thế nào, họ chỉ cần gọi hàm yêu cầu lấy một đối tượng, nếu
có yêu cầu cho việc tạo đối tượng đó (tham số), họ sẽ đưa ra.
Để
làm rõ hơn cho vấn đề này, hãy tạo một tình huống thực tế hơn. Ta sẽ coi
EmployeeFactory chính là một bộ phận tuyển dụng (Hiring Agency). Bộ phận này có
một danh sách những người tương ứng với những kỹ năng gì, và khi công ty cần, họ
sẽ đưa cho công ty những người này. Mình sẽ xây dựng lại một lớp HiringAgency mới
như sau:
Bộ
phận này ban đầu có danh sách những người làm trong nghề. Những người ở đầu
danh sách là những người được bộ phận này đánh giá rất cao.
Công
ty 8TechBlog đưa ra yêu cầu cho bên bộ phận này tuyển một số người vào công ty.
Tổng
cộng họ cần là 2 dev, 1 tester và 1 sale.
Với
phương diện là một bộ phận tuyển dụng, chắc chắn họ sẽ đưa ra những nhân viên
sáng giá nhất cho công ty. Công việc này là công việc của Hiring Agency (HA),
công ty không cần quan tâm điều này. Cái công ty cần chỉ là khi công ty gọi yêu
cầu có nhân viên, bên HA phải đưa người qua đây làm nhân viên.
Bây
giờ cùng xây dựng tiếp cho lớp HiringAgency nào
Ta
có ba hằng số 1, 2, 3 đại diện cho ba nghề developer, tester và sale (Việc nhập
job bằng các hằng số thay cho việc nhập chuỗi như ví dụ EmployeeFactory trên sẽ
làm cho phía client đỡ phải xác định giá trị chuỗi phải có dạng như thế nào).
(Tại
constructor nhớ khởi tạo 3 danh sách nhé. Mình quên :D )
Phương
thức getEmployee() sẽ lựa chọn người trong danh sách để trả về (với loại danh
sách tùy thuộc vào công việc). list.get(0) tức là chọn người đứng đầu
danh sách, là người sáng giá nhất. Và list.remove(0) tức là gạch tên người
đó ra khỏi danh sách sau khi chọn.
Sau
khi chạy code thì ta nhận được như sau
Phía
company đã nhận được 2 dev, 1 tester và 1 sale. Còn ở phía ha thì đã gạch tên
những người đưa qua công ty ra khỏi danh sách.
Mẫu
này cũng không quá khó các bạn nhỉ!
Sơ
đồ thiết kế Factory Pattern về cơ bản sẽ trông như thế này
Product
chính là Employee, ConcreteProduct chính là các employee cụ thể (developer,
tester, sale). ConcreteCreator chính là cái EmployeeFactory cũng như cái
HiringAgency mà chúng ta xây dựng, hàm FactoryMethod() là getEmployee(). Còn
class Creator kia là lớp tổng quát (interface) chủ yếu để tổng quát hóa cũng
như khi có nhu cầu tạo product với nhiều cách khác nhau thì chúng ta có thể mở rộng thêm từ cái tổng quát đó.
Cảm ơn các bạn đã đón xem! Tuần này
có vẻ làm nhanh hơn so với mọi khi, có lẽ là do mẫu này không quá khó so với
các mẫu trước.
Trong quá trình viết bài có thể có một
số sai sót, mình cũng hơi lo là sẽ làm các bạn hiểu sai, nên các bạn chịu khó
tham khảo thêm nhiều bài viết khác nữa nhé =w=”!
Bài viết tuần tới sẽ nói về Adapter
Pattern. Mọi người cùng đón xem!
Nội dung bài viết thuộc về Lê Công Diễn. Có sự
tham khảo từ kha khá nhiều chỗ, mỗi chỗ một ít nên thôi khỏi ghi :3
Người viết: Lê Công Diễn
Mang đi nhớ ghi nguồn
Nhận xét
Đăng nhận xét