Monthly Archives: June 2024

DDD in Action

หลังจากที่ได้เรียนรู้ Domain Driven Design (DDD) แล้ว ลองเอา concept ของ DDD มาใช้เพื่อออกแบบ Software Architect โดยใช้หลักการของ Swift Method ซึ่งเป็น framework สำหรับการพัฒนา Modernization Software

เริ่มจากสิ่งที่เราเข้าใจ และอธิบายความหมายของคำว่า Item อย่างไร

Item สำหรับแต่ละคนมีความหมายที่แตกต่างกัน แล้วแต่ประสบการณ์และมุมมอง

Item เมื่อไปอยู่ในแต่ละ context ที่แตกต่างกัน ก็จะมีลักษณะไม่เหมือนกัน หรือเป็นคนละอย่างกันเลย เช่น Item ที่อยู่ใน Cart ก็อาจจะเป็นสินค้า แต่ Item ที่อยู่ใน Order ก็จะหมายถึงคำสั่งซื้อ โดยที่อาจจะมีข้อมูลและลักษณะใช้แทนกันไม่ได้เลยทีเดียว ดังนั้นการออกแบบ Software ที่หลายๆ Application ใช้ share data model เดียวกันจึงเป็นการออกแบบที่ไม่เหมาะสม เพราะจะมีปัญหาเรื่องของการ scale หรือแก้ไขเพิ่มเติม จะส่งผลกระทบกับหลายๆ Application ในภายหลัง

สิ่งสำคัญต่อมาคือการพัฒนาการสื่อสารที่เป็น common language ระหว่าง Business และ IT เพราะปัญหาของนักพัฒนา Application ส่วนใหญ่จะเป็นเรื่องของความเข้าใจที่คลาดเคลื่อน (misaligned) จากผู้ที่เป็น Business หรือเจ้าของ Project (Domain Experts) เพราะคนกลุ่มนี้จะไม่ค่อยเข้าใจเรื่อง IT ดังนั้น Software Developer จะต้องใช้ภาษาที่ Business เข้าใจง่าย รวมถึงการออกแบบจะต้องใช้รูปแบบที่แสดงให้เห็นถึงสิ่งที่เกิดขึ้นในชีวิตจริง จึงจะสามารถพัฒนา Code ตาม Business Concept ได้อย่างถูกต้อง

ซึ่งก็คือการใช้ ubiquitous language หรือที่เรียกว่าการใช้ภาษาเดียวกันภายใน bounded context ที่ทีมได้ร่วมกันพัฒนาอยู่

นอกจากนี้ยังต้องพิจารณาเรื่องของ integration ระหว่าง context อื่นๆ ที่ต้องมีรูปแบบการสื่อสารและความสำพันธ์ขึ้นอยู่กับ context นั้นๆ

และกรณีที่ต้องมีการแปลงการสื่อสารเพื่อให้สื่อสารได้ตรงกัน ก็จำเป็นต้องมี Anti-Corruption Layer ACL เข้ามาร่วมด้วย เช่นการสื่อสารระหว่าง 2 ทีม ที่เป็น upstream และ downstream โดยที่ downstream มีส่วนของ ACL เพื่อให้การสื่อสารสามารถเข้ากันได้ เป็นต้น

บางกรณีอาจจะพิจารณาใช้ Aggregates เพื่อให้ข้อมูลถูกนำไปใช้ได้เลย

อาจจะมองเป็นลักษณะของ transaction ที่ข้อมูลประกอบด้วยหลายๆ business entity เช่น Policy, Order, Customer, Account ที่ถูก Aggregates ไว้ด้วยกัน ซึ่งแสดงความสัมพันธ์เป็นลำดับชั้นของกราฟที่มี Root entity และ entity อื่นๆ รวมถึง value object

ตัวอย่างของ Aggregate ของ Item

Item เป็น transaction ที่ประกอบด้วยหลาย entity ภายใต้ขอบเขตเดียวกัน (consistency boundary) สามารถมีได้มากกว่าหนึ่ง entity และ value object โดยมีการ reference ผ่าน ID (ไม่ใช่ reference object) ดังนั้นเมื่อมีการเปลี่ยนแปลงใดๆ กับ Item ก็จะทำให้ผู้ที่เรียกใช้ Item นี้เห็นการเปลี่ยนแปลงนี้ด้วยเช่นกัน (eventually consistent)

Domain Events เป็นเหตุการณ์ที่เกิดขึ้นใน Business เนื่องจากเป็นเหตุการณ์ที่เกิดขึ้นแล้ว จึงนิยมใช้ในรูปแบบ Past Tense การเขียนจะต้องใช้ภาษาที่เข้าใจง่ายทั้ง dev และ domain expert โดยชนิดของ event มีทั้งที่เป็น การแจ้งเตือน (Notification) และ การเปลี่ยนสถานะ (State transfer)

Command ใช้เพื่อระบุว่าเกิดการ request หรือ trigger เพื่อให้เกิดเหตุการณ์ใดๆ ขึ้นใน Business

เมื่อนำ item, domain event และ command เพื่อแสดงสิ่งที่เกิดขึ้นใน domain มารวมกันจะทำให้ทั้ง business expert และ developer เข้าใจตรงกัน สื่อสารกันได้ง่ายและถูกต้อง

Event Storming

ในการออกแบบ software ควรต้องเริ่มต้นจาก events ที่เกิดขึ้นในแต่ละ business โดย event เองเป็น common language ที่ทั้ง business และ IT สามารถสื่อสารและเข้าใจกันได้ง่าย

ข้อดีของการทำ Event Storming

  • ทำให้ Business และ IT เข้าใจในทิศทางเดียวกัน
  • เป็นวิธีที่มีประสิทธิภาพในการทำงานกับ Business
  • ทำให้เข้าใจรายละเอียดของ Domain และ Sub Domain
  • พูดคุย แลกเปลี่ยนความคิดเห็น
  • วิธีการที่เร็ว ทำให้เห็นปัญหา แก้ไข และปรับปรุงให้ดีขึ้น
  • สามารถมองเห็นว่าควรจะทำอะไรก่อนหลัง (priority) และการ deliver
  • สามารถมองเห็นปัญหาได้แต่เนินๆ
  • ตัดสินใจเริ่มทำสิ่งใดสิ่งหนึ่งได้ง่าย

ในการทำ session Event Storming จำเป็นต้องจัดสถานที่ที่เหมาะสม เพื่อให้ business และ IT ได้ทำกิจกรรมด้วยกัน โดยมีกระดาน (board) ที่มีเนื้อที่ขนาดใหญ่ และ sticky note สำหรับแต่ละคนใช้เพื่อเขียน event ลงใน sticky note เพื่อแปะบนกระดาน (board) มีการอธิบายรูปแบบของสีที่ใช้ ว่าสื่อความความหมายถึงอะไร

ในการแปะ event ลงใน board จะต้องเรียงตามลำดับเวลาจากสิ่งที่เกิดขึ้นก่อน แล้วตามด้วยสิ่งที่เกิดขึ้นภายหลัง

ตัวอย่างการแปะ event โดยแบ่งตามสี ถ้าสีส้มคือ event ส่วนสี ชมพู หมายถึง note และแปะตามเวลาก่อนหลัง

ทั้งนี้อาจจะมีสีอื่นๆ เพื่ออธิบาย event ที่เกิดขึ้นได้ชัดเจน เช่น

ตัวอย่างการแปะ event เพื่อแสดง aggregate และ command ด้วย

Value Stream Scenario

ตัวอย่างของการใช้ Event Storming สำหรับระบบ E-Commerce ที่ลูกค้าสามารถเลือกสินค้าเข้าไปยังตะกร้า (cart) ทำการสั่งซื้อ (checkout) มีการส่ง order ไปยังระบบส่งของไปยังที่อยู่ปลายทาง (Shippping)

ลำดับเหตุการณ์ของระบบ purchase แบะ fulfillment จากการทำ Event Storming

จากลำดับเหตุการณ์ทำการ Grouping ให้ event ประเภทเดียวกันอยู่ด้วยกันเพื่อให้เข้าใจง่ายขึ้น และแปะชื่อกลุ่ม รวมถึง note ถ้ามี

แต่ละ group คือ sub domain ใน DDD ที่เคยเรียนมา ทำการแปะเพิ่มเติมในแต่ละกลุ่ม เพื่อให้ event มีความสมบูรณ์มากขึ้น โดยใช้สีแทนความหมาย (DDD – Tactical design)

หลังจากนั้นนำแต่ sub domain มาสร้างเป็นความสัมพันธ์ว่าในแต่ context นั้นมีการเรียกใช้ data หรือบริการอะไรจาก context อื่น เรียกแบบ Sync call หรือ Async event ด้วยวิธีการนี้จะทำให้เราเห็นภาพรวมของระบบ รวมถึงปัญหาที่อาจจะเกิดขึ้นจากการ integration ข้อมูลที่จำเป็นที่จำเป็นจะต้องรู้จากระบบภายนอก (external sytem) เป็นต้น

ตัวอย่างข้างต้นคือการทำ BORIS ซึ่งเป็นกระบวนการหนึ่งใน Swift Method

ขั้นตอนสุดท้ายคือการลงรายละเอียดของ APIs, Data, Pub/Sub, External System/UI, Agile Stories และ Risk เพื่อให้เข้าใจว่าในแต่ sub domain มีกระบวนการ ขั้นตอนการทำงานที่เป็น specification คร่าวๆ เพื่อนำไปเข้าระบบ project management tool (Jira) และทีม developer ก็สามารถจะเริ่มทำการ develop software ได้ตาม sprint หรือ agile process

ขั้นตอนนี้เรียกว่า SNAP ในกระบวนการของ Swift Method

ภาพรวมของทุก sub domain

จะเห็นว่ากระบวนการออกแบบ software เป็นเรื่องที่สนุกและการมีหลายๆ ทีมที่เกี่ยวข้องเข้ามาร่วมออกแบบจะทำให้ software ออกมาตรงความตรงการ และ business ก็สามารถเข้าใจ และแนะนำการแก้ไข และปรับปรุงได้ง่าย

และการมี diagram ที่ติดไว้ใน board จะทำให้ทีมที่เกี่ยวข้อง เข้าใจในส่ิงที่กำลัง develop และไม่เสียเวลามากนักในขั้นตอน document

Cloud Native Design – 12 Factors

หลักการพิจารณาเพื่อให้การออกแบบ Application สามารถทำงานบน Cloud Environment ได้อย่างราบรื่น และใช้ความสามารถของ Cloud ใด้อย่างมีประสิทธิภาพ ประกอบด้วย 12 ข้อดังนี้

  1. Codebase ใช้ code base เดียว เพื่อ track ในแต่ละ revision control และ deploy ไปยังแต่ละ environment ต่าง

2. Dependencies ระบุความต้องการ lib และ dependencies อื่นๆ ใน project และไม่ share

3. Configuration เก็บ configuration ของ application ใน environment ของระบบ แยกจาก code

4. Backing services สร้าง resource adapter ไปยัง external service อื่นๆ โดยมองว่าเป็นหนึ่ง resource ที่ application เรียกใช้งาน ทำให้การสลับแต่ล่ะ resource ทำได้ด้วยการ attach resource ใหม่ โดยไม่กระทบกับ code

5. Build, release, run แยกขั้นตอน build และ run จากกัน ทำให้ build ครั้งเดียวสามารถ deploy ไปยังหลายๆ ที่

6. Processes ต้อง run app ในรูปแบบ stateless process กรณีที่ต้องมีการจัดเก็บ state การทำงานสามารถเก็บไว้ใน cache โดยใช้หลักการ Backing Services

7. Port Binding ต้อง expose service ออกมาในรูป service port ให้ภายนอกเรียกใช้

8. Concurrency สามารถรอบรับปริมาณงานด้วยการเพิ่มจำนวน process

9. Disposability กระบวนการ start/stop service ต้องทำได้ด้วยความรวดเร็ว โดยไม่ต้องการ manual process หรือ script

10. Dev/Prod Parity สร้าง environment dev และ prod โดยใช้ config และ components version เดียวกัน

11. Logs ใช้ระบบเพื่อจัดการ application log ไม่เป็นส่วนหนึ่งของ application

12. Admin Processes แยก process สำหรับงาน admin และจัดการอื่นๆ

Ref:

the twelve-factor app

Domain Driven Design (DDD)

เป็นรูปแบบการออกแบบ Software System ที่แก้ปัญหาความซับซ้อน (complexity) โดยเทียบเคียงกับหน่วยงานหรือองค์กรที่การดำเนินงานธุรกิจ ที่มีความถนัดในเรื่องใดเรื่องหนึ่งเฉพาะ (expert domain) การใช้วิธีการนี้เป็นการนำไปสู่การออกแบบ microservice application ได้อย่างดีรวมถึงเป็นการสื่อสาร สร้างความเข้าใจกับทีม Business อย่างมีประสิทธิภาพ (Business first approach)

Domain Driven design แบ่งออกเป็น 2 ส่วนคือ Strategic design และ Tractical Design โดยที่ Strategic Design เป็นการออกแบบเชิงกลยุทธ์ เน้นถึงสิ่งที่สำคัญเชิงกลยุทธ์ต่อธุรกิจ โดยแบ่งตามความสำคัญและผสมผสานตามความจำเป็น

Strategic Domain Driven Design ประกอบด้วย

  • Domain
  • Sub-Domain
  • Bounded Context
  • Ubiquitous Language
  • Context Map

Tactical Domain Driven Design เป็นวิธีปฏิบัตที่จะทำให้บรรลุเป้าหมายตามกลยุทธ์ ส่วนนี้จะลงลึกถึงขั้นตอนในเชิงปฏิบัติ

ประกอบด้วย

  • Entities
  • Value Objects
  • Aggregates
  • Services
  • Modules
  • Factories
  • Repositories

Domains ประกอบด้วย sub-domains และ bounded context

Core Domain คือส่วนของธุรกิจหลัก ซึ่งเป็นสิ่งที่มีคุณค่าและโดดเด่นกว่าคู่แข่ง ไม่ต้องการแชร์หรือให้ใครก็ตามใช้โมเดลหลักนี้ รวมถึงการทำให้โมเดลนี้ไปติดกับ framework ใดๆ (Hibernate Entities) โดยจะมีการพัฒนาในส่วนนี้เองทั้งหมด

Supporting Domain เป็น domain ที่ช่วยทำให้ธุรกิจสามารดำเนินการได้โดยปกติ ตัวอย่างเช่น ในการอนุมัติสินเชื้อ เราต้องการข้อมูลเครดิตบูโรร่วมด้วยในการพิจารณา ทั้งนี้ควรพิจารณาเครื่องมือที่มีอยู่แล้วเพื่อเป็นส่วนเสริมให้กับธุรกิจหลัก หรือนำจากแหล่งอื่นๆ มาใช้ หรือไม่ก็พิจารณาสร้างเท่าที่เห็นว่าจำเป็น

Generic Domain เป็นสิ่งที่มีทั่วไป หรือกระบวนการธุรกิจทั่วไป ที่เราไม่ควรสร้างขึ้นมาใหม่ เช่น SMTP server สำหรับส่ง email หรือ cloud platform สำหรับ run application ควรพิจารณาลงทุนในส่วน core domain เป็นหลัก

Bounded Contexts

  • เป็นขอบเขตบริบทเชิงความหมาย ซึ่งเมื่อพูดถึงสิ่งไดสิ่งหนึ่งแล้วคนฟังจะเข้าใจทันทีว่าเป็นเรืองอะไร
  • เมื่อเป็นคนละเรื่อง สามารถมองได้ว่าจะต้องใช้ software package แยกกัน
  • ในแต่ละ Bounded Context จะมี components อยู่ข้างในที่มีความหมายและทำงานเฉพาะตัว
  • มีการพัฒนาเพื่อให้องค์กรมีความแตกต่างและแข่งขันกับองค์กรภายนอกอื่นๆ
  • ต้องมีหลักในการพิจารณาว่าอะไรควรหรือไม่ควรจะเป็นส่วนหลักของ core domain

ยกตัวอย่างทีม Developer ที่ทำงานกับเรื่องไดเรื่องหนึ่ง เช่น Bounded Context A

โดยที่ทีมนี้สามารถทำงานกับ Bounded context อื่นได้ แต่ไม่ควรให้หลายทีมทำงานบน Bounded Context เดียวกัน เพราะจะส่งปัญหาเรื่องความเข้าใจกับ Bounded Context ที่แตกต่างกันได้

ทำไม Bounded context จึงสำคัญ ถ้าเราพิจารณาเรื่อง Account ในความหมายของ Account สำหรับ Banking ก็จะหมายถึงบัญชีธนาคาร ยอดเงินฝาก ดอกเบี้ย แต่ถ้าในมุมมอง Security จะหมายถึง User Login สิทธิการเข้าถึง service ต่างๆ ดังนี้การมีหลายทีมที่ทำเรื่องเดียวกัน สิ่งเดียวกันแต่อาจจะเป็นคนละอย่างกันได้

Ubiquitous Language

เป็นพัฒนาภาษาที่คุยทั่วไปภายในทีม เช่นคำย่อ เพื่อให้การสื่อสารได้ด้วยความรวดเร็ว และเข้าใจตรงกัน ซึ่งมีทั้งที่เชิงเทคนิค และในเชิงธุรกิจ ของบริบทและในขอบเขตของเรื่องนั้นๆ (Bounded context) แต่ต้องระวังเมื่อนำไปคุยสื่อสารในกลุ่มอื่นๆ เพราะอาจจะเกิดความไม่เข้าใจได้

Context Maps

เป็นภาพรวมความสัมพันธ์ของธุรกิจระหว่าง bounded contexts ต่างๆ ในองค์กร (domain) ซึ่งเป็นส่วนสำคัญ ทำให้ทราบการเชื่อมโยงและวิธีการจัดการในแต่ละ contexts อย่างเช่น Banking ที่เชื่อมโยงไปในหลาย context ตามรูป

Context mappings ประกอบด้วย

  • Partnership
  • Shared kernel
  • Customer-Supplier
  • Conformist
  • Anti-corruption layer
  • Open host service
  • Published language
  • Big ball of mud
  • Separate ways

Context Mapping – Partnership

เป็นความสัมพันธ์ที่มีการร่วมือ และยอมรับอย่างเติมที่ contexts ทั้งสองขึ้นอยู่กับกันและกัน สามารถสื่อสารอย่างเปิดเผย เป็นกรณี success หรือ fail ไปด้วยกัน

Context Mapping – Shared Kernel

เป็นความสัมพันธ์ที่ทั้งสองทีมแบ่งส่วนใดส่วนหนึ่งเพื่อใช้ร่วมกัน ส่งผลให้เกิดการแยกส่วนร่วมนี้เป็นก้อนใหม่ (artifact) เพื่อการ deliver

Context Mapping – Customer-Supplier

เงื่อนไขความสำเร็จของ Supplier บางส่วนขึ้นอยู่กับความสำเร็จของ Customer เช่นระบบกู้ยืมจำเป็นต้องได้ข้อมูลทางด้านการเงินเพื่อพิจารณา

Context Mapping – Conformist

เป็นความคล้อยตาม (conform) ที่โมเดล upstream มีทุกอย่างที่ downstream ต้องการ โดยที่ upstream ไม่ได้สนใจ downstream

Context Mapping – Anti-Corruption Layer

เป็นลักษณะที่ context ไม่สามารถปฏิบัติตามได้ จึงต้องมีส่วนสำหรับการแปลงการสื่อสารภายใน

Context Mapping – Open Host Service

เป็นการกำหนด protocal ในการสื่อสารไว้เพื่อให้ context อื่นสามารถใช้ integrate เข้ามาได้

Context Mapping – Published Language

เป็นการกำหนดภาษากลางไว้สำหรับการติดต่อ เช่น JSON, YAML, XML

Context Mapping – Big Ball of Mud

เป็นอีกประเภทของความสัมพันธ์แบบ ACL ที่ Bounded Context ได้ให้ส่วนของ model ต่างๆ มาใช้ มักจะพบเมื่อต้อง integrate กับระบบเก่ามากๆ (Lagacy)

Context Mapping – Separate ways

เป็นการยกเลิกความสัมพันธ์ที่มีอยู่ และสร้างขึ้นมาใหม่ใน context ทั้งนี้อาจจะง่ายกว่าที่ต้องใช้ความสัมพันธ์ในแบบเดิม

Tactical Design

เป็น design ที่มี scope ใน context ประกอบด้วยหลายส่วนดังนี้

  • Entity ส่วนใดๆ (things) ใน model ที่มีความจำเพาะ (unique identity)
  • Value Object ใช้ในการให้ความหมาย และจำนวนของ Entity เช่น สี และ จำนวน โดยจะไม่มีการเปลี่ยนรูป
  • Aggregates เป็นการรวมหรือเชื่อมข้อมูล เช่น Entity และ Value Object
  • Services การทำงาน หรือ Function
  • Factories สำหรับสร้างส่วนเสริมต่างๆ หรือส่วนสนับสนุน
    • Repositories ตัวแทนสำหรับการ access data ทำให้ model และ data แยกจากกันได้ ทั้งยังเป็นถังสำหรับ Entity และ Aggregates
    • Modules เป็นการ grouping ของสิ่งต่างๆ ใน Bounded context ที่อาจจะมีหลาย module โดยไม่สัมพันธ์กัน
    • Event เป็นตัวแทนของการเปลี่ยนแปลงใดๆ ใน domain จากสถานะหนึ่งไปเป็นอีกสถานะหนึ่ง ปกติเขียนในรูป Noun + past-tense verb เช่น ClaimCreated, ClaimSettled เป็นต้น

The Monolith

ลักษณะของ software architecture ที่รวมทุก modules ไว้ใน project หรือ package เดียว เพื่อความง่ายในการเรียกใช้ function หรือ service ใน project โดยไม่ต้องแยก deploy ที่ต้องเรียกใช้งานผ่าน interface อย่างเช่น API อีกทั้งการส่งมอบงาน และ deploy ก็ง่ายเพราะ deploy ทั้ง package และการ reuse ในส่วนของ code ก็ทำได้สะดวกสบาย ถือเป็นหลักนิยมของการพัฒนา software ในยุคที่ผ่านมา จนกระทั้ง software ได้ถูกนำมาใช้เป็นบริการหลักของธุรกิจ ความต้องการใหม่ๆ ที่เพิ่มและแก้ไขตลอดเวลา รวมถึงการรองรับจำนวนผู้ใช้จำนวนมาก ทำให้รูปแบบการพัฒนาแบบเดิมเริ่มจะส่งผลในทางลบมากกว่า กล่าวคือ การเพิ่มทีมพัฒนาเข้าไปจะทำได้ยาก เพราะการวาง code ภาษาที่ใช้ จะรู้จักดีในเฉพาะทีมเท่านั้น แต่ละ module ที่มีการเรียกใช้งานเริ่มมีความซับซ้อน และต้อง share หรือรับงานที่มากขึ้น (overloaded) ความต้องการเพิ่มจำนวน process (scalability) ที่ต้องขยาย resource ทั้ง server การที่ทำให้ระบบทำงานได้อย่างต่อเนื่อง (availability) ด้วยประสิทธิภาพของการให้บริการที่ดีตลอดเวลา (reliability) รวมถึงการให้บริการได้แม้ในขณะที่ระบบเกิดปัญหา (Resiliency) การส่งมอบ software อย่างต่อเนื่อง (Continuous Delivery) โดยไม่ทำให้การบริการหยุดชะงัก ทำให้เกิดอัตราเร่งให้ต้องเปลี่ยนแปลงไปสู่ microservice architect

Forces

  • Developer หลายคนทำงานใน project เดียว
  • Developer ใหม่ของทีมสามารถเริ่มต้นทำงานได้อย่างรวดเร็ว
  • Application จะต้องง่ายในการทำความเข้าใจ และแก้ไข
  • ต้องการ apply continuous deployment practices
  • ความต้องการเรื่อง Scale up – Scalability, Availability และ Resiliency
  • ต้องการใช้ประโยชน์จาก technology ใหม่ใน project เช่น framework และ programming language

Solutions

  • สร้างหลายๆ module แล้ว pack ไว้ใน package เดียว เช่น WAR หรือ EAR
    • Deploy ทุกอย่างอยู่ในรูปแบบของ directory เดียว
    • อาจจะแยกหน้าที่ออกเป็นหลายๆ Tier (N-Tier Architechy)
    • ออกแบบเป็นลักษณะลำดับชั้น (Layered Architecture)

Resulting Context

  • การพัฒนา application มีรูปแบบที่ซับซ้อน (Complexity)
  • Web Server ทำงานหนัก ด้วยการทำงานทุกอย่างใน Server เดียว
  • การ deploy ส่ิงใหม่ๆ (continuous deliver) จะทำยากเพราะเกี่ยวพันกับหลาย module
  • การ scale out ใช้เวลามากเพราะต้องการ resource และ scale ทั้ง server
  • การแก้ไข เพื่อให้ใช้งานได้ไปก่อน (Technical debt) ไม่ได้เป็นแนวทางระยะยาว
  • ทำงานได้ใน scope อย่างไดอย่างหนึ่ง มีความยากในการต่อยอด