บทนำ: ทำไมต้อง UML?
เมื่อเขียนโปรแกรมใหญ่ขึ้น การสื่อสารระหว่างทีมกลายเป็นปัญหา:
- วิศวกร A เข้าใจระบบไม่เหมือนวิศวกร B
- เอกสารเป็นตัวหนังสือยาวเหยียด อ่านไม่รู้เรื่อง
- โค้ดมีหลายพันบรรทัด มองไม่เห็นภาพรวม
UML (Unified Modeling Language) คือ ภาษากลาง ที่ใช้ วาดภาพระบบซอฟต์แวร์ ให้ทุกคนเห็นภาพเดียวกัน
ประโยชน์:
- 📊 มองเห็นภาพรวม – เข้าใจโครงสร้างระบบได้ทันที
- 💬 สื่อสารง่าย – ทีมเข้าใจตรงกัน
- 📝 เป็นเอกสาร – blueprint ก่อนเขียนโค้ด
- 🔍 วิเคราะห์ปัญหา – เห็นจุดอ่อนของระบบ
- บทนำ: ทำไมต้อง UML?
- UML Diagrams: ภาพรวม 14 ประเภท
- 1. Structure Diagrams (โครงสร้าง) – 7 ประเภท
- 2. Behavior Diagrams (พฤติกรรม) – 7 ประเภท
- Class Diagram: Diagram สำคัญที่สุด
- โครงสร้าง Class Diagram
- Class Box: กล่องแสดง Class
- Access Modifiers: สัญลักษณ์การเข้าถึง
- ตัวอย่าง: Class Diagram แรก
- ตัวอย่าง: Static Members
- Relationships: ความสัมพันธ์ระหว่าง Classes
- 1. Association (เชื่อมโยง)
- 2. Aggregation (รวมกัน – แบบหลวม)
- 3. Composition (ประกอบด้วย – แบบแน่น)
- 4. Inheritance (สืบทอด)
- 5. Realization/Implementation (ทำตาม Interface)
- 6. Dependency (พึ่งพา)
- ตัวอย่างที่ 1: ระบบจัดการนักศึกษา
- Code
- Class Diagram
- Multiplicity: จำนวนความสัมพันธ์
- ตัวอย่าง: Multiplicity
- ตัวอย่างที่ 2: ระบบห้องสมุด (Library System)
- Requirements
- Code
- Class Diagram
- Abstract Class และ Interface ใน UML
- Abstract Class
- Interface
- สรุปตอนที่ 1
- ตัวอย่างท้ายตอน: E-Commerce System (Partial)
UML Diagrams: ภาพรวม 14 ประเภท
UML มี 14 ประเภท แบ่งเป็น 2 กลุ่มใหญ่:
1. Structure Diagrams (โครงสร้าง) – 7 ประเภท
แสดงโครงสร้างคงที่ของระบบ
| Diagram | ความหมาย | ใช้เมื่อ |
|---|---|---|
| Class Diagram | โครงสร้าง classes และความสัมพันธ์ | ออกแบบ OOP |
| Object Diagram | instances ของ objects ในเวลาหนึ่ง | แสดงตัวอย่างข้อมูล |
| Component Diagram | โครงสร้างของ components | แบ่งระบบใหญ่ |
| Deployment Diagram | การติดตั้งบน hardware | วาง architecture |
| Package Diagram | การจัดกลุ่ม classes | จัดระเบียบโปรเจค |
| Composite Structure | โครงสร้างภายใน class | ออกแบบซับซ้อน |
| Profile Diagram | ขยาย UML | ปรับแต่ง UML |
2. Behavior Diagrams (พฤติกรรม) – 7 ประเภท
แสดงการทำงานและการเปลี่ยนแปลงของระบบ
| Diagram | ความหมาย | ใช้เมื่อ |
|---|---|---|
| Use Case Diagram | ฟังก์ชันของระบบ | กำหนด requirements |
| Activity Diagram | ขั้นตอนการทำงาน (flowchart) | วาดกระบวนการ |
| State Machine Diagram | สถานะของ object | lifecycle ของ object |
| Sequence Diagram | ลำดับการส่งข้อความ | interaction ตามเวลา |
| Communication Diagram | การสื่อสารระหว่าง objects | interaction แบบเน้น structure |
| Timing Diagram | เวลาในการทำงาน | real-time systems |
| Interaction Overview | ภาพรวม interactions | รวม sequence diagrams |
Class Diagram: Diagram สำคัญที่สุด
Class Diagram คือ ไดอะแกรมที่สำคัญที่สุด ใน UML สำหรับ OOP
แสดง:
- Classes ที่มีในระบบ
- Attributes และ Methods ของแต่ละ class
- ความสัมพันธ์ระหว่าง classes
โครงสร้าง Class Diagram
Class Box: กล่องแสดง Class
text┌──────────────────────┐
│ ClassName │ ← ชื่อ class
├──────────────────────┤
│ - attribute1: type │ ← attributes
│ - attribute2: type │
├──────────────────────┤
│ + method1(): type │ ← methods
│ + method2(): type │
└──────────────────────┘
แบ่งเป็น 3 ส่วน:
- ส่วนบน – ชื่อ class
- ส่วนกลาง – attributes (fields)
- ส่วนล่าง – methods (operations)
Access Modifiers: สัญลักษณ์การเข้าถึง
| สัญลักษณ์ | ความหมาย | Java |
|---|---|---|
+ | public | public |
- | private | private |
# | protected | protected |
~ | package/default | ไม่ระบุ |
ตัวอย่าง: Class Diagram แรก
Code:
javapublic class Student {
private String studentID;
private String name;
private double gpa;
public Student(String studentID, String name, double gpa) {
this.studentID = studentID;
this.name = name;
this.gpa = gpa;
}
public void study() {
gpa += 0.1;
}
public double getGPA() {
return gpa;
}
public void displayInfo() {
System.out.println("ID: " + studentID);
}
}
Class Diagram:
text┌─────────────────────────┐
│ Student │
├─────────────────────────┤
│ - studentID: String │
│ - name: String │
│ - gpa: double │
├─────────────────────────┤
│ + Student(id, name, gpa)│
│ + study(): void │
│ + getGPA(): double │
│ + displayInfo(): void │
└─────────────────────────┘
ตัวอย่าง: Static Members
Code:
javapublic class BankAccount {
private static String bankName = "Bangkok Bank";
private static int totalAccounts = 0;
private String accountNumber;
private double balance;
public BankAccount(String accountNumber, double balance) {
this.accountNumber = accountNumber;
this.balance = balance;
BankAccount.totalAccounts++;
}
public void deposit(double amount) {
balance += amount;
}
public static int getTotalAccounts() {
return totalAccounts;
}
}
Class Diagram:
text┌────────────────────────────────┐
│ BankAccount │
├────────────────────────────────┤
│ - bankName: String {static} │ ← static = underline
│ - totalAccounts: int {static} │
│ - accountNumber: String │
│ - balance: double │
├────────────────────────────────┤
│ + BankAccount(num, bal) │
│ + deposit(amount): void │
│ + getTotalAccounts(): int {static} │
└────────────────────────────────┘
หมายเหตุ: Static members ใช้ underline (ขีดเส้นใต้)
Relationships: ความสัมพันธ์ระหว่าง Classes
Class Diagram ไม่ได้มีแค่ classes เดี่ยวๆ แต่แสดงความสัมพันธ์ด้วย
มี 6 ประเภทหลัก:
1. Association (เชื่อมโยง)
ความหมาย: Class A รู้จัก Class B (มีการใช้งานกัน)
สัญลักษณ์: เส้นตรง ────
ตัวอย่าง: Teacher สอน Student
text┌──────────┐ ┌──────────┐
│ Teacher │────────────│ Student │
└──────────┘ teaches └──────────┘
Code:
javapublic class Teacher {
private String name;
public void teach(Student student) {
// Teacher ใช้งาน Student
System.out.println("Teaching " + student.getName());
}
}
public class Student {
private String name;
public String getName() {
return name;
}
}
2. Aggregation (รวมกัน – แบบหลวม)
ความหมาย: Class A มี Class B แต่ B สามารถอยู่ได้โดยไม่มี A
สัญลักษณ์: เส้น + ข้าวหลามตัดขาว ◇────
ตัวอย่าง: Department มี Teacher
text┌────────────┐ ┌──────────┐
│ Department │◇────────│ Teacher │
└────────────┘ └──────────┘
contains
Code:
javapublic class Department {
private String deptName;
private ArrayList<Teacher> teachers; // มี teachers
public void addTeacher(Teacher teacher) {
teachers.add(teacher);
}
}
public class Teacher {
private String name;
// Teacher สามารถอยู่ได้โดยไม่มี Department
}
หมายเหตุ: ถ้าลบ Department, Teacher ยังอยู่ได้
3. Composition (ประกอบด้วย – แบบแน่น)
ความหมาย: Class A มี Class B และ B ไม่สามารถอยู่ได้โดยไม่มี A
สัญลักษณ์: เส้น + ข้าวหลามตัดดำ ◆────
ตัวอย่าง: House มี Room
text┌────────┐ ┌────────┐
│ House │◆─────────│ Room │
└────────┘ └────────┘
contains
Code:
javapublic class House {
private String address;
private Room[] rooms; // มี rooms
public House(String address) {
this.address = address;
// สร้าง rooms พร้อม house
this.rooms = new Room[5];
for (int i = 0; i < 5; i++) {
rooms[i] = new Room(i + 1);
}
}
}
public class Room {
private int roomNumber;
public Room(int roomNumber) {
this.roomNumber = roomNumber;
}
// Room ไม่สามารถอยู่ได้โดยไม่มี House
}
หมายเหตุ: ถ้าลบ House, Room จะถูกลบด้วย
4. Inheritance (สืบทอด)
ความหมาย: Class B สืบทอดจาก Class A (IS-A relationship)
สัญลักษณ์: เส้น + ลูกศรสามเหลี่ยมขาว ◁────
ตัวอย่าง: Dog สืบทอด Animal
text ┌────────┐
│ Animal │
└────────┘
△
│
│
┌────────┐
│ Dog │
└────────┘
Code:
javapublic class Animal {
protected String name;
public void eat() {
System.out.println("Eating...");
}
}
public class Dog extends Animal {
public void bark() {
System.out.println("Woof!");
}
}
5. Realization/Implementation (ทำตาม Interface)
ความหมาย: Class B ทำตาม Interface A
สัญลักษณ์: เส้นประ + ลูกศรสามเหลี่ยมขาว ◁┄┄┄
ตัวอย่าง: Dog ทำตาม Runnable
text ┌──────────────┐
│ <<interface>>│
│ Runnable │
└──────────────┘
△
┆┆┆
│
┌────────┐
│ Dog │
└────────┘
Code:
javapublic interface Runnable {
void run();
}
public class Dog implements Runnable {
@Override
public void run() {
System.out.println("Dog is running");
}
}
6. Dependency (พึ่งพา)
ความหมาย: Class A ใช้ Class B แต่ไม่ได้เก็บเป็น attribute
สัญลักษณ์: เส้นประ + ลูกศร ←┄┄┄
ตัวอย่าง: Calculator ใช้ Math
text┌────────────┐ ┌──────┐
│ Calculator │┄┄┄┄┄┄>│ Math │
└────────────┘ uses └──────┘
Code:
javapublic class Calculator {
public double calculateArea(double radius) {
// ใช้ Math แต่ไม่ได้เก็บเป็น attribute
return Math.PI * radius * radius;
}
}
ตัวอย่างที่ 1: ระบบจัดการนักศึกษา
Code
java// Class 1: Person (Base class)
public class Person {
protected String id;
protected String name;
protected int age;
public Person(String id, String name, int age) {
this.id = id;
this.name = name;
this.age = age;
}
public void displayInfo() {
System.out.println("ID: " + id + ", Name: " + name);
}
}
// Class 2: Student (Inherits Person)
public class Student extends Person {
private double gpa;
private Course[] enrolledCourses;
public Student(String id, String name, int age, double gpa) {
super(id, name, age);
this.gpa = gpa;
this.enrolledCourses = new Course[10];
}
public void enrollCourse(Course course) {
// เพิ่ม course
}
}
// Class 3: Course
public class Course {
private String courseCode;
private String courseName;
private Teacher teacher; // Aggregation
public Course(String code, String name) {
this.courseCode = code;
this.courseName = name;
}
public void assignTeacher(Teacher teacher) {
this.teacher = teacher;
}
}
// Class 4: Teacher (Inherits Person)
public class Teacher extends Person {
private String department;
public Teacher(String id, String name, int age, String dept) {
super(id, name, age);
this.department = dept;
}
}
Class Diagram
text ┌─────────────────┐
│ Person │
├─────────────────┤
│ # id: String │
│ # name: String │
│ # age: int │
├─────────────────┤
│ + Person(...) │
│ + displayInfo() │
└─────────────────┘
△
│
┌───────────┴───────────┐
│ │
┌───────────────┐ ┌──────────────┐
│ Student │ │ Teacher │
├───────────────┤ ├──────────────┤
│ - gpa: double │ │ - department │
├───────────────┤ ├──────────────┤
│ + Student(...)│ │ + Teacher(...)│
│ + enrollCourse│ └──────────────┘
└───────────────┘ │
│ │
│ enrolls teaches
│ │
↓ ↓
┌────────────────────────────────────┐
│ Course │
├────────────────────────────────────┤
│ - courseCode: String │
│ - courseName: String │
├────────────────────────────────────┤
│ + Course(code, name) │
│ + assignTeacher(teacher): void │
└────────────────────────────────────┘
ความสัมพันธ์:
- Person ← Student (Inheritance)
- Person ← Teacher (Inheritance)
- Student → Course (Association)
- Course ◇→ Teacher (Aggregation)
Multiplicity: จำนวนความสัมพันธ์
Multiplicity บอกจำนวนของ objects ที่เกี่ยวข้อง
| สัญลักษณ์ | ความหมาย |
|---|---|
1 | หนึ่งเดียว |
0..1 | ศูนย์ หรือ หนึ่ง |
* หรือ 0..* | ศูนย์ หรือ มากกว่า |
1..* | หนึ่ง หรือ มากกว่า |
n | n เท่านั้น |
n..m | n ถึง m |
ตัวอย่าง: Multiplicity
text┌──────────┐ 1 * ┌──────────┐
│ Teacher │────────────│ Student │
└──────────┘ teaches └──────────┘
ความหมาย:
- 1 Teacher สอนได้หลาย Students (*)
- หลาย Students (*) เรียนกับ 1 Teacher
text┌──────────┐ 1 1..* ┌──────────┐
│ Company │───────────────│ Employee │
└──────────┘ employs └──────────┘
ความหมาย:
- 1 Company มีอย่างน้อย 1 Employee (1..*)
- หลาย Employees (1..*) ทำงานกับ 1 Company
text┌──────────┐ * * ┌──────────┐
│ Student │────────────│ Course │
└──────────┘ enrolls └──────────┘
ความหมาย:
- หลาย Students () ลงทะเบียนหลาย Courses ()
- หลาย Courses () มีหลาย Students ()
ตัวอย่างที่ 2: ระบบห้องสมุด (Library System)
Requirements
textระบบห้องสมุด:
- มี Books หลายเล่ม
- มี Members หลายคน
- Member ยืม Books ได้
- มีการบันทึก BorrowRecords
Code
java// Class 1: Book
public class Book {
private String isbn;
private String title;
private String author;
private int quantity;
private int availableCopies;
public Book(String isbn, String title, String author, int quantity) {
this.isbn = isbn;
this.title = title;
this.author = author;
this.quantity = quantity;
this.availableCopies = quantity;
}
public boolean isAvailable() {
return availableCopies > 0;
}
public void borrowBook() {
if (availableCopies > 0) {
availableCopies--;
}
}
public void returnBook() {
if (availableCopies < quantity) {
availableCopies++;
}
}
}
// Class 2: Member
public class Member {
private String memberID;
private String name;
private String email;
private ArrayList<BorrowRecord> borrowHistory;
public Member(String memberID, String name, String email) {
this.memberID = memberID;
this.name = name;
this.email = email;
this.borrowHistory = new ArrayList<>();
}
public BorrowRecord borrowBook(Book book) {
if (book.isAvailable()) {
book.borrowBook();
BorrowRecord record = new BorrowRecord(this, book);
borrowHistory.add(record);
return record;
}
return null;
}
}
// Class 3: BorrowRecord
public class BorrowRecord {
private String recordID;
private Member member;
private Book book;
private LocalDate borrowDate;
private LocalDate returnDate;
public BorrowRecord(Member member, Book book) {
this.recordID = generateID();
this.member = member;
this.book = book;
this.borrowDate = LocalDate.now();
this.returnDate = null;
}
public void returnBook() {
this.returnDate = LocalDate.now();
book.returnBook();
}
private String generateID() {
return "R" + System.currentTimeMillis();
}
}
// Class 4: Library (Main system)
public class Library {
private String libraryName;
private ArrayList<Book> books;
private ArrayList<Member> members;
public Library(String name) {
this.libraryName = name;
this.books = new ArrayList<>();
this.members = new ArrayList<>();
}
public void addBook(Book book) {
books.add(book);
}
public void registerMember(Member member) {
members.add(member);
}
}
Class Diagram
text┌──────────────────────────────┐
│ Library │
├──────────────────────────────┤
│ - libraryName: String │
├──────────────────────────────┤
│ + Library(name) │
│ + addBook(book): void │
│ + registerMember(m): void │
└──────────────────────────────┘
│ │
│ 1 1 │
│ │
│ * * │
↓ ↓
┌───────────┐ * * ┌────────────────┐
│ Book │──────────│ Member │
├───────────┤ borrows ├────────────────┤
│ - isbn │ │ - memberID │
│ - title │ │ - name │
│ - author │ │ - email │
│ - quantity│ ├────────────────┤
├───────────┤ │ + borrowBook() │
│ + borrow()│ └────────────────┘
│ + return()│ │
└───────────┘ │ 1
△ │
│ │ *
│ 1 ↓
│ ┌──────────────────┐
└──────────────│ BorrowRecord │
records ├──────────────────┤
│ - recordID │
│ - borrowDate │
│ - returnDate │
├──────────────────┤
│ + returnBook() │
└──────────────────┘
ความสัมพันธ์:
- Library ◆→ Book (Composition – 1 to *)
- Library ◆→ Member (Composition – 1 to *)
- Member → Book (Association – * to *)
- Member ◆→ BorrowRecord (Composition – 1 to *)
- BorrowRecord → Book (Association – * to 1)
Abstract Class และ Interface ใน UML
Abstract Class
สัญลักษณ์: ชื่อเป็น italic หรือ {abstract}
text┌──────────────────┐
│ <<abstract>> │
│ Animal │
├──────────────────┤
│ # name: String │
├──────────────────┤
│ + eat(): void │
│ + sleep(): void │
│ + move(): void {abstract} │
└──────────────────┘
△
│
┌───┴───┐
│ │
┌───────┐ ┌───────┐
│ Dog │ │ Cat │
└───────┘ └───────┘
Code:
javapublic abstract class Animal {
protected String name;
public void eat() {
System.out.println("Eating...");
}
public void sleep() {
System.out.println("Sleeping...");
}
public abstract void move(); // Abstract method
}
public class Dog extends Animal {
@Override
public void move() {
System.out.println("Running");
}
}
public class Cat extends Animal {
@Override
public void move() {
System.out.println("Walking");
}
}
Interface
สัญลักษณ์: <<interface>> หรือ <<I>>
text┌──────────────────┐
│ <<interface>> │
│ Drawable │
├──────────────────┤
│ + draw(): void │
└──────────────────┘
△
┆┆┆
│
┌───┴───┐
│ │
┌────────┐ ┌────────┐
│ Circle │ │ Square │
└────────┘ └────────┘
Code:
javapublic interface Drawable {
void draw();
}
public class Circle implements Drawable {
@Override
public void draw() {
System.out.println("Drawing circle");
}
}
public class Square implements Drawable {
@Override
public void draw() {
System.out.println("Drawing square");
}
}
สรุปตอนที่ 1
เราได้เรียนรู้:
✅ UML คืออะไร – ภาษากลางสำหรับวาดภาพซอฟต์แวร์
✅ 14 Diagrams – แบ่งเป็น Structure และ Behavior
✅ Class Diagram พื้นฐาน – Class box 3 ส่วน
✅ Access Modifiers – +, -, #, ~
✅ 6 Relationships – Association, Aggregation, Composition, Inheritance, Realization, Dependency
✅ Multiplicity – 1, 0..1, , 1.. เป็นต้น
✅ Abstract และ Interface – ใน UML
ตัวอย่างท้ายตอน: E-Commerce System (Partial)
text┌──────────────┐ 1 * ┌──────────────┐
│ Customer │───────────│ Order │
├──────────────┤ places ├──────────────┤
│ - customerID │ │ - orderID │
│ - name │ │ - orderDate │
│ - email │ │ - status │
├──────────────┤ ├──────────────┤
│ + register() │ │ + addItem() │
│ + login() │ │ + checkout() │
└──────────────┘ └──────────────┘
│
│ 1
│
│ *
↓
┌──────────────┐
│ OrderItem │
├──────────────┤
│ - quantity │
│ - price │
├──────────────┤
│ + getTotal() │
└──────────────┘
│
│ *
│
│ 1
↓
┌──────────────┐
│ Product │
├──────────────┤
│ - productID │
│ - name │
│ - price │
├──────────────┤
│ + getInfo() │
└──────────────┘
🎯 ในตอนต่อไป เราจะเรียนรู้:
- Behavior Diagrams แบบละเอียด
- Use Case Diagram
- Sequence Diagram
- Activity Diagram
- ตัวอย่างระบบใหญ่ที่สมบูรณ์
