Menu
CoddyTech

Mẫu Factory

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

Mẫu Factory giao việc tạo đối tượng cho một hàm (function) hoặc phương thức riêng, cho phép bạn tạo instance mà không để lộ logic khởi tạo. Khác với Singleton, vốn kiểm soát số lượng instance, Factory tập trung vào việc tạo đối tượng linh hoạt dựa trên các tham số đầu vào.

Trong Go, hàm khởi tạo thường là một hàm trả về kiểu giao diện, cho phép bạn tạo các kiểu cụ thể khác nhau thông qua một API thống nhất:

type Notifier interface {
    Send(message string) string
}

type EmailNotifier struct{}
type SMSNotifier struct{}

func (e EmailNotifier) Send(message string) string {
    return "Email: " + message
}

func (s SMSNotifier) Send(message string) string {
    return "SMS: " + message
}

func NewNotifier(notifierType string) Notifier {
    switch notifierType {
    case "email":
        return EmailNotifier{}
    case "sms":
        return SMSNotifier{}
    default:
        return EmailNotifier{}
    }
}

Hàm nhà máy NewNotifier gói gọn quyết định về kiểu cụ thể cần tạo. Code phía máy khách chỉ làm việc với giao diện Notifier và không cần biết cách triển khai cụ thể:

notifier := NewNotifier("sms")
result := notifier.Send("Hello!")  // "SMS: Hello!"

Mẫu này phát huy hiệu quả khi bạn cần tạo đối tượng dựa trên các điều kiện lúc chạy, muốn tập trung logic khởi tạo phức tạp vào một nơi hoặc cần dễ dàng thêm các kiểu mới mà không sửa code phía client. Chỉ cần thêm một struct triển khai interface và cập nhật hàm factory.

challenge icon

Thử thách

Dễ

Hãy xây dựng một hệ thống chuyển đổi tài liệu bằng mẫu Factory nhé! Bạn sẽ tạo một factory tạo ra các bộ chuyển đổi tài liệu khác nhau dựa trên định dạng đích, giúp code phía máy khách làm việc với bất kỳ bộ chuyển đổi nào thông qua một giao diện thống nhất.

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

  • converter.go: Định nghĩa giao diện bộ chuyển đổi và các phần triển khai cụ thể.

    Tạo giao diện Converter với phương thức Convert(content string) string, nhận nội dung tài liệu và trả về kết quả đã chuyển đổi.

    Triển khai ba kiểu bộ chuyển đổi:

    • PDFConverter: phương thức Convert trả về PDF: [content]
    • HTMLConverter: phương thức Convert trả về HTML: <p>[content]</p>
    • MarkdownConverter: phương thức Convert trả về MD: # [content]

    Tạo hàm factory NewConverter(format string) Converter trả về bộ chuyển đổi phù hợp dựa trên chuỗi định dạng (pdf, html hoặc markdown). Với mọi định dạng không được nhận diện, hãy trả về PDFConverter làm mặc định.

  • main.go: Dùng factory để tạo bộ chuyển đổi và xử lý tài liệu.

    Đọc loại định dạng và nội dung tài liệu. Dùng factory để tạo bộ chuyển đổi phù hợp, sau đó chuyển đổi nội dung và in kết quả ra.

Chương trình sẽ nhận các đầu vào sau:

  • Dòng 1: Loại định dạng (pdf, html, markdown hoặc định dạng khác)
  • Dòng 2: Nội dung tài liệu cần chuyển đổi

Ví dụ, với đầu vào:

html
Welcome to Go Programming

Kết quả đầu ra sẽ là:

HTML: <p>Welcome to Go Programming</p>

Và với đầu vào:

markdown
Chapter One

Kết quả đầu ra sẽ là:

MD: # Chapter One

Và với đầu vào:

pdf
Annual Report 2024

Kết quả đầu ra sẽ là:

PDF: Annual Report 2024

Và với đầu vào:

docx
Meeting Notes

Kết quả đầu ra sẽ là:

PDF: Meeting Notes

Lưu ý rằng code chính không cần biết các kiểu bộ chuyển đổi cụ thể. Code chỉ yêu cầu factory cung cấp một bộ chuyển đổi rồi dùng giao diện. Nhờ vậy, bạn có thể dễ dàng thêm định dạng mới sau này mà không cần thay đổi code phía máy khách!

Tự làm thử

package main

import (
	"bufio"
	"fmt"
	"os"
)

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	
	// Đọc loại định dạng
	scanner.Scan()
	format := scanner.Text()
	
	// Đọc nội dung tài liệu
	scanner.Scan()
	content := scanner.Text()
	
	// TODO: Dùng factory để tạo bộ chuyển đổi phù hợp
	// TODO: Chuyển đổi nội dung và in ra kết quả
	
	fmt.Println(result)
}
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 Go online