การสลายตัวตามลำดับชั้น
คุณไม่ควรเริ่มเขียนชั้นเรียนสำหรับใบสมัครของคุณทันที ก่อนอื่นต้องออกแบบ การออกแบบควรจบลงด้วยสถาปัตยกรรมที่รอบคอบ และเพื่อให้ได้สถาปัตยกรรมนี้ คุณต้องแยกย่อยระบบอย่างสม่ำเสมอ
การสลายตัวต้องดำเนินการตามลำดับขั้น - อันดับแรก ระบบจะแบ่งออกเป็นโมดูลการทำงานขนาดใหญ่ / ระบบย่อยที่อธิบายการทำงานในรูปแบบทั่วไป จากนั้นโมดูลผลลัพธ์จะได้รับการวิเคราะห์โดยละเอียดยิ่งขึ้นและแบ่งออกเป็นโมดูลย่อยหรือวัตถุ
ก่อนเลือกอ็อบเจกต์ ให้แบ่งระบบออกเป็นบล็อกความหมายพื้นฐาน อย่างน้อยก็ทางจิตใจ ในแอปพลิเคชันขนาดเล็กมักทำได้ง่ายมาก: ลำดับชั้นสองสามระดับก็เพียงพอแล้วเนื่องจากระบบแบ่งออกเป็นระบบย่อย / แพ็คเกจก่อนและแพ็คเกจจะแบ่งออกเป็นคลาส
ความคิดนี้ไม่สำคัญอย่างที่คิด ตัวอย่างเช่น อะไรคือสาระสำคัญของ "รูปแบบสถาปัตยกรรม" ทั่วไปเช่น Model-View-Controller (MVC)
มันคือทั้งหมดที่เกี่ยวกับ การแยก งานนำเสนอออกจากตรรกะทางธุรกิจ ประการแรก แอปพลิเคชันผู้ใช้ใด ๆ จะแบ่งออกเป็นสองโมดูล - โมดูลหนึ่งมีหน้าที่รับผิดชอบในการนำตรรกะทางธุรกิจไปใช้เอง (แบบจำลอง) และโมดูลที่สองมีหน้าที่รับผิดชอบในการโต้ตอบกับผู้ใช้ (ส่วนต่อประสานผู้ใช้หรือมุมมอง)
จากนั้นปรากฎว่าโมดูลต้องมีการโต้ตอบด้วยเหตุนี้พวกเขาจึงเพิ่มคอนโทรลเลอร์ซึ่งมีหน้าที่จัดการการโต้ตอบของโมดูล นอกจากนี้ใน MVC เวอร์ชันมือถือ (คลาสสิก) รูปแบบการสังเกตการณ์จะถูกเพิ่มเข้าไปเพื่อให้ View สามารถรับเหตุการณ์จากโมเดลและเปลี่ยนข้อมูลที่แสดงแบบเรียลไทม์
โมดูลระดับบนสุดทั่วไปที่ได้รับจากการแบ่งส่วนแรกของระบบออกเป็นส่วนประกอบที่ใหญ่ที่สุด ได้แก่:
- ตรรกะทางธุรกิจ
- หน้าจอผู้ใช้;
- ฐานข้อมูล;
- ระบบข้อความ;
- คอนเทนเนอร์วัตถุ
การแบ่งครั้งแรกมักจะแบ่งแอปพลิเคชันทั้งหมดออกเป็น 2-7 ส่วน (สูงสุด 10 ส่วน) หากเราแบ่งออกเป็นส่วน ๆ มากขึ้นก็จะมีความปรารถนาที่จะจัดกลุ่มและเราจะได้โมดูลระดับบนสุด 2-7 โมดูลอีกครั้ง
การสลายตัวตามหน้าที่
การแบ่งออกเป็นโมดูล/ระบบย่อยทำได้ดีที่สุดโดยยึดตามงานที่ระบบแก้ไข ภารกิจหลักแบ่งออกเป็นงานย่อยที่เป็นส่วนประกอบ ซึ่งสามารถแก้ไข/ดำเนินการได้ด้วยตนเอง โดยไม่ขึ้นต่อกัน
แต่ละโมดูลควรรับผิดชอบในการแก้ปัญหางานย่อยและทำหน้าที่ที่ เกี่ยวข้อง นอกเหนือจากวัตถุประสงค์การทำงานแล้ว โมดูลยังมีลักษณะเฉพาะด้วยชุดข้อมูลที่จำเป็นสำหรับการทำงาน นั่นคือ:
โมดูล = ฟังก์ชัน + ข้อมูลที่จำเป็นในการดำเนินการ
หากการสลายตัวเป็นโมดูลทำอย่างถูกต้อง การโต้ตอบกับโมดูลอื่น (รับผิดชอบฟังก์ชั่นอื่น) จะน้อยที่สุด อาจเป็นได้ แต่ไม่ควรมีความสำคัญต่อโมดูลของคุณ
โมดูลไม่ใช่ส่วนของรหัสตามอำเภอใจ แต่เป็นหน่วยโปรแกรม (โปรแกรมย่อย) ที่มีความหมายตามหน้าที่และสมบูรณ์ซึ่งแยกจากกันซึ่งจัดเตรียมวิธีแก้ปัญหาให้กับงานบางอย่าง และตามหลักแล้ว สามารถทำงานอย่างอิสระหรือในสภาพแวดล้อมอื่นและนำมาใช้ซ้ำได้ โมดูลควรเป็น "ความสมบูรณ์ที่สามารถเป็นอิสระจากพฤติกรรมและการพัฒนา" (คริสโตเฟอร์ อเล็กซานเดอร์)
ดังนั้น การสลายตัวที่มีความสามารถจึงขึ้นอยู่กับ การวิเคราะห์ฟังก์ชันของระบบและข้อมูลที่จำเป็นในการทำหน้าที่เหล่านี้เป็นอันดับแรก ฟังก์ชันในกรณีนี้ไม่ใช่ฟังก์ชันคลาสและโมดูล เนื่องจากไม่ใช่ออบเจกต์ หากคุณมีเพียงสองคลาสในโมดูล แสดงว่าคุณทำเกินค่านั้นไปแล้ว
การเชื่อมต่อที่แข็งแกร่งและอ่อนแอ
มันสำคัญมากที่จะไม่หักโหมกับการทำให้เป็นโมดูล หากคุณให้แอปพลิเคชัน Spring Bean แบบเสาหินแก่ผู้เริ่มต้นและขอให้เขาแบ่งออกเป็นโมดูล จากนั้นเขาจะแยก Spring Bean แต่ละอันออกเป็นโมดูลแยกต่างหากและพิจารณาว่างานของเขาเสร็จสิ้นแล้ว แต่มันไม่ใช่
เกณฑ์หลักสำหรับคุณภาพของการสลายตัวคือวิธีการที่โมดูลมุ่งเน้นไปที่การแก้ปัญหาและเป็นอิสระต่อกัน
โดยปกติจะมีการกำหนดดังนี้: "โมดูลที่ได้รับจากการสลายตัวควรเชื่อมต่อกันภายในให้มากที่สุด (การเกาะกันภายในสูง) และเชื่อมต่อระหว่างกันน้อยที่สุด (การเชื่อมต่อภายนอกต่ำ)"
การทำงานร่วมกันสูง การทำงานร่วมกันสูงหรือ "การทำงานร่วมกัน" ภายในโมดูล บ่งชี้ว่าโมดูลมุ่งเน้นไปที่การแก้ปัญหาที่แคบเพียงปัญหาเดียว และไม่มีส่วนร่วมในการปฏิบัติหน้าที่ที่แตกต่างกันหรือความรับผิดชอบที่ไม่เกี่ยวข้อง
การทำงานร่วมกันกำหนดลักษณะระดับของงานที่ดำเนินการโดยโมดูลที่เกี่ยวข้องกัน
ผลที่ตามมาของ High Cohesion คือ Single Responsibility Principleซึ่งเป็นหลักการแรกในห้าหลักการ SOLIDซึ่งวัตถุ/โมดูลใดๆ ควรมีความรับผิดชอบเพียงข้อเดียว และไม่ควรมีเหตุผลมากกว่าหนึ่งข้อในการเปลี่ยนแปลง
การมีเพศสัมพันธ์ต่ำการมีเพศสัมพันธ์แบบหลวม หมายความว่าโมดูลที่ระบบถูกแบ่งออก ถ้าเป็นไปได้ ควรเป็นอิสระหรือเชื่อมต่อกันอย่างหลวมๆ พวกเขาควรจะสามารถโต้ตอบได้ แต่ในขณะเดียวกันก็รู้เรื่องซึ่งกันและกันให้น้อยที่สุด
แต่ละโมดูลไม่จำเป็นต้องรู้ว่าโมดูลอื่นทำงานอย่างไร เขียนด้วยภาษาอะไร และทำงานอย่างไร บ่อยครั้งในการจัดระเบียบการโต้ตอบของโมดูลดังกล่าวจะใช้คอนเทนเนอร์บางตัวซึ่งโหลดโมดูลเหล่านี้
ด้วยการออกแบบที่เหมาะสม หากคุณเปลี่ยนโมดูลหนึ่ง คุณจะไม่ต้องแก้ไขโมดูลอื่น มิฉะนั้นการเปลี่ยนแปลงเหล่านี้จะน้อยที่สุด ยิ่งการเชื่อมต่อหลวมเท่าใด ก็ยิ่งเขียน/เข้าใจ/ขยาย/ซ่อมแซมโปรแกรมได้ง่ายขึ้นเท่านั้น
เชื่อว่าโมดูลที่ออกแบบอย่างดีควรมีคุณสมบัติดังต่อไปนี้:
- ความสมบูรณ์ของฟังก์ชันและความสมบูรณ์ - แต่ละโมดูลใช้ฟังก์ชันเดียว แต่ใช้งานได้ดีและสมบูรณ์ โมดูลจะดำเนินการชุดเต็มของการดำเนินการอย่างอิสระเพื่อใช้งานฟังก์ชันของตน
- หนึ่งอินพุตและหนึ่งเอาต์พุต - ที่อินพุต โมดูลโปรแกรมจะได้รับข้อมูลเริ่มต้นบางชุด ดำเนินการประมวลผลที่มีความหมายและส่งคืนข้อมูลผลลัพธ์หนึ่งชุด นั่นคือหลักการ IPO มาตรฐานถูกนำมาใช้ - อินพุต -\u003e กระบวนการ -\u003e เอาต์พุต
- ความเป็นอิสระทางตรรกะ - ผลลัพธ์ของการทำงานของโมดูลโปรแกรมขึ้นอยู่กับข้อมูลเริ่มต้นเท่านั้น แต่ไม่ได้ขึ้นอยู่กับการทำงานของโมดูลอื่น
- การเชื่อมโยงข้อมูลที่อ่อนแอกับโมดูลอื่น - การแลกเปลี่ยนข้อมูลระหว่างโมดูลควรลดลงหากเป็นไปได้
เป็นเรื่องยากมากสำหรับผู้เริ่มต้นที่จะเข้าใจวิธีลดการเชื่อมต่อของโมดูลให้มากยิ่งขึ้น ความรู้นี้ส่วนหนึ่งมาจากประสบการณ์ส่วนหนึ่ง - หลังจากอ่านหนังสือสมาร์ท แต่วิธีที่ดีที่สุดคือการวิเคราะห์สถาปัตยกรรมของแอปพลิเคชันที่มีอยู่
องค์ประกอบแทนการสืบทอด
การสลายตัวที่มีความสามารถเป็นศิลปะประเภทหนึ่งและเป็นงานยากสำหรับโปรแกรมเมอร์ส่วนใหญ่ ความเรียบง่ายนั้นหลอกลวงที่นี่ และความผิดพลาดนั้นมีค่าใช้จ่ายสูง
มันเกิดขึ้นที่โมดูลเฉพาะนั้นเชื่อมต่อกันอย่างมากและไม่สามารถพัฒนาได้อย่างอิสระ หรือไม่ชัดเจนว่าแต่ละคนมีหน้าที่รับผิดชอบอะไรบ้าง หากคุณพบปัญหาที่คล้ายกัน เป็นไปได้มากว่าการแบ่งพาร์ติชันเป็นโมดูลนั้นทำไม่ถูกต้อง
ควรมีความชัดเจนเสมอว่าแต่ละโมดูลมีบทบาทอย่างไร เกณฑ์ที่น่าเชื่อถือที่สุดที่การสลายตัวทำอย่างถูกต้องคือถ้าโมดูลเป็นรูทีนย่อยที่เป็นอิสระและมีค่าที่สามารถใช้ในการแยกออกจากส่วนที่เหลือของแอปพลิเคชัน (และดังนั้นจึงสามารถนำมาใช้ซ้ำได้)
เมื่อแยกย่อยระบบ ขอแนะนำให้ตรวจสอบคุณภาพโดยถามตัวเองว่า "แต่ละโมดูลทำหน้าที่อะไร" "โมดูลทดสอบได้ง่ายเพียงใด" "เป็นไปได้ไหมที่จะใช้โมดูลด้วยตัวเอง หรือในสภาพแวดล้อมอื่น" ส่งผลกระทบต่อผู้อื่นหรือไม่?
คุณต้องพยายามทำให้โมดูลเป็นอิสระ มากที่สุดเท่าที่จะเป็นไป ได้ ดังที่ได้กล่าวไว้ก่อนหน้านี้ นี่เป็นพารามิเตอร์หลักสำหรับการแยกส่วนที่เหมาะสม ดังนั้นจึงต้องดำเนินการในลักษณะที่โมดูลนั้นพึ่งพาอาศัยกันในขั้นต้นอย่างอ่อนแอ ถ้าคุณทำสำเร็จ คุณก็เก่งมาก
ถ้าไม่เช่นนั้นทั้งหมดจะไม่สูญหายไปเช่นกัน มีเทคนิคและรูปแบบพิเศษหลายอย่างที่ช่วยให้คุณสามารถย่อและลดความเชื่อมโยงระหว่างระบบย่อยได้อีก ตัวอย่างเช่น ในกรณีของ MVC รูปแบบผู้สังเกตการณ์ถูกใช้เพื่อจุดประสงค์นี้ แต่มีวิธีแก้ไขอื่นๆ ที่เป็นไปได้
อาจกล่าวได้ว่าเทคนิคในการแยกส่วนเป็น "ชุดเครื่องมือของสถาปนิก" หลัก จำเป็นต้องเข้าใจว่าเรากำลังพูดถึงระบบย่อยทั้งหมดและจำเป็นต้องลดการเชื่อมต่อในทุกระดับของลำดับชั้นนั่นคือไม่เพียง แต่ระหว่างคลาสเท่านั้น แต่ยังรวมถึงระหว่างโมดูลในแต่ละระดับลำดับชั้นด้วย
GO TO FULL VERSION