Chuyển tới nội dung chính

🗂️ Sắp Xếp Bếp - Code Organization

Chào mừng bạn đến bài học về tổ chức code - cách sắp xếp bếp để nấu ăn hiệu quả!

🎯 Món Ăn Hôm Nay

Tưởng tượng một nhà hàng lớn với nhiều khu vực:

  • Khu sơ chế: Rửa rau, thái thịt (packages cơ bản)
  • Khu chiên xào: Nấu món chính (main package)
  • Khu kho: Lưu trữ nguyên liệu (external packages)

Đó chính là cách tổ chức code trong Go!

🥘 Code Organization Là Gì?

Code Organization = Sắp xếp các khu vực trong bếp

Trong Go, chúng ta chia code thành:

  • Packages: Các khu vực bếp khác nhau
  • Folders: Kệ đựng đồ trong mỗi khu
  • main package: Bếp chính - nơi tạo ra món ăn cuối cùng
  • Import: Mượn dụng cụ/nguyên liệu từ khu khác
package main           // Bep chinh

import (
"fmt" // Muon bat dua tu kho
"myrestaurant/soche" // Lay nguyen lieu tu khu so che
)

func main() {
fmt.Println("Nha hang dang hoat dong!")
}

👨‍🍳 Câu Chuyện Trong Bếp

Hôm nay, Chef Minh mở nhà hàng mới. Anh nhận ra:

Vấn đề: Nếu để tất cả nguyên liệu, dụng cụ chung một chỗ → lộn xộn, khó tìm!

Giải pháp: Chia bếp thành nhiều khu vực:

  • Khu A: Sơ chế rau củ
  • Khu B: Chế biến thịt cá
  • Khu C: Nấu món chính
  • Kho: Lưu trữ nguyên liệu

Mỗi khu có công việc riêng, nhưng làm việc cùng nhau tạo nên món ăn hoàn chỉnh!

Đó chính là code organization - chia nhỏ để dễ quản lý.

📝 Công Thức Nấu (Code)

Ví Dụ 1: Cấu Trúc Bếp Đơn Giản

myrestaurant/
├── main.go # Bep chinh - noi tao ra mon an
├── go.mod # Danh sach nguyen lieu can thiet
└── menu/
└── pho.go # Cong thuc nau pho

File: main.go

package main

import (
"fmt"
"myrestaurant/menu"
)

func main() {
// Bep chinh goi mon pho tu khu menu
pho := menu.NauPho()
fmt.Println(pho)
}

File: menu/pho.go

package menu

// NauPho la cong thuc nau pho o khu menu
func NauPho() string {
// Cac buoc nau pho
nuocDung := "nuoc xuong"
banhPho := "banh pho tuoi"
thit := "thit bo"

return "Pho bo voi " + nuocDung + ", " + banhPho + ", " + thit
}

🔍 Giải Thích:

  • package main: Bếp chính - điểm bắt đầu của nhà hàng
  • package menu: Khu chuyên về menu món ăn
  • import "myrestaurant/menu": Mượn công thức từ khu menu
  • Hàm bắt đầu bằng chữ hoa (NauPho) → public (đầu bếp khác dùng được)
  • Hàm bắt đầu bằng chữ thường → private (chỉ trong bếp này dùng)

Ví Dụ 2: Cấu Trúc Bếp Đầy Đủ

myrestaurant/
├── main.go # Bep chinh
├── go.mod
├── menu/ # Khu menu
│ ├── pho.go
│ └── bun.go
├── soche/ # Khu so che
│ ├── rau.go
│ └── thit.go
└── kho/ # Kho luu tru
└── nguyenlieu.go

File: soche/rau.go

package soche

// RuaRau - ham public (chu hoa)
func RuaRau(tenRau string) string {
return "Da rua sach " + tenRau
}

// thaiRau - ham private (chu thuong)
func thaiRau(tenRau string) string {
return "Da thai " + tenRau
}

// ChuanBiRau - su dung ca 2 ham tren
func ChuanBiRau(tenRau string) string {
rauSach := RuaRau(tenRau)
rauThai := thaiRau(tenRau)
return rauSach + " va " + rauThai
}

File: main.go

package main

import (
"fmt"
"myrestaurant/soche"
"myrestaurant/menu"
)

func main() {
// Chuan bi nguyen lieu
rau := soche.ChuanBiRau("xa lach")
fmt.Println(rau)

// Nau mon
pho := menu.NauPho()
fmt.Println(pho)

// Loi! Ham private khong goi duoc
// soche.thaiRau("ca rot") // ❌ SAI - ham private
}

🔍 Giải Thích:

  • soche.ChuanBiRau(): Gọi hàm public từ package soche
  • soche.thaiRau(): KHÔNG thể gọi - hàm private (chữ thường)
  • Mỗi package có trách nhiệm riêng, dễ bảo trì

Ví Dụ 3: Sử Dụng Package Bên Ngoài

package main

import (
"fmt" // Package chuan cua Go
"time" // Package chuan ve thoi gian
"myrestaurant/menu" // Package cua minh
)

func main() {
// Lay gio hien tai
gio := time.Now().Hour()

if gio < 10 {
fmt.Println("Sang - phuc vu pho")
fmt.Println(menu.NauPho())
} else {
fmt.Println("Trua - phuc vu com")
}
}

🔍 Giải Thích:

  • Package từ Go standard library: fmt, time
  • Package tự viết: myrestaurant/menu
  • Kết hợp linh hoạt để tạo chương trình hoàn chỉnh

🔥 Thực Hành Trong Bếp

Bài Tập 1: Tạo Package Đồ Uống

Tạo cấu trúc sau:

myrestaurant/
├── main.go
└── douong/
└── cafe.go

File: douong/cafe.go

package douong

// PhaCafe - pha ca phe
func PhaCafe(loai string) string {
return "Ca phe " + loai + " da san sang!"
}

// themDuong - them duong (private)
func themDuong(luong int) string {
return "Da them duong"
}

File: main.go

package main

import (
"fmt"
"myrestaurant/douong"
)

func main() {
cafe := douong.PhaCafe("den")
fmt.Println(cafe)
}

Nhiệm vụ: Chạy thử và quan sát kết quả!

Bài Tập 2: Thêm Package Tính Tiền

Tạo package thanhtoan với hàm TinhTien(tenMon string, soLuong int) int

Gợi ý:

package thanhtoan

// TinhTien - tinh tien mon an
func TinhTien(tenMon string, soLuong int) int {
bangGia := map[string]int{
"pho": 50000,
"bun": 40000,
"com": 35000,
}

gia := bangGia[tenMon]
return gia * soLuong
}

Sử dụng trong main.go để tính tiền 2 tô phở!

Bài Tập 3: Tổ Chức Bếp Hoàn Chỉnh

Tạo cấu trúc nhà hàng với:

  • Package menu: Chứa các món ăn (pho, bun, com)
  • Package soche: Chuẩn bị nguyên liệu
  • Package thanhtoan: Tính tiền
  • main.go: Điều phối tất cả

Thử thách: Viết chương trình hoàn chỉnh từ đặt món → chuẩn bị → nấu → tính tiền!

⚠️ Những Lỗi Đầu Bếp Thường Gặp

Lỗi 1: Gọi Hàm Private Từ Package Khác

// File: menu/pho.go
package menu

func NauPho() string {
return "Pho bo"
}

func nauNuoc() string { // chu thuong = private
return "Nuoc xuong"
}

// File: main.go
package main

import "myrestaurant/menu"

func main() {
// ❌ SAI - ham private khong goi duoc
menu.nauNuoc() // Loi: undefined

// ✅ ĐÚNG - ham public goi duoc
menu.NauPho()
}

🔧 Cách sửa:

  • Hàm public phải bắt đầu bằng chữ HOA
  • Hàm private (chữ thường) chỉ dùng trong package đó

Lỗi 2: Package Name Không Khớp

// ❌ SAI
// File: menu/pho.go
package monchinh // Ten package khong khop voi ten thu muc

func NauPho() string {
return "Pho"
}

// ✅ ĐÚNG
// File: menu/pho.go
package menu // Ten package phai khop voi ten thu muc

func NauPho() string {
return "Pho"
}

🔧 Cách sửa: Tên package phải trùng với tên thư mục chứa nó

Lỗi 3: Import Sai Đường Dẫn

// ❌ SAI
import "menu" // Thieu ten module

// ✅ ĐÚNG
import "myrestaurant/menu" // Day du: module/package

🔧 Cách sửa:

  • Luôn dùng đường dẫn đầy đủ: module_name/package_name
  • Kiểm tra file go.mod để biết tên module

Lỗi 4: Quên Tạo go.mod

# ❌ SAI - chua co go.mod
cd myrestaurant
go run main.go # Loi: cannot find package

# ✅ ĐÚNG
cd myrestaurant
go mod init myrestaurant # Tao go.mod
go run main.go

🔧 Cách sửa: Luôn chạy go mod init trước khi tạo packages

💡 Bí Quyết Của Đầu Bếp

  1. Tên Package Ngắn Gọn:

    • menu, soche, thanhtoan
    • menumonanngon, khusochenguyenlieu
  2. Mỗi Package Một Trách Nhiệm:

    • Package menu: Chỉ về món ăn
    • Package thanhtoan: Chỉ về tính tiền
    • Không trộn lẫn trách nhiệm!
  3. Hàm Public vs Private:

    • Public (chữ HOA): Những gì người khác cần dùng
    • Private (chữ thường): Chi tiết nội bộ, không cần chia sẻ
  4. Cấu Trúc Thư Mục Rõ Ràng:

    myrestaurant/
    ├── cmd/ # Cac chuong trinh chinh
    ├── pkg/ # Cac package tai su dung
    ├── internal/ # Code rieng, khong chia se
    └── api/ # API endpoints
  5. Import Gọn Gàng:

    import (
    // Standard library truoc
    "fmt"
    "time"

    // External packages sau
    "github.com/gin-gonic/gin"

    // Local packages cuoi cung
    "myrestaurant/menu"
    "myrestaurant/soche"
    )
  6. Đặt Tên Module Đúng Chuẩn:

    • Nếu code trên GitHub: github.com/username/myrestaurant
    • Nếu code local: myrestaurant hoặc example.com/myrestaurant

🎓 Bạn Đã Học Được

  • ✅ Package = khu vực trong bếp, mỗi khu có chức năng riêng
  • package main = bếp chính, nơi bắt đầu chương trình
  • ✅ Import = mượn dụng cụ/công thức từ package khác
  • ✅ Hàm chữ HOA = public (ai cũng dùng được)
  • ✅ Hàm chữ thường = private (chỉ trong package đó)
  • go.mod = danh sách nguyên liệu cần thiết cho nhà hàng
  • ✅ Tổ chức code tốt = bếp gọn gàng, dễ tìm kiếm, dễ bảo trì

🍜 Món Tiếp Theo

Bếp đã sắp xếp gọn gàng! Giờ cần học cách kiểm tra độ chín của món ăn:

👉 Kiểm Tra Độ Chín - Control Structures


💡 Lời Khuyên Cuối: Bếp sắp xếp gọn gàng = code dễ đọc, dễ sửa, dễ mở rộng. Đầu tư thời gian sắp xếp bếp ngay từ đầu sẽ giúp bạn tiết kiệm rất nhiều thời gian sau này!