- Huỳnh Thái Toàn - MSSV: 23120175 (Nhóm trưởng)
- Triệu Tuấn Kiệt - MSSV: 23120137
- Lê Nhật Minh Tâm - MSSV: 23120163
- Thiết kế kiến trúc tổng thể của hệ thống theo mô hình 3 tầng
- Phân tích và thiết kế class diagram, luồng nghiệp vụ
- Xây dựng các lớp model: User, Trip, Booking
- Phát triển các service: UserService, TripService, BookingService
- Thiết lập các interface repository (IUserRepository, ITripRepository, IBookingRepository)
- Xây dựng lớp Application chính để quản lý toàn bộ hệ thống
- Review code và hỗ trợ giải quyết các vấn đề kỹ thuật
- Viết unit test
- Thiết kế và hiện thực các repository: UserRepository, TripRepository, BookingRepository
- Xây dựng lớp DatabaseConnection để quản lý kết nối dữ liệu
- Phát triển các DTO và mapper cho việc chuyển đổi dữ liệu
- Xử lý đọc/ghi file CSV, quản lý persistence
- Đảm bảo các repository tuân thủ interface đã định nghĩa
- Xử lý các tình huống lỗi trong việc truy cập dữ liệu
- Viết documentation
- Phát triển UI console: MenuHandler, InputHandler, OutputFormatter
- Xây dựng các view: UserView, TripView, BookingView
- Xây dựng các class tiện ích: Validator, Configuration
- Thiết kế menu và giao diện người dùng
- Xử lý validation đầu vào và format đầu ra
- Tạo các script build và deployment (build.bat)
- Viết tài liệu hướng dẫn sử dụng cho end-user
- Test UI/UX và cải thiện trải nghiệm người dùng
| Thành viên | Tỉ lệ đóng góp | Công việc chính |
|---|---|---|
| Huỳnh Thái Toàn | 35% | Kiến trúc hệ thống, Business Layer, Test Unit |
| Lê Nhật Minh Tâm | 32% | Data Access Layer, File I/O, Document |
| Triệu Tuấn Kiệt | 33% | Presentation Layer, UI/UX, Test Manual |
| Tổng | 100% |
| Thành viên | Tỉ lệ điểm |
|---|---|
| Huỳnh Thái Toàn | 33.33% |
| Lê Nhật Minh Tâm | 33.33% |
| Triệu Tuấn Kiệt | 33.33% |
| Tổng | 100% |
Video Demo - Travel Agency Management System [https://youtu.be/jP3l2pom2dk]
Nhóm đã phân chia công việc một cách rõ ràng dựa trên kiến trúc 3 tầng:
- Toàn: Chịu trách nhiệm thiết kế tổng thể và tầng Business Logic
- Tâm: Phụ trách tầng Data Access và quản lý dữ liệu
- Kiệt: Đảm nhiệm tầng Presentation và giao diện người dùng
Tiến độ được theo dõi qua:
- Sử dụng GitHub để quản lý source code và track changes
- Trao đổi qua nhóm chat để giải quyết vấn đề
So với mã nguồn gốc được viết theo phong cách thủ tục với các hàm toàn cục, chúng em đã tái cấu trúc hoàn toàn theo hướng đối tượng:
Mã nguồn gốc:
- Sử dụng biến toàn cục (global variables)
- Không có phân tách trách nhiệm
- Khó bảo trì và mở rộng
Mã nguồn sau khi cải tiến:
- Tổ chức thành các lớp rõ ràng theo từng chức năng
- Áp dụng kiến trúc 3 tầng (Presentation, Business, Data)
- Sử dụng interface và dependency injection
- Phân tách rõ ràng giữa UI, business logic và data access
- Dễ dàng test và maintain
-
Quản lý người dùng:
- Thêm validation đầy đủ cho thông tin người dùng
- Hỗ trợ tìm kiếm theo nhiều tiêu chí (ID, tên)
- Chinh sửa và xóa người dùng
- Thêm nguời dùng mới với thông tin đầy đủ
-
Quản lý chuyến đi chi tiết hơn:
- Quản lý địa điểm khởi hành
- Theo dõi số lượng chỗ ngồi còn trống
- Tim kiếm chuyến đi theo nhiều tiêu chí (ID, Tên)
- Thêm chuyến đi mới với thông tin đầy đủ
- Hỗ trợ chỉnh sửa và xóa chuyến đi
-
Quản lý đặt chỗ:
- Tự động tính toán giá dựa trên số người và loại chuyến đi
- Quản lý trạng thái booking (Pending, Confirmed, Cancelled)
- Kiểm tra tự động số chỗ còn trống
- Hỗ trợ hủy và chỉnh sửa booking
- Tim kiếm booking theo nhiều tiêu chí (ID, User ID, Trip ID)
- Menu hierarchical: Tổ chức menu theo nhóm chức năng logic
- Input validation: Kiểm tra và hướng dẫn người dùng nhập liệu đúng format
- Output formatting: Hiển thị dữ liệu dưới dạng bảng đẹp mắt, dễ đọc
- Error handling: Thông báo lỗi rõ ràng với hướng dẫn khắc phục
- Navigation: Dễ dàng quay lại menu chính hoặc thoát chương trình
- Confirmation dialogs: Xác nhận trước khi thực hiện các thao tác quan trọng
Chúng em đã thiết kế hệ thống theo kiến trúc 3 tầng (3-layer Architecture):
-
Presentation Layer (Tầng giao diện):
MenuHandler: Quản lý điều hướng menuInputHandler: Xử lý đầu vào từ người dùngOutputFormatter: Format và hiển thị dữ liệu- Các View classes:
UserView,TripView,BookingView
-
Business Layer (Tầng nghiệp vụ):
- Models:
User,Trip,Booking- Đại diện cho các thực thể nghiệp vụ - Services:
UserService,TripService,BookingService- Xử lý logic nghiệp vụ - Interfaces: Định nghĩa contract giữa các tầng
- Models:
-
Data Access Layer (Tầng dữ liệu):
- Repositories:
UserRepository,TripRepository,BookingRepository DatabaseConnection: Quản lý kết nối và file operations- DTOs: Data Transfer Objects cho việc mapping
- Repositories:
SOLID Principles:
-
Single Responsibility Principle (SRP):
- Mỗi class chỉ có một lý do để thay đổi
- VD:
UserServicechỉ xử lý logic nghiệp vụ liên quan đến User
-
Open/Closed Principle (OCP):
- Sử dụng interfaces để mở rộng chức năng mà không sửa đổi code cũ
- VD:
IUserRepositorycó thể implement nhiều cách lưu trữ khác nhau
-
Liskov Substitution Principle (LSP):
- Các derived class có thể thay thế base class mà không ảnh hưởng chương trình
- VD: Bất kỳ implementation nào của
IUserRepositoryđều hoạt động đúng
-
Interface Segregation Principle (ISP):
- Chia nhỏ interfaces thành các phần chuyên biệt
- VD:
IUserRepository,ITripRepositorytách biệt rõ ràng
-
Dependency Inversion Principle (DIP):
- High-level modules không phụ thuộc vào low-level modules
- Services phụ thuộc vào interfaces, không phụ thuộc concrete classes
OOP Principles:
- Encapsulation: Dữ liệu được che dấu trong private members, chỉ truy cập qua public methods
- Inheritance: Sử dụng kế thừa hợp lý cho các base classes
- Polymorphism: Sử dụng virtual functions và interfaces
- Abstraction: Tạo abstract interfaces cho repositories và services
-
Singleton Pattern:
- Áp dụng cho class
Application - Đảm bảo chỉ có một instance duy nhất của ứng dụng
static Application& getInstance();
- Áp dụng cho class
-
Repository Pattern:
- Tách biệt business logic khỏi data access logic
- Cung cấp interface thống nhất cho việc truy cập dữ liệu
- Dễ dàng thay đổi cơ chế lưu trữ (CSV, Database, API)
-
Factory Pattern:
RepositoryFactoryđể tạo các repository instances- Giúp quản lý việc khởi tạo objects phức tạp
-
Model-View-Controller (MVC):
- Mô hình này được áp dụng trong Presentation Layer
Viewclasses hiển thị dữ liệu,Controllerxử lý logic vàModelchứa dữ liệu
Hệ thống được kiểm thử toàn diện với cả kiểm thử tự động và kiểm thử thủ công. Chi tiết đầy đủ về kế hoạch kiểm thử có thể tham khảo tại TEST_PLAN.md.
Kiểm thử tự động với Google Test:
-
Kiểm thử đơn vị (Unit Tests):
- Kiểm thử Model: Kiểm tra constructor, getters/setters, validation cho User, Trip, Booking
- Kiểm thử Repository: Kiểm tra các thao tác CRUD, chức năng tìm kiếm, xử lý lỗi
- Kiểm thử Service: Kiểm tra logic nghiệp vụ, tích hợp với repositories
-
Tổ chức kiểm thử:
source/test/ ├── model_tests/ # Kiểm thử cho business models ├── repository_tests/ # Kiểm thử cho data repositories ├── service_tests/ # Kiểm thử cho business services ├── CMakeLists.txt # Cấu hình CMake ├── build_tests.bat # Script build └── TEST_PLAN.md # Chi tiết kế hoạch kiểm thử -
Hướng dẫn nhanh:
# Build và chạy tests cd source/test ./build_tests.bat # Windows ./build_tests.sh # Linux/Mac
-
Build và kiểm thử tự động:
- Script
build_tests.batđể build và chạy tests - Tích hợp CMake để quản lý dependencies
- Google Test framework tự động download và setup
- Xem chi tiết tại README.md
- Script
Kiểm thử thủ công:
- Kiểm thử UI/UX cho điều hướng menu
- Kiểm thử tích hợp cho quy trình end-to-end
- Kiểm thử hiệu năng với datasets lớn
- Kiểm thử chấp nhận người dùng
- Quy ước đặt tên:
- Classes: PascalCase (
UserService,BookingRepository) - Methods: camelCase (
getUserById,createBooking) - Private members: tiền tố underscore (
_userId,_name) - Constants: UPPER_SNAKE_CASE (
MAX_USERS,DEFAULT_CAPACITY)
- Classes: PascalCase (
-
Naming Convention:
- Classes: PascalCase (
UserService,BookingRepository) - Methods: camelCase (
getUserById,createBooking) - Private members: underscore prefix (
_userId,_name) - Constants: UPPER_SNAKE_CASE (
MAX_USERS,DEFAULT_CAPACITY)
- Classes: PascalCase (
-
Code Organization:
- Header files (.h) chứa declarations
- Implementation files (.cpp) chứa definitions
- Mỗi class một file riêng biệt
- Folder structure theo layers
-
Documentation:
- Doxygen comments cho tất cả public methods
- Inline comments cho logic phức tạp
-
Error Handling:
- Sử dụng exceptions
Hệ thống được tài liệu hóa đầy đủ bằng Doxygen, bao gồm:
Cấu trúc tài liệu:
- HTML Documentation: Tài liệu web đầy đủ với navigation và search
- Class Documentation: Mô tả chi tiết các classes, methods và attributes
- File Documentation: Tài liệu cho từng source file
- Dependency Graphs: Biểu đồ phụ thuộc giữa các modules
Truy cập tài liệu:
# Mở tài liệu HTML
cd source/docs/html
python3 -m http.server 8000
# Then open http://localhost:8000 in your browserl # LinuxCác tài liệu chính:
Application- Class quản lý chính của hệ thốngUser,Trip,Booking- Business models- Repository classes - Data access layer
- Service classes - Business logic layer
- View classes - Presentation layer
Tạo lại tài liệu:
# Yêu cầu Doxygen được cài đặt
doxygen DoxyfileTài liệu Doxygen cung cấp:
- Class hierarchy và inheritance diagrams
- Method signatures với parameters và return types
- Code examples và usage notes
- Cross-references giữa các components
- Include dependency graphs
Xem thêm tại thư mục source/docs/ để truy cập đầy đủ documentation
Travel Agency System - Class Diagram (lượt bỏ các chi tiết không cần thiết để giữ cho sơ đồ ngắn gọn)
classDiagram
class User {
-int id
-string name
-string address
-string phone
-string email
+User()
+getId() int
+getName() string
+setName(string) void
}
class Trip {
-int id
-string name
-double cost
-int availableSeats
-string startDate
-string endDate
+Trip()
+getId() int
+getName() string
+getCost() double
}
class Booking {
-int id
-int userId
-int tripId
-string bookingDate
-int numberOfPeople
-double totalCost
-string status
+Booking()
+getId() int
+getUserId() int
+getTripId() int
}
class IUserRepository {
<<interface>>
+getAll() vector
+getById(int) User
+add(User) bool
+update(User) bool
+remove(int) bool
}
class ITripRepository {
<<interface>>
+getAll() vector
+getById(int) Trip
+add(Trip) bool
+update(Trip) bool
+remove(int) bool
}
class IBookingRepository {
<<interface>>
+getAll() vector
+getById(int) Booking
+add(Booking) bool
+update(Booking) bool
+remove(int) bool
}
class UserRepository {
-DatabaseConnection dbConnection
+UserRepository()
+getAll() vector
+getById(int) User
+add(User) bool
+update(User) bool
+remove(int) bool
}
class TripRepository {
-DatabaseConnection dbConnection
+TripRepository()
+getAll() vector
+getById(int) Trip
+add(Trip) bool
+update(Trip) bool
+remove(int) bool
}
class BookingRepository {
-DatabaseConnection dbConnection
+BookingRepository()
+getAll() vector
+getById(int) Booking
+add(Booking) bool
+update(Booking) bool
+remove(int) bool
}
class UserService {
-IUserRepository userRepository
+UserService()
+getAllUsers() vector
+addUser(User) bool
+updateUser(User) bool
+deleteUser(int) bool
}
class TripService {
-ITripRepository tripRepository
+TripService()
+getAllTrips() vector
+addTrip(Trip) bool
+updateTrip(Trip) bool
+deleteTrip(int) bool
}
class BookingService {
-IBookingRepository bookingRepository
+BookingService()
+getAllBookings() vector
+createBooking(Booking) bool
+updateBooking(Booking) bool
+cancelBooking(int) bool
}
class DatabaseConnection {
-string dataPath
+DatabaseConnection()
+connect(string) bool
+disconnect() void
+isConnected() bool
}
class Application {
-UserService userService
-TripService tripService
-BookingService bookingService
+Application()
+initialize() void
+run() void
}
class MenuHandler {
-UserService userService
-TripService tripService
-BookingService bookingService
+MenuHandler()
+start() void
}
class InputHandler {
+getInt() int
+getString() string
+getChoice(int, int) int
+validateEmail(string) bool
}
class OutputFormatter {
+printHeader(string) void
+printSuccess(string) void
+printError(string) void
+printUser(User) void
+printTrip(Trip) void
+printBooking(Booking) void
}
UserRepository ..|> IUserRepository
TripRepository ..|> ITripRepository
BookingRepository ..|> IBookingRepository
UserService --> IUserRepository
TripService --> ITripRepository
BookingService --> IBookingRepository
UserRepository --> DatabaseConnection
TripRepository --> DatabaseConnection
BookingRepository --> DatabaseConnection
Application --> UserService
Application --> TripService
Application --> BookingService
Application --> MenuHandler
User "1" -- "0..*" Booking
Trip "1" -- "0..*" Booking
