Menu
CoddyTech

Hàm tạo đối tượng

Thuộc phần Lập trình hướng đối tượng trong hành trình Lua của Coddy. Bài học 62 trên 70.

Trong suốt khóa học này, bạn đã tạo đối tượng bằng cách gọi trực tiếp hàm khởi tạo: Circle:new(), Rectangle:new() và các hàm khác. Nhưng nếu bạn muốn tạo các loại đối tượng khác nhau dựa trên một điều kiện nào đó mà đoạn code gọi không cần biết phải dùng lớp cụ thể nào thì sao?

Đây là lúc mẫu Factory phát huy tác dụng. Factory chỉ đơn giản là một hàm tạo và trả về các đối tượng. Lợi ích chính là bên gọi không cần biết chi tiết về cách tạo đối tượng. Bên gọi chỉ cần yêu cầu factory tạo thứ mình cần.

local function createShape(shapeType)
    if shapeType == "circle" then
        return Circle:new(10)
    elseif shapeType == "square" then
        return Square:new(5)
    end
end

-- Phần code gọi hàm không cần biết về các lớp (class) Circle hay Square
local myShape = createShape("circle")
print(myShape:area())

Hàm factory (factory function) nhận một đối số chuỗi (string) và quyết định lớp (class) nào cần khởi tạo. Cách này tập trung logic tạo đối tượng vào một nơi. Nếu sau này bạn thêm một kiểu hình dạng mới, bạn chỉ cần sửa factory, không phải sửa mọi đoạn code tạo hình dạng.

Factory đặc biệt hữu ích khi việc tạo đối tượng cần thiết lập phức tạp, khi bạn muốn ẩn chi tiết triển khai hoặc khi kiểu đối tượng cụ thể phụ thuộc vào các điều kiện lúc chạy, chẳng hạn như đầu vào của người dùng hoặc tệp cấu hình.

challenge icon

Thử thách

Dễ

Hãy cùng xây dựng một nhà máy thú cưng! Thay vì tạo thú cưng trực tiếp bằng cách gọi hàm khởi tạo của từng lớp, bạn sẽ tạo một hàm nhà máy (factory function) để tạo ra loại thú cưng phù hợp dựa trên một đối số chuỗi đơn giản.

Bạn sẽ sắp xếp code trong bốn tệp:

  • Dog.lua: Tạo lớp Dog với hàm khởi tạo :new(name) để lưu tên thú cưng. Thêm phương thức :speak() trả về chuỗi "{name} says: Woof!" (trong đó {name} là tên của chó).
  • Cat.lua: Tạo lớp Cat có cấu trúc tương tự: hàm khởi tạo :new(name) và phương thức :speak() trả về "{name} says: Meow!".
  • PetFactory.lua: Đây là nơi mẫu nhà máy (Factory pattern) phát huy tác dụng! Tạo hàm createPet(petType, name) nhận hai đối số: một chuỗi cho biết loại thú cưng ("dog" hoặc "cat") và tên thú cưng. Hàm này sẽ trả về đối tượng thú cưng phù hợp. Nếu loại là "dog", hãy trả về một đối tượng Dog mới; nếu là "cat", hãy trả về một đối tượng Cat mới.
  • main.lua: Nạp module PetFactory. Đọc hai đầu vào: loại thú cưng và tên thú cưng. Dùng hàm nhà máy để tạo thú cưng, sau đó gọi phương thức :speak() của nó và in kết quả ra.

Điểm hay của mẫu nhà máy là code chính của bạn không cần nạp trực tiếp Dog hay Cat. Nó chỉ cần biết về nhà máy. Nhà máy xử lý mọi chi tiết về việc khởi tạo lớp nào.

Bạn sẽ nhận được hai đầu vào:

  1. Loại thú cưng (là "dog" hoặc "cat")
  2. Tên thú cưng (một chuỗi)

Ví dụ, nếu đầu vào là dog và Buddy, đầu ra sẽ là:

Buddy says: Woof!

Nếu đầu vào là cat và Whiskers, đầu ra sẽ là:

Whiskers says: Meow!

Tự làm thử

-- main.lua
-- Dùng PetFactory để tạo thú cưng

local PetFactory = require('PetFactory')

-- Đọc đầu vào
local petType = io.read()
local petName = io.read()

-- TODO: Dùng PetFactory.createPet để tạo thú cưng
-- TODO: Gọi phương thức (method) :speak() của thú cưng và in ra kết quả
quiz iconTự kiểm tra

Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.

Tất cả bài học trong Lập trình hướng đối tượng

Tự luyện tập: Trình biên dịch Lua online