Style Specifics (รายละเอียดเฉพาะของสไตล์)
layer ใน architectural style นี้จะห่อหุ้มพื้นที่ความรับผิดชอบเชิงเทคนิคเฉพาะเจาะจงเอาไว้ แต่ตัว layer เองก็อาจแสดงคุณลักษณะอื่น ๆ ได้ด้วย
Layers of Isolation (ระดับการแยกตัวของ Layer)
แต่ละ layer สามารถเป็นได้ทั้งแบบ closed หรือ open ถ้า layer หนึ่งเป็น closed เมื่อ request เคลื่อนที่จาก layer บนสุดลงไปยัง layer ล่างสุด request นั้นจะข้าม layer ใดไปไม่ได้เลย มันต้องผ่าน layer ที่อยู่ถัดลงไปทันทีก่อนจะไปยัง layer ถัดไป (ดู Figure 10-3 ) ตัวอย่างเช่น ใน architecture ที่ทุก layer เป็น closed request ที่เริ่มต้นจาก Presentation layer จะต้องผ่าน Business layer ก่อน แล้วจึงไปยัง Persistence layer ก่อนที่จะไปถึง Database layer ในที่สุด
Figure 10-3. Closed layer ภายใน layered architecture
สังเกตว่าใน Figure 10-3 จะเร็วและง่ายกว่ามากถ้า Presentation layer เข้าถึงฐานข้อมูลได้โดยตรงสำหรับ request การดึงข้อมูลง่าย ๆ โดยข้าม layer ที่ไม่จำเป็นไป (สิ่งที่เคยรู้จักกันในช่วงต้นทศวรรษ 2000 ในชื่อ pattern Fast-Lane Reader ) เพื่อให้สิ่งนี้เกิดขึ้นได้ Business layer และ Persistence layer จะต้องเป็น open เพื่อให้ request สามารถข้าม layer อื่นได้ แล้วแบบไหนดีกว่ากัน—open layer หรือ closed layer? คำตอบของคำถามนี้อยู่ที่แนวคิดสำคัญที่เรียกว่า layers of isolation
แนวคิด layers of isolation หมายความว่าการเปลี่ยนแปลงที่เกิดขึ้นใน layer หนึ่งของ architecture โดยทั่วไปจะไม่ส่งผลกระทบต่อ component ใน layer อื่น ตราบใดที่ contract ระหว่าง layer เหล่านั้นยังไม่เปลี่ยนแปลง แต่ละ layer จะเป็นอิสระจาก layer อื่น โดยแทบไม่รู้หรือไม่รู้เลยเกี่ยวกับการทำงานภายในของกันและกัน อย่างไรก็ตาม เพื่อรองรับ layers of isolation layer ที่เกี่ยวข้องกับ flow หลักของ request จะต้องเป็น closed ถ้า Presentation layer สามารถเข้าถึง Persistence layer ได้โดยตรง การเปลี่ยนแปลงใน Persistence layer จะส่งผลกระทบต่อทั้ง Business layer และ Presentation layer ทำให้เกิดแอปพลิเคชันที่ coupled แน่นมาก โดยมี layer interdependency ระหว่าง component สิ่งนี้ทำให้ layered architecture เปราะบางมาก รวมถึงเปลี่ยนแปลงได้ยากและมีค่าใช้จ่ายสูง
การใช้ layers of isolation ยังทำให้สามารถเปลี่ยน layer ใด ๆ ใน architecture ได้โดยไม่ส่งผลกระทบต่อ layer อื่น (โดยสมมติว่ามี contract ที่ชัดเจนและใช้ pattern Business Delegate ) 1 ตัวอย่างเช่น คุณสามารถใช้ layers of isolation เพื่อแทนที่ UI framework เก่าของคุณด้วยตัวใหม่ ทั้งหมดภายใน Presentation layer
Adding Layers (การเพิ่ม Layer)
แม้ว่า closed layer จะช่วยเรื่อง layers of isolation และช่วยแยกการเปลี่ยนแปลงออกจากกัน แต่ก็มีบางกรณีที่การให้ layer บางตัวเป็น open นั้นสมเหตุสมผล ตัวอย่างเช่น สมมติว่า Business layer ใน layered architecture ของคุณมี shared object ที่มีฟังก์ชันการทำงานร่วมกันสำหรับ business component (เช่น utility class สำหรับวันที่และสตริง, class สำหรับ auditing, class สำหรับ logging และอื่น ๆ) คุณตัดสินใจเชิงสถาปัตยกรรมที่จำกัดไม่ให้ Presentation layer ใช้ shared business object เหล่านี้ ข้อจำกัดนี้แสดงอยู่ใน Figure 10-4 โดยมีเส้นประวิ่งจาก presentation component ไปยัง shared business object ใน Business layer สถานการณ์นี้ควบคุมและกำกับดูแลได้ยาก เพราะ ในทาง architecture Presentation layer สามารถเข้าถึง Business layer ได้ ซึ่งหมายถึงสามารถเข้าถึง shared object ภายใน layer นั้นได้ด้วย
Figure 10-4. Shared object ภายใน Business layer
วิธีหนึ่งในการบังคับใช้ข้อจำกัดนี้ในทาง architecture คือการเพิ่ม Services layer ใหม่ที่มี shared business object ทั้งหมดอยู่ (ดู Figure 10-5 ) การเพิ่ม layer ใหม่นี้จะจำกัดในทาง architecture ไม่ให้ Presentation layer เข้าถึง shared business object ได้ เพราะ Business layer เป็น closed อย่างไรก็ตาม คุณต้องกำหนดให้ Services layer ใหม่นี้เป็น open ไม่เช่นนั้น Business layer จะถูกบังคับให้ต้องผ่าน Services layer เพื่อเข้าถึง Persistence layer การกำหนดให้ Services layer เป็น open ทำให้ Business layer สามารถเข้าถึง layer นั้นได้ (ตามที่ลูกศรทึบระบุ) หรือข้ามมันไปยัง layer ถัดไปด้านล่างได้ (ตามที่ลูกศรประระบุ)
Figure 10-5. การเพิ่ม Services layer ใหม่เข้าไปใน architecture
การใช้แนวคิดเรื่อง open และ closed layer ช่วยกำหนดความสัมพันธ์ระหว่าง architecture layer กับ request flow นอกจากนี้ยังให้ข้อมูลและแนวทางที่จำเป็นแก่นักพัฒนาเพื่อให้เข้าใจข้อจำกัดในการเข้าถึง layer ภายใน architecture การไม่บันทึกหรือไม่สื่อสารอย่างเหมาะสมว่า layer ใดใน architecture เป็น open หรือ closed (และเพราะอะไร) มักจะส่งผลให้เกิด architecture ที่ coupled แน่นและเปราะบาง ซึ่งทดสอบ บำรุงรักษา และ deploy ได้ยากมาก
layered architecture ทุกแบบจะมีอย่างน้อยบางสถานการณ์ที่กลายเป็น antipattern Architecture Sinkhole antipattern นี้เกิดขึ้นเมื่อ request ถูกส่งผ่านจาก layer หนึ่งไปยังอีก layer หนึ่งเฉย ๆ โดยไม่มีการรัน business logic ใด ๆ เลย ตัวอย่างเช่น สมมติว่า Presentation layer ตอบสนองต่อ request ง่าย ๆ ของผู้ใช้ในการดึงข้อมูลลูกค้าพื้นฐาน (เช่น ชื่อและที่อยู่) Presentation layer ส่ง request ไปยัง Business layer ซึ่งไม่ทำอะไรนอกจากส่ง request ต่อไปยัง Rules layer ซึ่งก็ไม่ทำอะไรนอกจากส่งต่อไปยัง Persistence layer ซึ่งจากนั้นก็เรียก SQL แบบง่าย ๆ ไปยัง Database layer เพื่อดึงข้อมูลลูกค้า จากนั้นข้อมูลจะถูกส่งกลับขึ้นมาตลอดทาง โดยไม่มีการประมวลผลหรือ logic เพิ่มเติมเพื่อรวม คำนวณ ใช้กฎ หรือแปลงข้อมูลใด ๆ เลย สิ่งนี้ส่งผลให้เกิดการสร้าง object และการประมวลผลที่ไม่จำเป็น ซึ่งทำให้สิ้นเปลืองทั้งหน่วยความจำและ performance
กุญแจสำคัญในการพิจารณาว่า antipattern นี้กำลังเกิดขึ้นอยู่หรือไม่ คือการวิเคราะห์เปอร์เซ็นต์ของ request ที่ตกอยู่ในหมวดหมู่นี้ กฎ 80-20 มักเป็นแนวทางปฏิบัติที่ดีให้ยึดถือ ตัวอย่างเช่น ถ้ามีแค่ 20% ของ request ที่เป็น sinkhole ก็ยังถือว่ายอมรับได้ แต่ถ้าเป็น 80% นั่นเป็นสัญญาณที่ดีว่า layered architecture ไม่ใช่ architecture style ที่ถูกต้องสำหรับ problem domain นั้น อีกวิธีหนึ่งในการแก้ไข Architecture Sinkhole antipattern คือการทำให้ทุก layer ใน architecture เป็น open ทั้งหมด—โดยตระหนักว่า trade-off คือความยากลำบากที่เพิ่มขึ้นในการจัดการการเปลี่ยนแปลง .