Style Specifics (รายละเอียดเฉพาะของ Style)

แม้ว่าการ implement pipeline architecture ส่วนใหญ่จะเป็นแบบ monolithic แต่ก็สามารถ deploy แต่ละ filter (หรือกลุ่มของ filter) เป็น service แยกกันได้ ทำให้เกิด distributed architecture ที่มีการเรียกระยะไกล (remote call) แบบ synchronous หรือ asynchronous ไปยังแต่ละ service ไม่ว่า deployment topology จะเป็นแบบใด architecture นี้ประกอบด้วย architectural component เพียงสองอย่างเท่านั้น คือ filter และ pipe ซึ่งเราจะอธิบายรายละเอียดในหัวข้อถัดไป

Filters (Filter)

Filter คือชิ้นส่วนของฟังก์ชันการทำงานที่เป็นอิสระจาก filter อื่น ๆ โดยทั่วไปจะเป็น stateless และควรทำหน้าที่เพียงงานเดียวเท่านั้น งานที่ซับซ้อน (composite task) มักถูกจัดการด้วยลำดับของ filter หลายตัวมากกว่าที่จะใช้ filter เดียว

เนื่องจาก filter สามารถ implement ได้ด้วย class file มากกว่าหนึ่งไฟล์ จึงถือว่า filter เป็น component ของ architecture (ดู Chapter 8 ) แม้ว่า filter หนึ่งจะเรียบง่ายและ implement ด้วย class file เดียว มันก็ยังถือเป็น component อยู่ดี

pipeline architecture style มี filter อยู่สี่ประเภท:

Producer

producer filter คือจุดเริ่มต้นของ process และเป็น outbound เท่านั้น บางครั้งก็เรียกว่า source ทั้ง user interface และคำขอจากภายนอกที่เข้าสู่ระบบต่างก็เป็นตัวอย่างของ producer filter

Transformer

transformer filter รับ input เข้ามา อาจทำการแปลงข้อมูล (transformation) กับข้อมูลบางส่วนหรือทั้งหมด แล้วส่งต่อข้อมูลไปยัง outbound pipe นักพัฒนาสาย functional programming จะจำฟีเจอร์นี้ได้ในชื่อ map transformer filter อาจใช้เพิ่มข้อมูล แปลงข้อมูล หรือคำนวณบางอย่างก็ได้

Tester

tester filter รับ input เข้ามา ทดสอบตาม criteria อย่างน้อยหนึ่งข้อ แล้วอาจสร้าง output ตามผลการทดสอบนั้น นักพัฒนาสาย functional จะเห็นว่าคล้ายกับ reduce tester filter อาจใช้ตรวจสอบว่าข้อมูลทั้งหมดถูกต้องและกรอกอย่างถูกต้อง หรือทำหน้าที่เป็น switch เพื่อตัดสินว่าควรดำเนินการต่อหรือไม่ (เช่น “อย่าส่งข้อมูลไปยัง filter ถัดไปถ้ายอดสั่งซื้อต่ำกว่าห้าดอลลาร์”)

Consumer

consumer filter คือจุดสิ้นสุดของ pipeline flow บางครั้งก็ persist ผลลัพธ์สุดท้ายของ pipeline process ลงฐานข้อมูล หรือแสดงผลลัพธ์สุดท้ายบนหน้าจอ UI

ธรรมชาติแบบทางเดียว (unidirectional) และความเรียบง่ายของ pipe และ filter ส่งเสริมการนำกลับมาใช้ใหม่แบบ compositional นักพัฒนาจำนวนมากค้นพบความสามารถนี้ผ่านการใช้ shell เรื่องราวชื่อดังจากบล็อก “More Shell, Less Egg” แสดงให้เห็นว่า abstraction เหล่านี้ทรงพลังเพียงใด Donald Knuth ได้รับมอบหมายให้เขียนโปรแกรมแก้ปัญหาการจัดการข้อความนี้: อ่านไฟล์ข้อความ หาคำที่ใช้บ่อยที่สุด n คำ แล้วพิมพ์รายการคำเหล่านั้นเรียงตามความถี่ เขาเขียนโปรแกรมยาวกว่า 10 หน้าด้วยภาษา Pascal พร้อมออกแบบ (และเขียนเอกสารประกอบ) อัลกอริทึมใหม่ไปพร้อมกัน จากนั้น Doug McIlroy ก็สาธิต shell script ที่สั้นพอจะใส่ลงในโพสต์โซเชียลมีเดียได้สบาย ๆ และแก้ปัญหาได้อย่างสวยงาม:

        tr -cs A-Za-z '\n' |
        tr A-Z a-z |
        sort |
        uniq -c |
        sort -rn |
        sed ${1}q

แม้แต่ผู้ออกแบบ Unix shell เองก็ยังต้องแปลกใจกับวิธีที่นักพัฒนาคิดค้นการใช้งาน composite abstraction ที่เรียบง่ายแต่ทรงพลังเหล่านี้

Pipes (Pipe)

Pipe ใน architecture นี้ทำหน้าที่เป็นช่องทางการสื่อสารระหว่าง filter แต่ละ pipe มักเป็นแบบทางเดียวและ point-to-point คือรับ input จากแหล่งหนึ่งแล้วส่ง output ไปยังอีกแหล่งหนึ่ง payload ของมันเป็นข้อมูลรูปแบบใดก็ได้ แต่สถาปนิกมักเลือกใช้ข้อมูลขนาดเล็กเพื่อให้ได้ performance สูง

ถ้า filter (หรือกลุ่มของ filter) ถูก deploy เป็น service แยกในลักษณะ distributed pipe จะทำการเรียกระยะไกลแบบทางเดียวโดยใช้ REST, messaging, streaming หรือ remote communication protocol อื่น ๆ ไม่ว่า deployment topology จะเป็น monolithic หรือ distributed pipe ก็สามารถเป็นได้ทั้งแบบ synchronous หรือ asynchronous ใน monolithic deployment สถาปนิกจะใช้ thread หรือ embedded messaging สำหรับการสื่อสารแบบ asynchronous ไปยัง filter