Agile Development คือ
Agile Development แนวทางพัฒนาซอฟต์แวร์ Iterative Sprint ส่งมอบงานรอบสั้น ตอบสนองเปลี่ยนแปลงเร็ว ลูกค้ามีส่วนร่วม ทีมจัดการตัวเอง Scrum Kanban
| Agile Framework | Sprint | Roles | เหมาะกับ |
|---|---|---|---|
| Scrum | 1-4 สัปดาห์ | PO, SM, Dev Team | Product Development |
| Kanban | ไม่มี (Continuous) | ไม่กำหนดตายตัว | Support, Maintenance |
| XP | 1-2 สัปดาห์ | Coach, Customer, Dev | High Quality Code |
| SAFe | PI 8-12 สัปดาห์ | RTE, PO, SM, Teams | Enterprise Scale |
| Lean | Continuous | Flexible | Startup, Innovation |
Agile Manifesto
# agile.py — Agile Manifesto & Principles
manifesto = {
"Individuals and interactions": "over processes and tools",
"Working software": "over comprehensive documentation",
"Customer collaboration": "over contract negotiation",
"Responding to change": "over following a plan",
}
print("=== Agile Manifesto ===\n")
for left, right in manifesto.items():
print(f" {left}")
print(f" {right}\n")
principles = [
"ส่งมอบซอฟต์แวร์ที่ใช้ได้จริงเป็นประจำ สัปดาห์ถึงเดือน",
"ต้อนรับ Requirements ที่เปลี่ยนแปลง แม้จะช่วงท้ายโปรเจค",
"ส่งมอบ Working Software บ่อยๆ ยิ่งถี่ยิ่งดี",
"Business กับ Developer ทำงานร่วมกันทุกวัน",
"สร้างโปรเจคจากู้คืนที่มีแรงจูงใจ ให้สิ่งแวดล้อมและการสนับสนุน",
"สื่อสารแบบเจอหน้ามีประสิทธิภาพที่สุด",
"Working Software เป็นตัววัดความก้าวหน้าหลัก",
"Sustainable Development ทำงานสม่ำเสมอไม่ Burnout",
"ใส่ใจ Technical Excellence และ Good Design",
"ความเรียบง่าย ลดงานที่ไม่จำเป็น",
"ทีมจัดการตัวเอง Self-organizing Teams",
"ทบทวนและปรับปรุงอย่างสม่ำเสมอ Retrospective",
]
print("=== 12 Agile Principles ===\n")
for i, p in enumerate(principles, 1):
print(f" {i:>2}. {p}")
# Agile vs Waterfall
comparison = {
"Planning": {"Agile": "แผนปรับเปลี่ยนได้ Sprint ละ", "Waterfall": "วางแผนทั้งหมดก่อนเริ่ม"},
"Delivery": {"Agile": "ส่งมอบทุก Sprint", "Waterfall": "ส่งมอบตอนจบโปรเจค"},
"Changes": {"Agile": "ยินดีรับเปลี่ยนแปลง", "Waterfall": "เปลี่ยนยาก Cost สูง"},
"Testing": {"Agile": "ทดสอบทุก Sprint", "Waterfall": "ทดสอบตอนท้าย"},
"Customer": {"Agile": "มีส่วนร่วมตลอด", "Waterfall": "มีส่วนร่วมต้นและท้าย"},
"Risk": {"Agile": "เจอปัญหาเร็ว แก้เร็ว", "Waterfall": "เจอปัญหาตอนท้าย แก้ยาก"},
"Team": {"Agile": "Cross-functional Self-organizing", "Waterfall": "แบ่งตาม Function"},
}
print(f"\n\n=== Agile vs Waterfall ===")
for aspect, vals in comparison.items():
print(f"\n [{aspect}]")
print(f" Agile: {vals['Agile']}")
print(f" Waterfall: {vals['Waterfall']}")
Scrum Framework
# scrum.py — Scrum Sprint Management
from dataclasses import dataclass, field
from typing import List, Optional
from datetime import datetime, timedelta
from enum import Enum
class Status(Enum):
TODO = "To Do"
IN_PROGRESS = "In Progress"
IN_REVIEW = "In Review"
DONE = "Done"
@dataclass
class UserStory:
id: str
title: str
description: str
story_points: int
status: Status = Status.TODO
assignee: Optional[str] = None
@dataclass
class Sprint:
name: str
goal: str
start_date: str
duration_weeks: int
stories: List[UserStory] = field(default_factory=list)
@property
def end_date(self) -> str:
start = datetime.strptime(self.start_date, "%Y-%m-%d")
end = start + timedelta(weeks=self.duration_weeks)
return end.strftime("%Y-%m-%d")
@property
def total_points(self) -> int:
return sum(s.story_points for s in self.stories)
@property
def completed_points(self) -> int:
return sum(s.story_points for s in self.stories
if s.status == Status.DONE)
@property
def velocity(self) -> float:
total = self.total_points
if total == 0:
return 0
return (self.completed_points / total) * 100
def burndown(self) -> dict:
remaining = self.total_points
data = {"Day 0": remaining}
done = [s for s in self.stories if s.status == Status.DONE]
for i, story in enumerate(done, 1):
remaining -= story.story_points
data[f"Day {i*2}"] = remaining
return data
# สร้าง Sprint
sprint = Sprint(
name="Sprint 15",
goal="User Authentication System",
start_date="2024-01-15",
duration_weeks=2,
)
stories = [
UserStory("US-101", "Login Page UI", "สร้างหน้า Login", 5, Status.DONE, "สมชาย"),
UserStory("US-102", "JWT Authentication", "ระบบ Token", 8, Status.DONE, "สมหญิง"),
UserStory("US-103", "Password Reset", "ลืมรหัสผ่าน", 5, Status.IN_PROGRESS, "สมศักดิ์"),
UserStory("US-104", "OAuth2 Google", "Login ด้วย Google", 8, Status.TODO, None),
UserStory("US-105", "2FA Setup", "Two-Factor Auth", 13, Status.TODO, None),
]
for story in stories:
sprint.stories.append(story)
print(f"=== {sprint.name}: {sprint.goal} ===")
print(f"Period: {sprint.start_date} to {sprint.end_date}")
print(f"Total Points: {sprint.total_points}")
print(f"Completed: {sprint.completed_points}")
print(f"Velocity: {sprint.velocity:.0f}%")
print(f"\n Stories:")
for s in sprint.stories:
assignee = s.assignee or "Unassigned"
print(f" [{s.status.value:<12}] {s.id} {s.title} "
f"({s.story_points}pts) - {assignee}")
print(f"\n Burndown:")
for day, points in sprint.burndown().items():
bar = "█" * points
print(f" {day:<8}: {points:>2} pts {bar}")
# Scrum Ceremonies
ceremonies = {
"Sprint Planning": {"duration": "2-4 ชม.", "who": "ทั้งทีม", "when": "ต้น Sprint"},
"Daily Standup": {"duration": "15 นาที", "who": "Dev Team", "when": "ทุกวัน"},
"Sprint Review": {"duration": "1-2 ชม.", "who": "ทีม + Stakeholders", "when": "ปลาย Sprint"},
"Retrospective": {"duration": "1-1.5 ชม.", "who": "ทั้งทีม", "when": "ปลาย Sprint"},
"Backlog Refinement": {"duration": "1-2 ชม.", "who": "PO + Dev", "when": "กลาง Sprint"},
}
print(f"\n\n=== Scrum Ceremonies ===")
for ceremony, info in ceremonies.items():
print(f"\n [{ceremony}]")
for k, v in info.items():
print(f" {k}: {v}")
Kanban Board
# kanban.py — Kanban Board Management
from dataclasses import dataclass, field
from typing import List, Dict
@dataclass
class KanbanCard:
id: str
title: str
priority: str # high, medium, low
assignee: str = ""
@dataclass
class KanbanBoard:
columns: Dict[str, List[KanbanCard]] = field(default_factory=dict)
wip_limits: Dict[str, int] = field(default_factory=dict)
def add_column(self, name: str, wip_limit: int = 0):
self.columns[name] = []
if wip_limit > 0:
self.wip_limits[name] = wip_limit
def add_card(self, column: str, card: KanbanCard) -> bool:
if column in self.wip_limits:
if len(self.columns[column]) >= self.wip_limits[column]:
print(f" WIP Limit reached for '{column}'!")
return False
self.columns[column].append(card)
return True
def move_card(self, card_id: str, to_column: str) -> bool:
for col, cards in self.columns.items():
for card in cards:
if card.id == card_id:
if to_column in self.wip_limits:
if len(self.columns[to_column]) >= self.wip_limits[to_column]:
print(f" WIP Limit! Cannot move to '{to_column}'")
return False
cards.remove(card)
self.columns[to_column].append(card)
return True
return False
def show(self):
print("\n=== Kanban Board ===")
for col, cards in self.columns.items():
limit = self.wip_limits.get(col, "-")
print(f"\n [{col}] (WIP: {len(cards)}/{limit})")
if not cards:
print(f" (empty)")
for card in cards:
print(f" [{card.priority[0].upper()}] {card.id}: "
f"{card.title} ({card.assignee or '-'})")
board = KanbanBoard()
board.add_column("Backlog")
board.add_column("To Do", wip_limit=5)
board.add_column("In Progress", wip_limit=3)
board.add_column("Review", wip_limit=2)
board.add_column("Done")
cards = [
KanbanCard("T-201", "Fix login bug", "high", "สมชาย"),
KanbanCard("T-202", "Add dark mode", "medium", "สมหญิง"),
KanbanCard("T-203", "Update API docs", "low", "สมศักดิ์"),
KanbanCard("T-204", "Performance tuning", "high"),
KanbanCard("T-205", "Add unit tests", "medium"),
]
board.add_card("In Progress", cards[0])
board.add_card("In Progress", cards[1])
board.add_card("Review", cards[2])
board.add_card("To Do", cards[3])
board.add_card("Backlog", cards[4])
board.show()
# Kanban Metrics
metrics = {
"Lead Time": "เวลาจาก Request ถึง Delivery (วัน)",
"Cycle Time": "เวลาจาก Start Work ถึง Done (วัน)",
"Throughput": "จำนวนงานเสร็จต่อสัปดาห์",
"WIP": "จำนวนงานที่กำลังทำอยู่",
"Blocked Items": "งานที่ติดปัญหา",
}
print(f"\n\n=== Kanban Metrics ===")
for metric, desc in metrics.items():
print(f" {metric}: {desc}")
เคล็ดลับ
- Sprint สั้น: Sprint 2 สัปดาห์ ส่งมอบบ่อย Feedback เร็ว
- User Stories: เขียนจากมุมมองผู้ใช้ As a... I want... So that...
- WIP Limit: จำกัดงานที่ทำพร้อมกัน โฟกัสงานให้เสร็จ
- Retrospective: ทำทุก Sprint ปรับปรุงกระบวนการต่อเนื่อง
- Velocity: ใช้ Velocity จาก Sprint ก่อนวางแผน Sprint ถัดไป
Agile Development คืออะไร
แนวทางพัฒนาซอฟต์แวร์ Iterative Sprint ส่งมอบรอบสั้น ตอบสนองเปลี่ยนแปลง ลูกค้ามีส่วนร่วม ทีมจัดการตัวเอง
Scrum กับ Kanban ต่างกันอย่างไร
Scrum Sprint กำหนดเวลา Roles Ceremonies Kanban ไม่มี Sprint Continuous WIP Limit Board สถานะ Support Maintenance
Sprint Planning ทำอย่างไร
เลือก User Stories จาก Backlog ประเมิน Story Points Planning Poker Sprint Goal ใช้ Velocity กำหนดปริมาณงาน
Daily Standup คืออะไร
ประชุมสั้นทุกวัน 15 นาที เมื่อวานทำอะไร วันนี้ทำอะไร อุปสรรคือะไร Sync ทีม ไม่ใช่ประชุมรายงาน
สรุป
Agile Development Iterative Sprint ส่งมอบบ่อย Scrum Kanban XP SAFe Manifesto 12 Principles Sprint Planning Daily Standup Review Retrospective User Stories Story Points Velocity WIP Limit
