အခန်း ၉ :: Software Quality Principles and Attributes

Code ရေး၍ ပြီးသွားသောအခါ "ငါ့ Code က Run လို့ရပြီ၊ Error မတက်ဘူး" ဟု ကျေနပ်နေ၍ မရပါ။ Professional Software Engineer တစ်ယောက်အနေဖြင့် "အလုပ်ဖြစ်ရုံ" (Working Software) နှင့် "အရည်အသွေး ကောင်းမွန်ခြင်း" (High Quality Software) သည် ကွာခြားကြောင်း နားလည်ထားရပါမည်။
ဤအခန်းသည် Software Engineering ၏ အနှစ်သာရ ဖြစ်သော Quality (အရည်အသွေး) ကို အသေးစိတ် လေ့လာမည့် အခန်းဖြစ်သည်။ Quality ဆိုသည်မှာ Bug ကင်းစင်ရုံ သက်သက် မဟုတ်ပါ။ Software တစ်ခုသည် သုံးစွဲရ မြန်ဆန်ခြင်း (Performance)၊ လုံခြုံစိတ်ချရခြင်း (Security)၊ နှင့် နောင်တစ်ချိန် ပြုပြင်ပြောင်းလဲရန် လွယ်ကူခြင်း (Maintainability) စသည့် ဂုဏ်သတ္တိများနှင့် ပြည့်စုံမှသာ အရည်အသွေး ပြည့်မီသည်ဟု ဆိုနိုင်ပါသည်။
၉.၁ Software Quality ဆိုတာ ဘာလဲ?
Software Quality ကို အဓိပ္ပာယ် ဖွင့်ဆိုရာတွင် ရှုထောင့် နှစ်ခု ရှိပါသည်။
- Functional Quality: Software သည် အလုပ်လုပ်သလား။ (Requirement တွင် ပါသည့်အတိုင်း လုပ်ဆောင်ချက်များ မှန်ကန်မှု ရှိမရှိ)။
- Structural Quality (Non-Functional): Code ၏ ဖွဲ့စည်းပုံ ကောင်းမွန်သလား။ (လုံခြုံမှု၊ မြန်ဆန်မှု၊ ပြုပြင်လွယ်ကူမှု ရှိမရှိ)။
Functional Quality ကို User က မြင်ရသော်လည်း၊ Structural Quality ကို User က မမြင်ရပါ။ သို့သော် ရေရှည်တွင် Structural Quality ညံ့ဖျင်းသော Software သည် ပြုပြင်ရ ခက်ခဲလာပြီး၊ နောက်ဆုံးတွင် ပျက်စီးသွားလေ့ ရှိပါသည်။
McCall’s Quality Model (1977)
Software Quality ကို တိုင်းတာရန်အတွက် ၁၉၇၇ ခုနှစ်တွင် Jim McCall က ရှုထောင့် (၃) ခု ပါဝင်သော Model တစ်ခုကို မိတ်ဆက်ခဲ့ပါသည်။ ခေတ်ဟောင်းဟု ဆိုနိုင်သော်လည်း ယနေ့ထက်ထိ အသုံးဝင်နေဆဲ အခြေခံ သဘောတရားများ ဖြစ်ပါသည်။
McCall က Software တစ်ခု၏ သက်တမ်း (Lifecycle) ကို ကြည့်ပြီး မေးခွန်း ၃ ခု မေးခဲ့ပါတယ် -
- Product Operation: အခု သုံးနေတဲ့အချိန်မှာ ကောင်းမွန်ရဲ့လား။
- Product Revision: ပြုပြင် ပြောင်းလဲတဲ့အခါ လွယ်ကူရဲ့လား။
- Product Transition: ပတ်ဝန်းကျင် အသစ်၊ စက်အသစ်ဆီ ပြောင်းတဲ့အခါ အဆင်ပြေရဲ့လား။
mindmap
root((McCall's Model))
Product Operation<br/>(အသုံးပြုနေစဉ်)
Correctness<br/>(မှန်ကန်မှု)
Reliability<br/>(စိတ်ချရမှု)
Efficiency<br/>(စွမ်းဆောင်ရည်)
Integrity<br/>(လုံခြုံမှု)
Usability<br/>(သုံးရလွယ်ကူမှု)
Product Revision<br/>(ပြုပြင်ပြောင်းလဲစဉ်)
Maintainability<br/>(ထိန်းသိမ်းလွယ်မှု)
Flexibility<br/>(ပြောင်းလွယ်ပြင်လွယ်မှု)
Testability<br/>(စစ်ဆေးရလွယ်ကူမှု)
Product Transition<br/>(ပြောင်းရွှေ့စဉ်)
Portability<br/>(ရွှေ့ပြောင်းလွယ်မှု)
Reusability<br/>(ပြန်သုံးနိုင်မှု)
Interoperability<br/>(ချိတ်ဆက်နိုင်မှု)
၉.၂ ISO/IEC 25010 Quality Model
McCall Model သည် ကောင်းမွန်သော်လည်း၊ ယနေ့ခေတ် Modern Software Engineering အတွက် နိုင်ငံတကာ စံနှုန်းဖြစ်သော ISO/IEC 25010 ကို အဓိက အသုံးပြုကြပါသည်။ ဤစံနှုန်းတွင် Software Quality ကို အဓိက ခေါင်းစဉ်ကြီး (၈) ခု ဖြင့် ခွဲခြား သတ်မှတ်ထားပါသည်။
graph TD
Main[<b>Software Product Quality</b><br/>ISO/IEC 25010] --> F1[Functional Suitability]
Main --> F2[Performance Efficiency]
Main --> F3[Compatibility]
Main --> F4[Usability]
Main --> F5[Reliability]
Main --> F6[Security]
Main --> F7[Maintainability]
Main --> F8[Portability]
style Main fill:#2962FF,stroke:#fff,color:#fff
style F7 fill:#FF6D00,stroke:#333,stroke-width:2px
(Diagram တွင် Developer များအတွက် အရေးကြီးဆုံးဖြစ်သည့် Maintainability ကို Highlight လုပ်ထားပါသည်)
၁။ Functional Suitability (လုပ်ဆောင်ချက် ပြည့်စုံမှန်ကန်မှု)
System သည် လိုအပ်ချက်များကို မည်မျှ ပြည့်စုံစွာ ဖြည့်ဆည်းပေးနိုင်သလဲ။
- Functional Completeness: Feature တွေ အကုန်ပါရဲ့လား။
- Functional Correctness: တွက်ချက်မှုတွေ မှန်ကန်ရဲ့လား။
- Functional Appropriateness: ပါဝင်တဲ့ Feature တွေက User အတွက် တကယ် အသုံးဝင်ရဲ့လား။
၂။ Performance Efficiency (စွမ်းဆောင်ရည်)
Resource (CPU, RAM) ကို ဘယ်လောက် သုံးသလဲ။
- Time Behavior: Response Time မြန်ရဲ့လား။
- Resource Utilization: Memory စားတာ များလွန်းနေသလား။
၃။ Compatibility (လိုက်လျော်ညီထွေ ဖြစ်မှု)
- Co-existence: တခြား Software တွေနဲ့ စက်တစ်ခုတည်းမှာ ပြဿနာ မရှိဘဲ တွဲrun လို့ ရလား။
- Interoperability: API တွေကနေတဆင့် Data အပြန်အလှန် ပို့လို့ ရလား။
၄။ Usability (သုံးစွဲရ လွယ်ကူမှု)
- Learnability: User အသစ်တစ်ယောက်က ဒီ Software ကို သုံးတတ်ဖို့ ဘယ်လောက် မြန်မြန် သင်ယူနိုင်လဲ။
- User Error Protection: User က မှားနှိပ်မိရင် System က ကာကွယ်ပေးလား (ဥပမာ - Delete မလုပ်ခင် Confirm မေးတာမျိုး)။
၅။ Reliability (ယုံကြည်စိတ်ချရမှု)
- Maturity: ပုံမှန် အသုံးပြုနေစဉ်မှာ Bug ဘယ်လောက် ကင်းစင်လဲ။
- Availability: System Up-time (ဥပမာ - 99.9%) ရှိလား။
- Recoverability: System Crash ဖြစ်သွားရင် Data တွေ ပြန်ရနိုင်လား။
၆။ Security (လုံခြုံရေး)
- Confidentiality: ခွင့်ပြုချက် ရှိသူသာ Data ကို ကြည့်လို့ရလား။
- Integrity: Data တွေကို ခွင့်ပြုချက်မရှိဘဲ ပြင်ဆင်ခြင်းမှ ကာကွယ်ထားလား။
၇။ Maintainability (ပြုပြင်ထိန်းသိမ်း လွယ်ကူမှု) - Developers' Focus
Software Engineer တစ်ယောက်အတွက် အရေးကြီးဆုံး အချက်ပါ။
- Modularity: အစိတ်အပိုင်းလေးတွေ ခွဲထားလား။
- Reusability: ရေးပြီးသား Code ကို တခြားနေရာမှာ ပြန်သုံးလို့ ရလား။
- Analyzability: Error တက်ရင် ဘယ်နားမှာ ဖြစ်တာလဲ ရှာရ လွယ်လား (Log တွေ၊ Trace တွေ ကောင်းလား)။
- Modifiability: Code ပြင်လိုက်ရင် တခြားနေရာတွေပါ လိုက်ပျက်မသွားအောင် ရေးထားလား။
၈။ Portability (ရွှေ့ပြောင်းသယ်ယူ လွယ်ကူမှု)
- Adaptability: Screen Size မျိုးစုံ၊ OS မျိုးစုံမှာ အလုပ်လုပ်လား။
- Installability: Install လုပ်ရတာ လွယ်ကူရဲ့လား။
၉.၃ Software Metrics (တိုင်းတာခြင်း)
"You can't control what you can't measure."
Software Quality ကောင်းမွန်ဖို့အတွက် မြင်တာ နဲ့ ဆုံးဖြတ်လို့ မရပါဘူး။ ကိန်းဂဏန်း တွေနဲ့ တိုင်းတာရပါမယ်။ Metrics ၃ မျိုး ရှိပါတယ်။
၁။ Process Metrics (လုပ်ငန်းစဉ်ကို တိုင်းတာခြင်း)
Software ထုတ်လုပ်တဲ့ "နည်းလမ်း" ကောင်းမကောင်း တိုင်းတာတာပါ။
- Defect Removal Efficiency (DRE): Bug တွေကို Production မရောက်ခင် QA အဆင့်မှာ ဘယ်လောက် ဖယ်ရှားနိုင်ခဲ့လဲ။
- Lead Time: User က Requirement တောင်းလိုက်တဲ့ အချိန်ကနေ User လက်ထဲ ရောက်တဲ့အထိ ဘယ်လောက် ကြာလဲ။
၂။ Project Metrics (စီမံကိန်းကို တိုင်းတာခြင်း)
လက်ရှိ Project အခြေအနေကို တိုင်းတာတာပါ။ Project Manager တွေ အဓိက ကြည့်ပါတယ်။
- Burn-down Chart: Sprint တစ်ခုမှာ လုပ်စရာကျန်တဲ့ အလုပ်တွေ ဘယ်လောက် လျော့သွားပြီလဲ။
- Schedule Variance: သတ်မှတ်ထားတဲ့ Timeline ထက် ဘယ်လောက် နောက်ကျ/စော နေသလဲ။
၃။ Product Metrics (ထုတ်ကုန်ကို တိုင်းတာခြင်း)
Software Code ကိုယ်တိုင်ရဲ့ အရည်အသွေးကို တိုင်းတာတာပါ။
- Lines of Code (LOC): Code စာကြောင်းရေ (နည်းလေ ကောင်းလေ လို့ ဆိုနိုင်တယ် ဆိုတာထက် complex ဖြင့်မှု နည်းတယ် လို့ မြင်တာ ပိုအဆင်ပြေပါတယ်။ Code Line များလေလေ လက်ရှိ စနစ်က complex ဖြစ်လေလေ ဆိုတာ သိမြင်နိုင်ပါတယ်)။
- Code Coverage: Unit Test တွေက Code ရဲ့ ဘယ်လောက် ရာခိုင်နှုန်းကို စစ်ဆေးပေးထားလဲ။
၉.၄ Code Quality Metrics (Internal Quality)
Software Engineer တစ်ယောက်အနေနဲ့ အရေးကြီးဆုံးကတော့ Product Metrics ထဲက Internal Code Quality ပါပဲ။ Code ကောင်းမကောင်းကို အောက်ပါ Metric တွေနဲ့ အဓိက တိုင်းတာပါတယ်။
၉.၄.၁ Cyclomatic Complexity (ရှုပ်ထွေးမှု ညွှန်းကိန်း)
Function တစ်ခုအတွင်းမှာ ရှိတဲ့ လမ်းကြောင်း (Paths) အရေအတွက်ကို တိုင်းတာတာပါ။ if, else, while, for, switch တွေ များလေလေ၊ ဆုံးဖြတ်ချက်ချရမယ့် လမ်းကြောင်းတွေ များလေလေ၊ Complexity တက်လေလေ ပါပဲ။
- 1-10: ကောင်းမွန်သည်။ (Test လုပ်ရ လွယ်ကူသည်)
- 10-20: အသင့်အတင့် ရှုပ်ထွေးသည်။ (Test လုပ်ရ ခက်လာသည်)
- 20-50: အလွန် ရှုပ်ထွေးသည်။ (Bug ပါနိုင်ခြေ များသည်)
- >50: ပြန်ရေးသင့်သည်။ (Unmaintainable)
၉.၄.၂ Coupling
Low Coupling is Good
Module တစ်ခုနဲ့ တစ်ခု ဘယ်လောက်တောင် မှီခို ချိတ်ဆက် မှု ရှိနေလဲ။
- High Coupling (မကောင်း): Module A ကို ပြင်လိုက်ရင် Module B, C, D ပါ လိုက်ပြင်နေရတာမျိုးပါ။ USB ကြိုးတွေ ရှုပ်နေသလိုမျိုး တခုဆွဲလိုက်ရင် အကုန်ပါလာမယ့် အနေအထားပါ။
- Low Coupling (ကောင်း): Module တွေက လွတ်လပ်တယ်။ Socket ခေါင်းလိုပဲ ဖြုတ်တပ်ရ လွယ်တယ်။ A ကို ပြင်လည်း B ကို မထိခိုက်ဘူး။
၉.၄.၃ Cohesion
High Cohesion is Good
Module တစ်ခု (သို့မဟုတ် Class တစ်ခု) ဟာ သူ့တာဝန် သူ ဘယ်လောက် focus လုပ်ထားလဲ။
Low Cohesion (မကောင်း): Class တစ်ခုထဲမှာ User အကြောင်းလည်း ပါ၊ ငွေစာရင်း တွက်တာလည်း ပါ၊ Email ပို့တာလည်း ပါ နေတာမျိုးပါ။ ဒီလို အလုံးစုံ ပါနေတာမျိုးကို "God Object" လို့ ခေါ်ပါတယ်။ ပြင်ရ ခက်ပါတယ်။
High Cohesion (ကောင်း): Class တစ်ခုက တာဝန်တစ်ခုတည်းကိုပဲ ပြတ်ပြတ်သားသား လုပ်တာပါ။
UserServiceက User ကိစ္စပဲ လုပ်တယ်။EmailServiceက Email ကိစ္စပဲ လုပ်တယ်။
graph LR
subgraph "Ideal Architecture"
A[<b>High Cohesion</b><br/>One Focus] --- B[<b>Low Coupling</b><br/>Independent]
end
subgraph "Spaghetti Code"
C[<b>Low Cohesion</b><br/>Mixed Responsibilities] --- D[<b>High Coupling</b><br/>Interdependent]
end
style A fill:#ccffcc,stroke:#333
style B fill:#ccffcc,stroke:#333
style C fill:#ffcccc,stroke:#333
style D fill:#ffcccc,stroke:#333
၉.၅ Technical Debt
Project တစ်ခု အမြန်ပြီးချင်လို့ မြန်မြန် ရေးလိုက်တယ်။ Code ကို သေချာ Design မဆွဲဘဲ ပြီးအောင် အဓိက ထားရေးတယ် ဆိုပါစို့။ အလုပ်တော့ ပြီးသွားပါမယ်။ ဒါပေမဲ့ အဲဒီလို လုပ်လိုက်တာဟာ "အကြွေးယူလိုက်တာ" နဲ့ တူပါတယ်။
Ward Cunningham က Technical Debt ဆိုတဲ့ ဥပမာကို မိတ်ဆက်ပေးခဲ့ပါတယ်။ ငွေရေးကြေးရေး အကြွေးလိုပါပဲ။
- Principal (အရင်း): ညံ့ဖျင်းစွာ ရေးထားတဲ့ Code တွေကို ပြန်ပြင်ရမယ့် အလုပ်။
- Interest (အတိုး): အဲဒီ Code ညံ့တွေကြောင့် Feature အသစ်ထည့်တိုင်း ကြာလာတဲ့ အချိန်၊ ပေါ်လာတဲ့ Bug တွေ။
အကြွေး (Technical Debt) ကို မဆပ်ဘဲထားရင်၊ အတိုး (Interest) တွေများလာပြီး နောက်ဆုံးမှာ Project တစ်ခုလုံး ဘာမှ ဆက်လုပ်လို့ မရတော့တဲ့ (Technical Bankruptcy) အခြေအနေ ရောက်သွားနိုင်ပါတယ်။
တချို့ technical debt တွေက ထိတောင် မထိရဲဘူး ဖြစ်လောက်အောင်ပါပဲ။ အလုပ်လုပ်နေသေးသ၍ မပြင်ဘဲထားတာ က နေ ပိုပြီး ကြီးမားသည့် ပြဿနာ တွေ နောက်ပိုင်း ဖြစ်လာတတ်ပါတယ်။ ကျွန်တော်တို့ developer တွေက Technical Debt ကို ဟာသ တစ်ခု အနေနဲ့ ပြောနေကြ စကား တစ်ခု ရှိတယ်။
အစက ဘုရား နဲ့ ငါ နဲ့ ပဲ code ဘယ်လို အလုပ်လုပ်လဲ ဆိုတာ သိတယ်။ အခုတော့ ဘုရား ပဲ သိတော့တယ်။
ဒါဟာ ဟာသ ဆိုပေမယ့် ကြောက်ဖို့ ကောင်းပါတယ်။ ဥပမာ Developer က အလုပ်ထွက်သွားရင် ဒါမှမဟုတ် မတော်တဆ တစ်ခုခု ဖြစ်ပြီး အလုပ်မလုပ်နိုင်တော့ရင် ပြဿနာ ဖြစ်ပါပြီ။ Company leader တိုင်း သဘောပေါက်ထားတာကတော့ ဘယ်သူမှ company မှာ အမြဲ ရှိနေမှာ မဟုတ်ဘူး။ အချိန်တစ်ခု ရောက်ရင် ပြောင်းကြမှာပဲ ဆိုပြီး mindset ရှိပါတယ်။ ဒါကြောင့် Technical Debt ကို Developer တွေ ထက် leader တွေက ပိုကြောက်ကြပါတယ်။ သူ မရှိလို့ မဖြစ်ဘူး ဆိုတာကို တတ်နိုင်သလောက် ရှောင်ကြဉ် ကြပါတယ်။
ဒါကြောင့် Team တစ်ခုမှာ Feature အသစ်တွေ ထွက်တာ အရမ်းနှေးလာပြီ၊ Bug တွေ ခဏခဏ တက်လာပြီဆိုရင် ဒါဟာ Technical Debt တွေများပြီး အတိုး (Interest) ပေးနေရပြီဆိုတာ သတိပြုမိရမည့် အချိန်ပါပဲ။ ဒီလိုအချိန်မှာ Refactoring လုပ်ပြီး အကြွေးဆပ်ဖို့ လိုအပ်ပါတယ်။
Identification (ဘယ်လို သိနိုင်မလဲ)
Technical Debt ရှိနေပြီဆိုတာကို အောက်ပါ Code Smells တွေကနေ သိနိုင်ပါတယ်။
- Duplicated Code: Copy-Paste လုပ်ထားသော Code များ။
- Long Methods / God Classes: စာကြောင်းရေ ရာချီ ရှည်လျားသော Function များ။
- Rigidity: အသေးအဖွဲလေး ပြင်ချင်တာတောင် System တစ်ခုလုံးကို သွားထိခိုက်နိုင်လို့ မပြင်ရဲ ဖြစ်နေခြင်း။
- Fragility: နေရာတစ်ခု ပြင်လိုက်တိုင်း တခြား မဆိုင်တဲ့ နေရာမှာ Error တက်ခြင်း။
Management (ဘယ်လို စီမံမလဲ)
Technical Debt ကို လုံးဝ မရှိအောင် လုပ်ဖို့ မဖြစ်နိုင်ပါဘူး (Business အရ အမြန်သွားရတဲ့ အချိန်တွေ ရှိလို့ပါ)။ အဓိက က စနစ်တကျ စီမံဖို့ပါပဲ။
Make it Visible: Issue Tracker (Jira) ထဲမှာ "Refactor User Module" ဆိုပြီး Task အနေနဲ့ မှတ်ထားပါ။ Debt ကို ဖုံးမထားပါနဲ့။
The Boy Scout Rule: "ကိုယ်ရောက်လာတုန်းကထက် ပိုသန့်ရှင်းအောင် ထားခဲ့ပါ"။ File တစ်ခုကို ပြင်ဖို့ ဖွင့်လိုက်ရင်၊ အဲဒီ File ထဲက Variable နာမည်လောက်ပဲ ဖြစ်ဖြစ် နည်းနည်း ပြင်ခဲ့ပါ။
Refactoring Sprints: Sprint အနည်းငယ် ကြာတိုင်းမှာ Feature အသစ် မထည့်ဘဲ Code ရှင်းဖို့၊ Library Update လုပ်ဖို့ သီးသန့် Sprint (Clean-up Sprint) ထားပေးပါ။ Refactoring လုပ်တဲ့အခါ Code တွေ ပျက်မသွားဘူးဆိုတာ သေချာဖို့ Automated Tests (Unit Tests) တွေ ရှိထားဖို့ လိုပါတယ်။ Test မရှိဘဲ Refactor လုပ်တာက မျက်စိမှိတ် လမ်းလျှောက်တာနဲ့ တူပါတယ်။
Payment Plan: Feature အသစ် လုပ်တဲ့အချိန်ရဲ့ ၁၀% - ၂၀% ကို Refactoring လုပ်ဖို့ အချိန်ပေးပါ။