Puzzle Driven Development

Teerayut Hiruntaraporn
3 min readMar 16, 2021

--

CR: https://www.freepik.com/free-vector/people-putting-puzzle-pieces-together_5949654.htm#page=1&query=riddle&position=24

ส่วนตัวจำไม่ได้แล้วว่า ได้ยินคำนี้มาจากใคร เพราะพอได้ยินชื่อแล้ว ก็เลยเปิด Tab ใน Chrome ทิ้งไว้สักระยะนึงพึ่งจะมีเวลาอ่าน ก็ขอขอบคุณไว้ ณ ที่นี้ด้วยนะครับ แม้ว่าจะจำไม่ได้ก็ตาม -/\-

คือปกติแล้ว เวลาที่มันเป็น … Driven Development มันก็จะได้ประมาณว่า ใช้อะไรสักอย่างมาเป็นหัวลากในการพัฒนาซอฟท์แวร์ เช่น Test Driven Development ก็คือรูปแบบการพัฒนาซอฟท์แวร์ที่ใช้ Test มาเป็นตัวนำในเขียนโค้ด ถ้าอาจจะได้ฟีเจอร์อะไรก็ต้องเขียนเทสก่อน

ดังนั้น Puzzle Driven Development ก็จะเป็นการพัฒนาซอฟท์แวร์โดยใช้ Puzzle นำ พูดง่ายๆ ว่า ถ้าไม่มี Puzzle ก็จะไม่เขียน

แล้ว Puzzle คืออะไรกัน หลายคนจะนึกถึงเกมส์ Puzzle ซึ่งจะมีลักษณะของการแก้ปัญหาอะไรบางอย่างเพื่อให้ผ่านด่าน ดังนั้นจึงหมายความว่า ในการพัฒนาซอฟท์แวร์เราจะนำโดยใช้ปริศนาบางอย่าง ถ้าไม่มีปริศนาจะไม่ทำ ไปคิดมาก่อน

ซึ่งภาพรวมทั่วไปของของ PDD นั้น จะเป็นการแบ่งชิ้นงานออกเป็นส่วนเล็กๆ ผ่านปริศนาต่างๆ ซึ่งแต่ละชิ้นงานสามารถถูกนำเอาไปพัฒนาพร้อมๆกันได้

วิธีการนี้มักจะใช้กันใน กระบวนการพัฒนาซอฟท์แวร์ที่เรียกว่า Extreme Distributed Software Development หรือ XDSD ซึ่งจะเป็นการพัฒนาซอฟท์แวร์ในบริบทที่ทีมงานไม่ได้ทำอยู่ในสถานที่เดียวกัน อาจจะเป็นการ Remote ทำงานอยู่คนละซีกโลก ซึ่งไม่สามารถทำอะไรที่ Collaboration ได้เหมือนกับการมานั่งทำงานด้วยกันในบริษัท

แม้ว่าจะฟังดูเหมือนกับว่ามันดูไม่ค่อยจะเป็นไปได้ แต่ก็มีซอฟท์แวร์หลายตัวที่ถูกพัฒนาจากคนที่ไม่ได้อยู่ในที่เดียวกัน โดยเฉพาะกลุ่ม Opensource เช่น Apache , Nginx หรืออื่นๆ ซึ่งก็เรียกว่ามีหลักฐานเชิงประจักษ์ว่า วิธีการพัฒนาแบบรีโมตสามารถทำงานได้มีคุณภาพเช่นเดียวกัน

ตัวอย่างการคิดงานจาก Scenarios ตัวอย่าง

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

เคสของเขาคือการเขียนคลาส DbWriter ตัวหนึ่ง ซึ่งเขาก็จะอธิบายรายละเอียดมา ซึ่งตรงนี้สำคัญ รายละเอียดจะต้องละเอียดพอที่จะให้คนที่มาอ่านเข้าใจด้วย เพราะเราไม่ได้ทำคนเดียว

“Class DBWriter has to extend java.io.writer and save all incoming data to DB”

ข้อสังเกตอย่างหนึ่งคือ มีการกำหนดรายละเอียดที่แอบสูงนิดนึง เช่นปกติพวกเราทั่วไปก็จะไม่บอกว่า Class นี้จะ Extend อะไร ซึ่งตรงนี้เป็นสิ่งที่แสดงให้เห็นว่า เราจำเป็นต้องอธิบายเพื่อให้คนที่ถ้าจะมาทำต่อ จะอยู่ใน Blackbox ที่เป็นภาพเดียวกับเราได้นั่นเอง

นอกจากนี้ทางผู้เขียนก็ได้กำหนดอีกว่า ทั้งหมดนี้ใช้เวลาทำ 1 ชั่วโมง ใช่ครับ 1 ชั่วโมง ซึ่งจากการประเมินเบื้องต้นก็จะพอคิดได้ว่า ไม่น่าจะทันแน่นอน เพราะว่า งานใหญ่ และยังมีเรื่องที่ไม่รู้อีกหลายเรื่อง ไม่ว่าจะเป็น format ใช้อะไร, Schema ของ Database เป็นยังไง

ดังนั้นหลักการที่สำคัญคือ เราจะใช้ High-level Abstraction ในการเขียนก่อน แล้ว Seal รายละเอียดต่างๆ ลงใน Abstraction ครับ เช่นอย่างกรณีนี้เขาจะเขียนเทส เพื่อแสดง endpoint ของ library ก่อนเลยครับ

import org.junit.*;
import static org.mockito.Mockito.*;
public class DBWriterTest {
@Test
void testSavesDataIntoDatabase() throws Exception {
DataBridge mapper = mock(DataBridge.class);
Writer writer = new DBWriter(mapper);
try {
writer.write("hello, world!");
} finally {
writer.close();
}
verify(mapper).insert("hello, world!");
}
}

จากนั้นก็เติม Library ต่างๆ ให้สมบูรณ์ เพื่อให้งาน Test ผ่าน แต่จะไม่มีรายละเอียดใน detail ต่างๆ มากนัก

จุดสำคัญคือตรงนี้ครับ แน่นอนว่าตอนนี้เราจะมีเรื่องที่ยังไม่รู้อยู่ คือ mapper เขียนอะไรยังไงดี เขาจะเขียน Puzzle ไว้ เพื่อที่จะบอกว่า ปัญหาที่จะต้องแก้ต่อไปคืออะไรเช่น สำหรับตัว mapper เขาเขียนไว้ดังนี้ครับ

public interface DataBridge {
/**
* @todo #123 I assumed that a simple insert() method will be
* enough to insert data into the database. Maybe it's
* not true, and some sort of transaction support may be
* required. We should implement this interface and create
* an integration test with a database.
*/
void insert(String text) throws IOException;
}

โดยที่เขาจะใช้คำว่า @todo เป็น tag เพื่ออธิบาย Puzzle ว่าต้องทำอะไร context คืออะไร

หลังจากนั้นก็ทำการ merge task ที่เสร็จแล้ว และ puzzle เข้าไปใน Repository ครับ

ซึ่งตรงนี้ผลจากการ merge task อาจจะกลับมาด้วย puzzle ที่มากกว่า 1 ตัว ซึ่งตรง Puzzle ที่เพิ่มขึ้นก็จะสามารถส่งต่อให้ผู้อื่นทำต่อไปได้นั่นเอง

Puzzle จะมากขึ้นเมื่อลงรายละเอียดเพิ่ม

ข้อควรปฏิบัติ

ในการเขียนแนวทางนี้มีข้อแนะนำที่ควรปฏิบัติตามดังนี้ครับ:

  1. วางตำแหน่งของ tag @Todo ในตำแหน่งที่เป็น stub ในการเขียนโค้ดนั้นๆ
  2. Puzzle ต้องอยู่ใกล้ Code ซึ่งถ้าสมมติว่า มี 3 เคส ในแถวๆ นั้นก็จะต้องสร้าง 3 puzzles
  3. ต้องอธิบายให้รู้เรื่องที่สุดเท่าทีจะทำได้ สาเหตุก็คือเราจะส่ง Task ให้กับผู้อื่นจึงต้องเขียนให้คนอื่นเข้าใจจะได้ พัฒนาโค้ดให้ตรงกับที่เราคุยกัน

อุปกรณ์เสริมหลักสูตร

จากขั้นตอนที่กล่าวมาจะเป็นว่า puzzle จะขึ้นกับ Todo พอสมควร และมันก็เป็นไปได้ว่าเราจะสอดส่องไม่ถึงถ้า Code มันใหญ่มาก ดังนั้น ทางผู้คิดค้นจึงทำ Tool ขึ้นมาเป็น bot สำหรับไล่เก็บ Todo เหล่านี้ ให้ไปเป็น Ticket บน Github โดยมีชื่อ 0pdd

สิ่งที่ 0pdd ทำก็คือมันจะแสกน Code เพื่อหา tag todo แล้วนำข้อมูลตาม format ดัง กล่าว มาสร้างเป็น issue บน github ซึ่งเมื่อทำเป็น issue บน github แล้วก็สามารถทำการถกเถียงประเด็นเกี่ยวกับ issue ดังกล่าวได้บน Github ได้เลย ช่วยเรื่องการทำ Remote Collaboration อีกชั้นหนึ่ง

CR: https://0pdd.com

ความเห็นส่วนตัว

วันนี้ได้พยายามลองทำเบื้องต้น โดยการไล่ลง todo ไป ปัญหาที่สงสัยก็อาจจะมีเช่นว่า ด้วยเวลาที่สั้น เราอาจจะออกแบบได้ไม่ดี จะสามารถปรับแก้ไขท่าไหน แล้วมันจะ efficient กว่า คิดออกแบบไปก่อนแค่ไหน

ขณะที่เรื่องตัว bot นั้นเป็นอะไรที่น่าสนใจมาก นั่นแปลว่า จะทำให้เราสามารถ track ประเด็นที่ต้องทำได้โดยอัติโนมัติ น่าเสียดายที่ยังมีเฉพาะ github อยู่ อาจจะต้องไป modify เพื่อใช้กับตัวอื่น

ภาพรวมในการทำงาน บางครั้งแอบทำให้นึกถึง Publisher-Consumer บน Message Queue เหมือนกัน คือเราสร้าง task ใหม่ เอาไปวางใน Message Queue แล้วก็รอคนมารับงานไปทำ แต่ก็เป็นอะไรที่ compute สูงไม่ได้ เพราะเดี่ยวทรัพยากรจะโดนยึดนานเกินไป

ก็เดี๋ยวยังไงถ้าได้ลองถึงตัว 0pdd แล้วจะมารายงานต่ออีกทีครับ

ยังไงลองๆเล่นๆก่อนแล้วค่อยสรุปว่ามัน work ไม่ work ก็ไม่เสียหาย

ที่มา

  1. https://www.yegor256.com/2010/03/04/pdd.html

--

--

Teerayut Hiruntaraporn
Teerayut Hiruntaraporn

No responses yet