ในการพัฒนา Extension ด้วยภาษา AL (Application Language) บนแพลตฟอร์ม Dynamics 365 Business Central (D365BC) นักพัฒนาจำเป็นต้องให้ความสำคัญกับคุณภาพของโค้ดในระยะยาว หนึ่งในแนวทางที่ช่วยให้โค้ดมีคุณภาพสูงคือการทำ Refactor หรือการปรับปรุงโครงสร้างของโค้ดเดิมให้ดีขึ้น
⚙️ Refactoring is essential to improving code readability, maintainability, and extensibility—without changing its output.
การ Refactor ไม่ได้หมายถึงการเปลี่ยนผลลัพธ์หรือหน้าที่การทำงานของโปรแกรม แต่เป็นการปรับโครงสร้างภายในของโค้ดให้มีความชัดเจนมากขึ้น ช่วยให้โค้ดอ่านง่าย แก้ไขได้สะดวก และพร้อมรองรับการต่อยอดในอนาคต โดยเฉพาะในภาษา AL ที่มักเกี่ยวข้องกับ Business Logic ที่ซับซ้อนและเปลี่ยนแปลงอยู่เสมอ
แนวคิดนี้มีบทบาทสำคัญต่อคุณภาพซอฟต์แวร์ ไม่ว่าจะเป็นในมุมของผู้พัฒนาใหม่ที่ต้องเข้าใจโค้ด หรือการดูแลระบบในระยะยาวโดยทีมเทคนิค
รูปแบบการใช้งาน Refactor ในภาษา AL
Refactor ใน AL มีหลายเทคนิคที่สามารถนำมาใช้ได้กับ Codeunit, Page, Report หรือแม้แต่ Enum/Interface โดยเฉพาะในโครงสร้างที่ต้องพัฒนาแบบ Extension
เทคนิคยอดนิยมที่ควรรู้
| เทคนิค Refactor | แนวคิดหลัก | เหมาะกับสถานการณ์ |
|---|---|---|
| Extract Procedure | แยกโค้ดย่อยออกมาเป็นฟังก์ชันใหม่ เพื่อเพิ่มความชัดเจนและลดขนาดโค้ด | เมื่อ Procedure ยาวเกินไปหรือทำหลายหน้าที่ |
| Rename Symbol | เปลี่ยนชื่อฟังก์ชัน ตัวแปร หรือ Record ให้สื่อความหมายชัดเจน | ปรับปรุงความเข้าใจของทีมพัฒนา ลดข้อผิดพลาดจากการตีความผิด |
| Replace Magic Number | แทนค่าตัวเลข/ข้อความที่ไม่สื่อความหมาย ด้วย Constant หรือ Enum | เช่น จาก if Status = 3 → if Status = Status::Released |
| Simplify Conditionals | ลดความซับซ้อนของเงื่อนไข if-else ด้วยการใช้ exit, case, หรือย้ายเงื่อนไข | เมื่อโค้ดมีหลายระดับของเงื่อนไขซ้อนกัน |
| Move Method to Codeunit | แยก Business Logic ออกจาก UI เช่น Page หรือ Report ไปไว้ใน Codeunit | ลดภาระของ UI object และเพิ่มความสามารถในการทดสอบ |
| Split Large Method | แบ่งฟังก์ชันใหญ่ให้เป็นหลายส่วนย่อยที่ชัดเจน | ช่วยให้โค้ดอ่านง่าย และรองรับ Unit Test ได้ดีขึ้น |
ตัวอย่างการ Refactor
การ Refactor ควรเริ่มจากปัญหาที่พบในโค้ดจริง ตัวอย่างนี้มาจากฟังก์ชันที่ใช้สร้างหรืออัปเดตข้อมูลในตาราง "Item Unit of Measure" ซึ่งถูกใช้กันอย่างแพร่หลายในการจัดการหน่วยสินค้าใน Business Central
โค้ดต้นฉบับ (Before Refactor)
procedure InsertItemUnitOfMeasure(pCode: Code[20]; pItemNo: Code[20]; QtyPerUOM: Decimal)
var
ItemUOM, InsertItemUOM: Record "Item Unit of Measure";
Item: Record Item;
UnitofMeasure: Record "Unit of Measure";
begin
if pCode = '' then
Error('Unit of Measure Code cannot be empty.');
if pItemNo = '' then
Error('Item No. cannot be empty.');
ItemUOM.Reset();
ItemUOM.SetRange("Item No.", pItemNo);
ItemUOM.SetRange(Code, pCode);
if ItemUOM.FindFirst() then begin
ItemUOM.Validate("Qty. per Unit of Measure", QtyPerUOM);
ItemUOM.Modify();
end else begin
InsertItemUOM.Init();
InsertItemUOM.Validate("Code", pCode);
InsertItemUOM.Validate("Item No.", pItemNo);
InsertItemUOM.Insert(true);
InsertItemUOM.Validate("Qty. per Unit of Measure", QtyPerUOM);
InsertItemUOM.Modify();
end;
end;
โค้ดที่ผ่านการ Refactor (After Refactor)
procedure InsertItemUnitOfMeasure(pCode: Code[20]; pItemNo: Code[20]; QtyPerUOM: Decimal)
begin
ValidateInput(pCode, pItemNo);
if TryUpdateExistingUOM(pCode, pItemNo, QtyPerUOM) then
exit;
InsertNewItemUOM(pCode, pItemNo, QtyPerUOM);
end;
local procedure ValidateInput(pCode: Code[20]; pItemNo: Code[20])
var
Item: Record Item;
UOM: Record "Unit of Measure";
begin
if pCode = '' then
Error('Unit of Measure Code cannot be empty.');
if pItemNo = '' then
Error('Item No. cannot be empty.');
end;
local procedure TryUpdateExistingUOM(pCode: Code[20]; pItemNo: Code[20]; QtyPerUOM: Decimal): Boolean
var
ExistingUOM: Record "Item Unit of Measure";
begin
ExistingUOM.SetRange("Item No.", pItemNo);
ExistingUOM.SetRange(Code, pCode);
if ExistingUOM.FindFirst() then begin
ExistingUOM.Validate("Qty. per Unit of Measure", QtyPerUOM);
ExistingUOM.Modify();
exit(true);
end;
exit(false);
end;
local procedure InsertNewItemUOM(pCode: Code[20]; pItemNo: Code[20]; QtyPerUOM: Decimal)
var
NewUOM: Record "Item Unit of Measure";
begin
NewUOM.Init();
NewUOM.Validate("Item No.", pItemNo);
NewUOM.Validate(Code, pCode);
NewUOM.Validate("Qty. per Unit of Measure", QtyPerUOM);
NewUOM.Insert(true);
end;
สรุป (Summary)
การทำ Refactor ในภาษา AL Programming ไม่ใช่เพียงการจัดระเบียบโค้ดให้ดูดีขึ้นเท่านั้น แต่คือกระบวนการที่มีเป้าหมายเพื่อ
- เพิ่มความชัดเจน (Readability) ให้โค้ดอ่านง่าย เข้าใจไว
- ลดความซับซ้อน (Maintainability) แก้ไขและดูแลในระยะยาวได้ง่ายขึ้น
- รองรับการขยายฟีเจอร์ (Extensibility) ในอนาคตโดยไม่กระทบโค้ดเดิม
- ช่วยในการทดสอบ (Testability) โดยแยก Logic ออกเป็นฟังก์ชันย่อยได้
เมื่อโค้ดมีโครงสร้างที่ดีจากการ Refactor แล้ว จะช่วยให้สามารถพัฒนา ปรับปรุง และตรวจสอบคุณภาพได้อย่างมีประสิทธิภาพมากยิ่งขึ้น โดยเฉพาะในระบบ Business Central ที่ต้องการความแม่นยำ เสถียร และสามารถต่อยอดได้ในทุกเวอร์ชันของ Extension.

