วันจันทร์ที่ 15 มิถุนายน พ.ศ. 2552

Refactoring 1

Refactoring (ที่มา : http://www.refactoring.com/)
คือ การปรับปรุงโครงสร้างภายในของโปรแกรมที่มีอยู่ในปัจจุบัน โดยไม่กระทบพฤติกรรมของโปรแกรมนั้น หรือพูดอีกนัยหนึ่ง Refactoring ก็คือ ชุดของการเปลี่ยนแปลงรูปแบบเล็ก ๆ หลาย ๆ รูปแบบ โดยแต่ละรูปแบบเล็ก ๆ นั้นไม่กระทบพฤติกรรมของโปรแกรมส่วนนั้นๆ ทำไมถึงต้องเป็นการเปลี่ยนแปลงเล็ก ๆ เหตุผลก็เพื่อลดโอกาสที่้การเปลี่ยนแปลงนั้นจะกระทบการทำงานของระบบให้มากที่สุดนั่นเอง

มีการอธิบายขบวนการทำ Refactoring ในแต่ละรูปแบบ ไว้แล้ว ดังนี้ (ที่มา : http://www.refactoring.com/catalog/index.html)
  1. Add Parameter
  2. คือ การเพิ่ม parameter ของ method เพื่อให้การเรียกใช้ method นั้นสมบูรณ์
  3. Change Bidirectional Association to Unidirectional
  4. คือ การเปลี่ยนความสัมพันธ์ระหว่าง class 1 และ class 2 จากติดต่อกันได้ 2 ทาง เป็นติดต่อได้ทางเดียว คือ เปลี่ยนจากสามารถติดต่อทั้งขาไปและขากลับ ระหว่าง class 1 และ class 2 เป็น ติดต่อได้ทางเดียวคือ ติดต่อจาก class 1 ไปหา class 2 เท่านั้น เพราะ class 2 ไม่ต้องการติดต่อกลับไปหา class 1 หรือก็คือไม่ต้องการ feature ใด ๆ จาก class 1 นั่นเอง
  5. Change Reference to Value
  6. คือ เปลี่ยนการส่งผ่านค่าของ object จากแบบ reference เป็นแบบ value ด้วยเหตุผลที่ว่า object นั้น เล็ก เปลี่ยนรูปไม่ได้ และจัดการยาก
  7. Change Unidirectional Association to Bidirectional
  8. คือ การเปลี่ยนความสัมพันธ์ระหว่าง class 1 และ class 2 จากติดต่อกันทางเดียว เป็นติดต่อได้ทั้งสองทาง คือ เปลี่ยนจากสามารถติดต่อเฉพาะขาไป หรือเฉพาะขากลับ ระหว่าง class 1 และ class 2 เป็น ติดต่อได้ทั้งสองทางคือ ติดต่อจาก class 1 ไปหา class 2 ได้ และติดต่อจาก class 2 ไปหา class 1 ก็ได้ด้วย เหตุผลเพราะทั้งสอง class ต่างต้องการ feature จากอีก class หนึ่งนั่นเอง
  9. Change Value to Reference
  10. คือ เปลี่ยนการส่งผ่านค่าของ instants ซึ่งมีค่าเท่ากัน จากการส่งแบบ value เป็นส่งแบบ reference ด้วยเหตุผลที่ว่า instant นั้น ถูกส่งผ่านค่าหลายครั้งมาก
  11. Collapse Hierarchy
  12. คือ การ merge super class กับ sub class เข้าด้วยกัน ด้วยเหตุผลที่ว่า ทั้งสอง class ไม่มีความแตกต่างกัน มากนัก
  13. Consolidate Conditional Expression
  14. คือการรวมหลาย ๆ conditional tests เข้าด้วยกัน เพื่อให้เป็น single conditional expression ด้วยเหตุผลที่ว่าการรวมกันนั้นไม่ทำให้ผลลัพธ์เปลี่ยนแปลง
  15. Consolidate Duplicate Conditional Fragments
  16. คือ การย้าย fragment ที่เหมือนกัน ของ code ซึ่งปรากฎอยู่ในหลาย ๆ branches ของ conditional expression นั้น โดยทำการย้ายออกไปจาก expression นั้น
  17. Convert Dynamic to Static Construction
  18. คือ การใช้ static code แทนที่จะใช้การ load แบบ dynamic class
  19. Convert Static to Dynamic Construction
  20. คือ การใช้ java.lang.reflect เพื่อแก้ปัญหาที่มีบาง class depends on static compile time
  21. Decompose Conditional
  22. คือการใช้ Extract method ในการแก้ปัญหาคำสั่ง if-then-else โดย extract แต่ละส่วนออกมาเป็นแ้ต่ละ method
  23. Duplicate Observed Data
  24. คือ การทำสำเนาข้อมูลจาก data domain ไปไว้ใน object domain แล้วทำการ set up ให้ observer รู้จักข้อมูลทั้งสองที่ เพื่อแก้ปัญหาที่มีบางข้อมูลใน domain data ซึ่ง available เฉพาะกับ GUI control เท่านั้น
  25. Eliminate Inter-Entity Bean Communication
  26. คือ การใช้ coarse-grained entity bean เพื่อลดหรือกำจัด inter-entity bean relationships ใน model เพราะ inter-entity bean relationships ทำใ้ห้เกิด overhead ใน model
  27. Encapsulate Collection
  28. คือ การทำให้ method เป็นแบบอ่านได้อย่างเดียว พร้อมเพิ่มให้มี add และ remove method เพื่อจัดการกับบางข้อมูลในกลุ่ม เพื่อแก้ปัญหาที่มีบาง method คืนค่าข้อมูลออกมาทั้งกลุ่ม
  29. Encapsulate Downcast
  30. เนื่องจาก method ทำการ return ค่าเป็น object ซึ่งผู้เรียกใช้ method นี้ไม่ต้องการ จึงต้องทำการกำจัดโดยย้ายคำสั่งใน object นี้ กลับไปไว้ใน method ดังกล่าว
  31. Encapsulate Field
  32. คือการทำให้ public field เป็น private field พร้อมกำหนดให้มี accessors
  33. Extract Class
  34. คือการสร้าง class ใหม่ พร้อมทั้งย้าย fields และ methods ที่เกี่ยวข้องจาก class เก่ามาไว้ใน class ใหม่นี้
  35. Extract Interface
  36. คือ การ extract กลุ่มของบางส่วนของ class มาเป็น interface ของ class นั้น ด้วยเหตุผลว่ากลุ่มนี้ถูกเรียกใช้อยู่บ่อยๆ
  37. Extract Method
  38. คือ การ extract บางส่วนของ method ออกมาสร้างเป็น method ใหม่ เพื่อทำงานเฉพาะอย่าง
  39. Extract Package
  40. คือ การย้าย บางส่วน ของ package ออกมาสร้างเป็น package ใหม่ ด้วยเหตุผลที่ว่า package เดิม มีหลาย class เกินไป การสร้าง package ใหม่ ทำให้การทำงานง่ายขึ้น หรือเพื่อแก้ปัญหาที่ package เดิมที่ค่อนข้างสับสนปนเปกันเกินไป
  41. Extract Subclass
  42. คือ การแยกบางส่วนของ class เดิม ไปสร้างเป็น sub class ของ class นั้น เนื่องจากมีหลายครั้งที่การทำงานเกิดขึ้นกับเฉพาะส่วนที่แยกมาเป็น sub class เท่านั้น
  43. Extract Superclass
  44. คือ การ extract ส่วนที่เหมือนกันของ 2 class มาสร้างเป็น super class ของทั้ง 2 class นั้น
  45. Form Template Method
  46. เนื่องจากมี 2 sub class ของ super class เดียวกัน มีลำดับการทำงานเหมือนกัน แต่มีบาง step การทำงานที่แตกต่างกัน จึงแก้ปัญหานี้ โดยรวม step ที่แตกต่างกัน ของทั้งสอง sub class นั้นสร้างเป็น method ไว้ใน subclass นั้น ๆ เช่น รวม step ที่ sub class 1 ต่างจาก sub class 2 สร้างเป็น method ไว้ใน sub class 1 และเช่นกัน รวม step ที่ sub class 2 ต่างจาก sub class 1 สร้างเป็น method ไว้ใน sub class 2 และหลังจากนั้น ก็รวม step ที่เหมือนกันของทั้งสอง sub class โดย pull up ขึ้นไปสร้างเป็น method ไว้ใน super class เพื่อให้ sub class ที่สร้างใหม่ในทั้ง 2 sub class เรียกใช้ร่วมกันได้
  47. Hide Delegate
  48. เนื่องจากมีบาง class บนเครื่อง client เรียกใช้ delegate class ของ object จึงต้องทำการ refactoring โดย สร้าง method ใหม่ ไว้บน server เพื่อซ่อน delegate class ดังกล่าว
  49. Hide Method
  50. เนื่องจากมีบาง method ของ class ใด ๆ ไม่เคยถูกเรียกใช้จาก class อื่นเลย ดังนั้นจึงทำการแก้ไขโดย กำหนดให้ method นั้นมีการเข้าถึงแบบ private
  51. Hide presentation tier-specific details from the business tier
  52. เนื่องจาก business tier สามารถร้องขอ handling และ/หรือ protocol-related data structures ที่ถูกส่งออกมาแสดงจาก presentation tier ได้ จึงต้องแก้ปัญหานี้ โดย remove ทุก references ที่ยอมให้ business tier ทำงานดังกล่าวได้ ออกจาก business tier และกำหนดให้มีการส่งผ่านค่า (values) ระหว่าง tier โดยใช้ data structure ทั่วไปแทน
  53. Inline Class
  54. เนื่องจากมีบาง class ที่ไม่ค่อยได้ถูกใช้งาน จึงไม่ควรสร้างเป็น class อีกต่อไป จึงแก้ปัญหาโดย ยุบ class นั้นแล้วไปสร้างเป็นองค์ประกอบใน class ที่เกี่่ยวข้องแทน
  55. Inline Method
  56. เนื่องจากมีบาง method ที่ชัดเจนจนไม่จำเป็นต้องสร้างเป็น method จึงพิจารณาว่าควรยุบ method นั้นกลับไปเป็นองค์ประกอบของ method ที่เกี่ยวข้องแทน
  57. Inline Temp
  58. เนื่องจากมีตัวแปรชั่วคราวบางตัวที่ถูกกำหนดค่าด้วยชุดคำสั่งง่าย ๆ เพียงครั้งเดียว และตัวแปรชั่วคราวนี้ยังถูกนำเข้ามาใช้ในการทำ refactoring อื่นๆ ด้วย จึงพิจารณาว่าควรยุบตัวแปรชั่วคราวนี้ แล้วแทนที่การทำงานนี้ด้วยชุดคำสั่งแทน
  59. Introduce A Controller
  60. คือ การค้นหา control logic แล้ว extract มันออกมาเพื่อนำมาสร้างเป็น controller classes จำนวนตั้งแต่ 1 class ขึ้นไป โดยกำหนดให้ classes ใหม่เหล่านี้ทำหน้าที่เป็น initial contact point เพื่อ handling การร้องขอที่ส่งมาจาก client
  61. Introduce Assertion
  62. คือ การเพิ่ม assertion เข้าไปใน code ของโปรแกรม เพื่อทดสอบสมมติฐานในเรื่องเกี่ยวกับ state ของโปรแกรม เช่นเงื่อนไขที่เป็นไปไม่ได้ ซึ่งการเพิ่ม assertion เข้าไปในส่วนที่พิจารณาว่าจำเป็นต้องมี assertion นั้นจะส่งผลให้การทำงานของโปรแกรมมีประสิทธิภาพมากขึ้น
  63. Introduce Business Delegate
  64. เนื่องจาก session beans ซึ่งอยู่ใน business tier ต้องถูกส่งไปยัง tiers อื่นของ client จึงนำ business delegate เข้ามาช่วยในการ decouple บรรดา tiers เหล่านั้น และช่วยในการซ่อนรายละเอียดการ implement ด้วย
  65. Introduce Explaining Variable
  66. คือ การเพิ่มตัวแปรที่มีชื่อสื่อความหมาย เพื่อเก็บผลลัพธ์ หรือส่วนของคำสั่ง เพื่อลดความซับซ้อนของคำสั่งโปรแกรม
  67. Introduce Foreign Method
  68. เนื่องจากมีบาง class ของ server ซึ่งกำลังใช้งานอยู่ ต้องการเพิ่ม 1 method เข้าไปใน class นั้น แต่ไม่สามารถแก้ไขโครงสร้าง class ได้ จึงทำการ refactoring โดย เพิ่ม method นั้นใน class ของฝั่ง client โดยอาศัย instance จาก class ดังกล่าวของ server โดยสร้างตอนที่เริ่มติดต่อโต้ตอบกันครั้งแรก
  69. Introduce Local Extension
  70. เนื่องจากมีบาง class ของ server ซึ่งกำลังใช้งานอยู่ ต้องการเพิ่ม หลาย ๆ method เข้าไปใน class นั้น แต่ไม่สามารถแก้ไขโครงสร้าง class ได้ จึงทำการ refactoring โดย เพิ่ม class ใหม่ ให้มีครบทุก method ที่ต้องการเหล่านั้น แล้วกำหนดให้เป็น sub class หรือ wrapper ของ class เดิม
  71. Introduce Null Object
  72. เนื่องจากมีการ วน ตรวจสอบ null value ซ้ำแล้วซ้ำอีก จึงทำการ refactoring โดยแทนที่ null value ด้วย null object
  73. Introduce Parameter Object
  74. เนื่องจากมีการส่งผ่าน parameter กลุ่มหนึ่งไปด้วยกันเสมอ จึงทำการ refactoring โดยส่งเป็น object แทน
  75. Introduce Synchronizer Token
  76. เนื่องจาก client มีการร้องขอสิ่งเดิมซ้ำ ดังนั้นจึงต้องมีการ monitor และ control หรืออาจเกิดเนื่องจาก client มีการเข้าถึงข้อมูล view ใด ๆ อย่างผิดระเบียบ จึงทำการ refactoring โดยใช้ shared token ในการ monitor และ control กระแสการร้องขอนั้น (flow request)
  77. Localize Disparate Logic
  78. เนื่องจากมีการปะปนกันของ business logic และ presentation formatting ใน JSP view จึงต้องทำการ refactoring โดยทำการ extract business logic ออกมาเป็น helper classes จำนวน 1 หรืออาจมากกว่า 1 classe ก็ได้ ทั้งนี้เพื่อให้ JSP หรือ controller เรียกใช้ต่อไปนั่นเอง
  79. Merge Session Beans
  80. เนื่องจากต้องทำการสร้าง mapping ระหว่าง session beans และ entity beans แบบ one-to-one จึงต้องทำการ refactoring โดยทำการ map coarse-grained business services เข้ากับ session beans แล้วจัดการทำลาย หรือ รวม session beans ที่ทำหน้าที่เป็น entity beans proxies เข้ากับ session beans ที่ represent coarse-grained business services ดังกล่าว
  81. Move Business Logic to Session
  82. เนื่องจากความสัมพันธ์(relationships) แบบ inter-entity bean ก่อให้เกิด overhead ใน model นั้นจึงต้องทำ refactoring โดยทำการ encapsulate workflow ที่เกี่ยวข้องกับ inter-entity relationships นั้น โดย encapsulate ไว้ใน session bean
  83. Move Class
  84. เนื่องจากมีบาง class ถูกเก็บไว้ใน package ที่ประกอบด้วย classes อื่น ๆ ซึ่งไม่ได้มีการทำงานที่เกี่ยวข้องกับ class นี้เลย จึงควรทำ refactoring โดยการ move class ดังกล่าว ไปเก็บไว้ใน package อื่นที่เหมาะสม ซึ่งถ้าไม่มี package ที่เหมาะสม ก็อาจสร้าง package ใหม่ เพื่อเก็บ class นี้ไว้ใช้งานต่อไป
  85. Move Field
  86. เนื่องจากมีบาง field ที่ (จะ) ถูกเรียกใช้โดย class อื่น มากกว่า class ตัวเอง จึงควรทำ refactoring โดยย้าย field นี้ไปไว้ใน class ที่เรียกใช้มาก ๆ ดังกล่าว
  87. Move Method
  88. เนื่องจากมีบาง method ที่ (จะ) ใช้ features ของ class อื่น หรือ (จะ) ถูกเรียกใช้ features จาก class อื่น มากกว่า class ตัวเอง ดังนั้นจึงควรทำ refactoring โดยย้าย method นี้ไปไว้ใน class ที่เกี่ยวข้องกับ method นี้มากที่สุด
  89. Parameterize Method
  90. เนื่องจากมี หลาย ๆ methods ที่ทำงานเหมือนกันต่างกันเพียงค่าที่เก็บไว้ในส่วน body ของ methods เหล่านั้น เท่านั้น ดังนั้นจึงควรทำการ refactoring โดย สร้าง method ใหม่ขึ้นมาแล้วใช้ parameter ในการเก็บค่าที่แตกต่างกันของ methods ที่ทำงานเหมือนกันแต่ค่าที่เก็บต่างกันเหล่านั้น
  91. Preserve Whole Object
  92. เนื่องจากมีการทำงาน ที่รับค่าหลาย ๆ ค่า จาก object แล้วส่งผ่านค่าเหล่านั้นผ่าน parameters ของ method ที่เรียกใช้ จึงควรทำ refactoring โดย ส่ง object ให้เลย
  93. Pull Up Constructor Body
  94. เนื่องจากมีการสร้าง constructors บน subclasses โดยที่ constructors เหล่านั้นมีการกำหนดค่าให้ข้อมูลส่วนใหญ่ของ subclasses เหล่านั้น จึงควรทำ refactoring โดยทำการ pull up constructors ของ subclasses เหล่านั้นขึ้นไปเป็น constructors ของ superclass ของมัน แล้วให้ subclasses เหล่านั้นเรียกใช้ได้
  95. Pull Up Field
  96. เนื่องจากมี 2 subclasses มี field ที่เหมือนกัน จึงควรทำ refactoring โดยทำการ pull up field นั้นขึ้นไปเป็น field ของ superclass ของมันเพื่อให้ทั้งสอง subclasses เรียกใช้งาน
  97. Pull Up Method
  98. เนื่องจากมี 2 subclasses มี method ที่เหมือนกัน จึงควรทำ refactoring โดยทำการ pull up method นั้นขึ้นไปเป็น method ของ superclass ของมันเพื่อให้ทั้งสอง subclasses เรียกใช้งาน
  99. Push Down Field
  100. เนื่องจากมี field ของ superclass ที่ถูกเรียกใช้งานจากบาง subclasses เท่านั้น จึงควรทำ refactoring โดยย้าย field นั้นไปไว้ใน subclasses ที่ต้องการใช้งาน
  101. Push Down Method
  102. เนื่องจากมี method ของ superclass ที่ถูกเรียกใช้งานจากบาง subclasses เท่านั้น จึงควรทำ refactoring โดยย้าย method นั้นไปไว้ใน subclasses ที่ต้องการใช้งาน
  103. Reduce Scope of Variable
  104. เนื่องจากมีตัวแปรที่ถูกประกาศไว้ในขอบเขตซึ่งใหญ่กว่าที่ต้องการใช้งาน จึงควรทำ refactoring โดยทำการลดขอบเขตของตัวแปรดังกล่าว ด้วยการกำหนดให้สามารถมองเห็นและใช้งานได้เฉพาะู่ในที่ ๆ ต้องการใช้งานตัวแปรนี้เท่านั้น
  105. Refactor Architecture by Tiers
  106. เนื่องจากการเพิ่มขึ้นของ Architectural Sophistication ต้องการการเปลี่ยนแปลงแบบ localization ของ data access และ processing logic จึงควรทำ refactoring โดยย้าย data access ให้อยู่ใกล้ชิดกับแหล่งที่มาของข้อมูลจริง พร้อมทั้งย้าย processing logic ออกจากเครื่อง client และ presentation tiers โดยย้ายไปไว้ใน business tier แทน
  107. Remove Assignments to Parameters
  108. เนื่องจากโปรแกรมมีำการกำหนดค่าให้กับ parameter ควรทำ refactoring โดยใช้ตัวแปรแบบชั่วคราวแทน
  109. Remove Control Flag
  110. เนื่องจากมีตัวแปรที่ทำหน้าที่เป็น control flag สำหรับการทำงานของชุดคำสั่งทางตรรกะ จึงควรทำ refactoring โดยใช้ break และ return แทน
  111. Remove Double Negative
  112. เนื่องจากมีบางเงื่อนไขเป็นแบบ double negative จึงควรทำ refactoring โดยทำให้เป็น sing positive
  113. Remove Middle Man
  114. เนื่องจากมีการเข้าถึงข้อมูลของบาง class ที่กว่าจะได้ข้อมูลต้องเรียกใช้ผ่านหลายๆ class (เรียกว่ามีคนกลางคอยช่วย หรือก็คือ middle man) จึงควรทำ refactoring โดยทำให้เข้าถึงข้อมูลได้โดยตรง (ก็คือไม่ต้องมี middle man) ทำได้โดยทำให้ client เข้าถึงข้อมูลได้โดยตรง
  115. Remove Parameter
  116. เนื่องจากมีการใช้งาน parameter ในลักษณะที่จะไม่มีการใช้อีกในอนาคต จึงควร refactoring โดยเลิกใช้ parameter ดังกล่าว
  117. Remove Setting Method
  118. เนื่องจากมี field ที่ต้องกำหนดค่าให้ตอนสร้างครั้งแรก และห้ามเปลี่ยนแปลงแก้ไขค่าหลังจากนั้น จึงควรทำ refactoring โดยลบทุก method ที่ทำหน้าที่เปลี่ยนแปลงแก้ไขค่าของ field นี้
  119. Rename Method
  120. เนื่องจากมีบาง method ที่มีชื่อที่ไม่สื่อความหมาย จึงควร refactoring โดยทำการเปลี่ยนชื่อของ method นั้น
  121. Replace Array with Object
  122. เนื่องจากมีการใช้ array โดยที่แต่ละ elements ใน array นั้นมีการเก็บข้อมูลที่มีความหมายแตกต่างกัน จึงควร refactoring โดยการใช้ object ที่ประกอบด้วยหลาย field แทน โดยแต่ละ field ของ object แทนแต่ละ element ใน array นั่นเอง
  123. Replace Assignment with Initialization
  124. เนื่องจากมีโปรแกรมที่คำสั่งแรก ประกาศตัวแปร คำสั่งถัดมาคือ กำหนดค่าให้ตัวแปร จึงควร refactoring โดยยุบรวมสองคำสั่งนี้เป็นคำสั่งเดียว คือประกาศตัวแปรพร้อมกับกำหนดค่าไปด้วยในคราวเดียวกัน
  125. Replace Conditional with Polymorphism
  126. เนื่องจากมีโปรแกรมแบบเงื่อนไข ที่แต่ละเงื่อนไขจะทำงานต่างกันขึ้นอยู่กับ type ของ object ในเงื่อนไขนั้น ๆ จึงควรทำ refactoring โดยแทนที่โปรแกรมแบบเงื่อนไขนี้ด้วย polymorphism ซึ่งวิธีการก็คือ ทำการสร้าง subclass โดยแต่ละ subclass มี overriding method ซึ่งสร้างมาจากการดึงมาจากส่วนที่เป็นขาของแต่ละเงื่อนไขของ method เดิมใน class เดิม แล้วทำให้ method เดิมใน class เดิมนั้นเป็น abstract และให้กำหนดให้ class เดิมของ method เดิมนี้เป็น superclass ของ subclasses ใหม่ที่สร้างขึ้น
  127. Replace Conditional with Visitor
  128. เนื่องจากมีโปรแกรมแบบเงื่อนไข ซึ่งเงื่อนไขนั้นค่อนข้าง aggressive คือมีการทำงานต่างกันขึ้นอยู่กับ type ของ object ในเงื่อนไข และเรียกตัวเองซ้ำ ๆ บ่อย ๆ จึงควรทำ refactoring โดยแทนที่โปรแกรมแบบเงื่อนไขนี้ด้วย visitor วิธีการคือ สร้าง concrete instance ของ visitable object จากแต่ละ data type ของ object ในเงื่อนไขดังกล่าว และสร้าง concrete instance ของ visitor ซึ่ง encapsulate logic ของแต่ละเงื่อนไขนั้นไว้ แล้วกำหนดให้ visitor ทำการ visit visitable นั้น
  129. Replace Constructor with Factory Method
  130. เนื่องจากต้องการทำอะไรที่มากกว่าการ construction แบบง่าย ๆ จึงควรทำ refactoring โดยแทนที่ constructor ด้วย factory method
  131. Replace Data Value with Object
  132. เนื่องจากมีบาง data item ที่ต้องการเพิ่มเติม data หรือ behavior เข้ามา ในตัวมัน จึงควรทำ refactoring โดยเปลี่ยน data item นั้นให้กลายเป็น object
  133. Replace Delegation with Inheritance
  134. เนื่องจากมีการใช้ delegation และมักจะเขียน delegation แบบง่าย ๆ เพื่อให้ interface ใช้งาน จึงควรทำ refactoring โดยเลิกใช้ delegation แต่นำ delegation ไปสร้างเป็น subclass ของ interface นั้นแทน
  135. Replace Error Code with Exception
  136. เนื่องจากมีการเขียนโปรแกรมที่มีการคืนค่า error code ออกมา ควรทำ refactoring โดยใช้ exception แทน
  137. Replace Exception with Test
  138. เนื่องจากมีบาง exception ที่่ต้องการให้ผู้เรียกตรวจสอบเงื่อนไขก่อนเป็นอันดับแรก ดังนั้นควร refactoring โดยแก้ไขโปรแกรมส่วน exception ให้ ผู้เรียก ต้องตรวจสอบก่อนเป็นอันดับแรก
  139. Replace Inheritance with Delegation
  140. เนื่องจากมีบาง subclass ที่ใช้เฉพาะส่วน interface ของ superclass ไม่ได้ต้องการการถ่ายทอดข้อมูล จาก superclass จึงควรทำ refactoring โดยยุบความสัมพันธ์แบบ subclass ไปสร้างเป็น field ใน superclass แล้วแก้ไข method ใน subclass เดิม (ซึ่งตอนนี้ยังคง class นี้ไว้อยู่ เพียงแต่ไม่ใช่ subclass) ให้ delegate ไปยัง superclass เดิม
  141. Replace Iteration with Recursion
  142. เนื่องจากมีการวน loop ทำงานโปรแกรม และไม่ชัดเจนว่าการทำซ้ำหรือวน loop แต่ละครั้งคือการทำงานอะไร จึงควร refactoring โดยใช้ recursion แทนการวน loop ดังกล่าว
  143. Replace Magic Number with Symbolic Constant
  144. เนื่องจากมีการใช้ตัวเลขเพื่อแทนความหมายเฉพาะอย่างในโปรแกรม ดังนั้นควรทำ refactoring โดยใช้ constant เพื่อใช้เก็บค่าตัวเลขเหล่านั้น โดยตั้งชื่อตัวแปรให้สื่อความหมายด้วย
  145. Replace Method with Method Object
  146. เนื่องจากมี long method ซึ่งใช้ local variables จึงทำใ้ห้ไม่สามารถทำ refactoring แบบ extract method ได้ ดังนั้นจึงควรใช้ object ของตัวมันเอง แทน method ดังกล่าว โดยกำหนดให้ local variables เป็น fields ของ object นี้แทน ซึ่งส่งผลให้ต่อไปก็จะไม่สามารถ decompose method นี้ไปเป็น method อื่นใน object เดียวกันได้
  147. Replace Nested Conditional with Guard Clauses
  148. เนื่องจากบาง method มี พฤติกรรมการทำงานตามเงื่อนไข ซึ่งไม่ชัดเจนว่า normal path ของการ execution อยู่ตรงไหน จึงควร refactoring โดยใช้ Guard Clauses แทนทุก special case เหล่านั้น
  149. Replace Parameter with Explicit Methods
  150. เนื่องจากบาง method มีการทำงานที่แตกต่างกันขึ้นอยู่กับค่าของ enumerated parameter จึงควร refactoring โดยสร้าง method แยกไปต่างหากสำหรับแต่ละค่าของ parameter เหล่านั้น
  151. Replace Parameter with Method
  152. เนื่องจากมีการเขียนโปรแกรมที่มี ตัวแปร รับค่าผลลัพธ์จาก method ใด ๆ แล้วส่งค่าผลลัพธ์ที่รับมานั้น เป็น parameter ใน method อื่นทั้ง ๆ ที่ method อื่นนั้น สามารถเรียกใช้ method ใด ๆ นั้นได้เช่นกัน ควรทำ refactoring โดย เลิกส่งผ่านค่า parameter นั้น แต่ให้ method อื่นนั้นเรียกใช้และรับค่าผลลัพธ์จาก method ใด ๆ นั้นโดยตรง
  153. Replace Record with Data Class
  154. เนื่องจากในสิ่งแวดล้อมแบบ traditional program นั้น หากจำเป็นต้องทำการ interface กับ record structure ควรทำ refactoring โดยใช้ dumb data object แทน record นั้น
  155. Replace Recursion with Iteration
  156. เนื่องจากมีการใช้ recursion ที่ยากในการทำความเข้าใจ จึงควรทำ refactoring โดย แทนที่ recursion นั้น โดยคำสั่งทำซ้ำ ๆ
  157. Replace Static Variable with Parameter
  158. เนื่องจากมีความต้องการ reuse บาง function ซึ่งการทำงานขึ้นอยู่กับ static variable ในหลาย ๆ ที่ของโปรแกรม จึงควรทำ refactoring โดยใช้ parameter แทนในคำสั่งใน function ทุกที่มีการ reference ไปยัง static variable ดังกล่าว
  159. Replace Subclass with Fields
  160. เนื่องจาก มีชุดของ subclasses ที่มี method ที่ inherit มาจาก superclass เหมือน ๆ กัน แต่ที่แยกเป็น subclasses ที่แตกต่างกัน เพราะต้องการค่าที่คืนกลับมายังผู้เรียกต่างกันเท่านั้น จึงควรทำ refactoring โดยยุบ subclasses เหล่านั้น และนำไปสร้างเป็น fields ใน superclass เพื่อให้ method ต้นฉบับใน superclass เรียกใช้แทน
  161. Replace Temp with Query
  162. เนื่องจากมีการใช้ตัวแปรชั่วคราวในการเก็บผลลัพธ์ของ expression จึงควรทำ refactoring โดย สร้าง method ใหม่ แ้ล้วทำการ extract expression นั้นไปไว้ใน method ใหม่ดังกล่าว พร้อมทั้งแทนที่การอ้างถึงตัวแปรชั่วคราวดังกล่าวด้วย expression ใน method ใหม่ ซึ่ง method ใหม่นี้สามารถถูกนำไปใช้ใน method อื่น ๆ ต่อไปได้
  163. Replace Type Code with Class
  164. เนื่องจากบาง class ประกอบด้่วย numeric type code เพราะไม่ต้องการใ้ห้กระทบพฤติกรรมการทำงานของโปรแกรม จึงควรทำ refactoring โดยการสร้าง class ใหม่ แล้วแทนที่ numeric type code นั้นด้วย class ใหม่ที่สร้างขึ้น
  165. Replace Type Code with State/Strategy
  166. เนื่องจากมีบาง type code ที่มีผลกระทบกับพฤติกรรมการทำงานของ class แต่ไม่สามารถสร้าง subclasses ได้ กรณีนี้ควรทำ refactoring โดยแทนที่ type code นั้นด้วย state object
  167. Replace Type Code with Subclasses
  168. เนื่องจากมีบาง type code ซึ่งเปลี่ยนรูปไม่ได้ และมีผลกระทบกับพฤติกรรมการทำงานของ class กรณีนี้ควรทำ refactoring โดยแทนที่ type code นั้นด้วย subclasses
  169. Reverse Conditional
  170. เนื่องจากมีบางเงื่อนไขซึ่งจะทำความเข้าใจได้ง่ายขึ้นถ้าได้ reverse ความหมายของมัน ดังนั้นจึงควรทำ refactoring โดยทำการ reverse เงื่อนไข และเรียงลำดับ conditional's clause ใหม่
  171. Self Encapsulate Field
  172. เนื่องจากมีการเข้าถึงบาง field ได้โดยตรง แต่การ coupling ไปยัง field นั้นค่อนข้างงุ่มง่าม ดังนั้นควรทำ refactoring โดยสร้าง getting และ setting methods สำหรับ field นั้น เพื่อใช้ในการเข้าถึง field นั้นเพียงอย่างเดียว
  173. Separate Data Access Code
  174. เนื่องจากมีบาง data access code ซึ่งถูกฝังไว้ใน class โดยตรง อันเป็นต้นเหตุให้ความสัมพันธ์กับองค์ประกอบอื่นเกิดขึ้นไม่ได้ จึงควรทำ refactoring โดยทำการ extract data access code นั้นไปสร้างเป็น class ใหม่ และย้าย class นี้ไปไว้ใกล้กับ data source ให้มากที่สุด
  175. Separate Query from Modifier
  176. เนื่องจากมีบาง method ที่ถึงแม้จะมีการคืนค่าออกมา แต่ก็ยังคงเปลี่ยนแปลง state ของ object ได้ จึงควรทำ refactoring โดยสร้าง 2 methods ใหม่ขึ้นมา โดย method แรกเพื่องาน query ส่วนอีก method มีไว้เพื่องาน modification
  177. Split Loop
  178. เนื่องจากมีการทำงานแบบวนรอบ ที่มีทำงาน 2 อย่าง จึงควรทำ refactoring โดยทำการ duplicate งานวนรอบนั้นออกมาเป็นอีกอันหนึ่ง เพื่อแยก 2 งานนั้นออกจากกัน
  179. Split Temporary Variable
  180. เนื่องจากมีการใช้ตัวแปรชั่วคราว และกำหนดค่าให้ตัวแปรชั่วคราวนั้นมากกว่าหนึ่งครั้ง แต่ไม่ใช่ตัวแปรแบบวนรอบและไม่ใช่ตัวแปรสำหรับเก็บค่าสะสม ดังนั้นควรทำ refactoring โดยแยกตัววแปรชั่วคราวนั้นออกมาให้เพื่อให้มีหนึ่งตัวแปรต่อการกำหนดค่าหนึ่งครั้ง
  181. Substitute Algorithm
  182. เนื่องจากต้องการแทน algorithm ด้วยสิ่งที่ชัดเจนขึ้น ดังนั้นควร refactoring โดยแทนที่ส่วน body ของ method ด้วย algorithm ใหม่
  183. Use a Connection Pool
  184. เนื่องจากไม่มีการ share ส่วนที่เป็น database connection ทำให้ client ต้องจัดการ connections เองโดยการทำ database invocations ดังนั้นจึงควรทำ refactoring โดยใช้ connection-pool ในการทำ pre-initialize หลาย ๆ connections ที่เกิดขึ้นกับ client เหล่านั้นแทน เพื่อให้การขยายระบบ(scalability)ทำได้ดีขึ้น และประสิทธิผลการทำงาน(performance)ดีขึ้น
  185. Wrap entities with session
  186. เนื่องจากมี entity beans ที่มาจาก business tier ถูกส่งไปยัง tier อื่นของ client ดังนั้นควรทำ refactoring โดยใช้ session facade มาห่อหุ้ม (encapsulate) entity beans ดังกล่าวแทน
เนื่องจากมีผู้สนใจในเรื่องเกี่ยวกับ refactoring มาก ทำให้พัฒนาการทางด้านนี้ก้าวหน้าขึ้นอย่างรวดเร็ว หากมีท่านใดสนใจงานด้านนี้ หรือผู้รู้่ท่านใดมีคำแนะนำ เชิญร่วมแสดงความคิดเห็นค่ะ

1 ความคิดเห็น:

  1. ผมเสนอว่าลองมาจัดกลุ่มสักหน่อยดีไหมครับ เช่นกลุ่มของ refactoring ที่เกี่ยวกับการโปรแกรมแบบทั่ว ๆ ไป การ refactoring เกี่ยวกับการโปรแกรมในระดับ enterprise อะไรประมาณนี้นะ่ครับ

    ตอบลบ