23 รูปแบบการออกแบบบทที่ 19: รูปแบบห่วงโซ่ความรับผิดชอบของ Java
คำจำกัดความ: อนุญาตให้วัตถุหลายชิ้นมีโอกาสประมวลผลคำขอดังนั้นจึงหลีกเลี่ยงความสัมพันธ์ระหว่างผู้ส่งและผู้รับของคำขอ เชื่อมต่อวัตถุเหล่านี้เข้ากับโซ่และส่งคำขอไปตามห่วงโซ่จนกว่าวัตถุจะประมวลผล
ประเภท: รูปแบบพฤติกรรม
แผนภาพชั้นเรียน:
ก่อนอื่นให้ดูที่รหัสชิ้นหนึ่ง:
การทดสอบโมฆะสาธารณะ (int i คำขอ) {ถ้า (i == 1) {handler1.Response (คำขอ); } อื่นถ้า (i == 2) {handler2.Response (คำขอ); } อื่นถ้า (i == 3) {handler3.Response (คำขอ); } อื่นถ้า (i == 4) {handler4.Response (คำขอ); } else {handler5.Response (คำขอ); -ตรรกะทางธุรกิจของรหัสมีดังนี้: วิธีการมีสองพารามิเตอร์: จำนวนเต็ม I และคำขอคำขอ ตามค่าของฉันใครจะจัดการกับคำขอถ้าฉัน == 1 มันจะได้รับการจัดการโดย Handler1 ถ้า i == 2 มันจะได้รับการจัดการโดย Handler2 และอื่น ๆ
ในการเขียนโปรแกรมวิธีการประมวลผลธุรกิจประเภทนี้เป็นเรื่องธรรมดามาก คลาสทั้งหมดที่กระบวนการร้องขอรวมถึงถ้า ... อื่น ... งบการตัดสินตามเงื่อนไขที่เชื่อมต่อเป็นห่วงโซ่ความรับผิดชอบในการประมวลผลคำขอ ฉันเชื่อว่าทุกคนมักใช้มัน ข้อดีของวิธีนี้คือมันเป็นเรื่องง่ายง่ายและชัดเจนและค่อนข้างง่ายต่อการบำรุงรักษา แต่วิธีนี้ก็มีอาการปวดหัวหลายอย่างด้วย:
Code Bloated: ในแอปพลิเคชันจริงเงื่อนไขการตัดสินมักจะไม่ง่ายนักที่จะพิจารณาว่าเป็น 1 หรือ 2 มันอาจต้องใช้การคำนวณที่ซับซ้อนหรืออาจสอบถามฐานข้อมูล ฯลฯ นี้จะมีรหัสเพิ่มเติมมากมาย หากมีเงื่อนไขการตัดสินมากมายถ้า ... อื่น ... คำแถลงนั้นเป็นไปไม่ได้ที่จะอ่าน
ระดับการมีเพศสัมพันธ์สูง: หากเราต้องการเพิ่มคลาสที่ดำเนินการตามคำขอเราจะต้องเพิ่มอย่างอื่นหากเงื่อนไขการตัดสิน; นอกจากนี้ลำดับของเงื่อนไขนี้ยังเขียนถึงคนตาย หากเราต้องการเปลี่ยนคำสั่งซื้อเราสามารถแก้ไขคำสั่งเงื่อนไขนี้ได้เท่านั้น
เนื่องจากเราเข้าใจข้อบกพร่องแล้วเราจึงต้องหาวิธีแก้ปัญหาพวกเขา ตรรกะทางธุรกิจของสถานการณ์นี้ง่ายมาก: หากเป็นไปตามเงื่อนไข 1 มันจะถูกประมวลผลโดย Handler1 และหากไม่ตรงกับมันจะถูกส่งผ่าน หากพบกับเงื่อนไข 2 มันจะถูกประมวลผลโดย Handler2 และหากไม่ตรงกับมันจะถูกส่งผ่านลงไปจนถึงจุดสิ้นสุดของเงื่อนไข ในความเป็นจริงวิธีการปรับปรุงนั้นง่ายมากเช่นกันซึ่งก็คือการทำให้ส่วนหนึ่งของเงื่อนไขการตัดสินลงในคลาสการประมวลผล นี่คือหลักการของรูปแบบการเชื่อมต่อความรับผิดชอบ
โครงสร้างของห่วงโซ่ของแบบจำลองความรับผิดชอบ
แผนภาพคลาสของรูปแบบความรับผิดชอบนั้นง่ายมากมันประกอบด้วยคลาสที่ผ่านการประมวลผลแบบนามธรรมและชุดของคลาสการใช้งาน:
บทคัดย่อคลาสการประมวลผล: คลาสการประมวลผลนามธรรมส่วนใหญ่รวมถึงตัวแปรสมาชิก Nexthandler ชี้ไปที่คลาสการประมวลผลถัดไปและวิธีการจัดการที่จัดการกับคำขอ แนวคิดหลักของวิธี HandRequest คือหากเป็นไปตามเงื่อนไขการประมวลผลคลาสการประมวลผลนี้จะถูกประมวลผลมิฉะนั้นจะถูกประมวลผลโดย NexThandler
คลาสการประมวลผลเฉพาะ: คลาสการประมวลผลเฉพาะส่วนใหญ่ใช้ตรรกะการประมวลผลเฉพาะและเงื่อนไขที่ใช้สำหรับการประมวลผล
หลังจากทำความเข้าใจแนวคิดทั่วไปของแบบจำลองห่วงโซ่ความรับผิดชอบมันจะง่ายกว่าที่จะเข้าใจเมื่อดูที่รหัส:
ระดับคลาส {ระดับ int ส่วนตัว = 0; ระดับสาธารณะ (ระดับ int) {this.level = ระดับ; - บูลีนสาธารณะด้านบน (ระดับระดับ) {ถ้า (this.level> = level.level) {return true; } return false; }} คำขอคลาส {ระดับระดับ; คำขอสาธารณะ (ระดับระดับ) {this.level = ระดับ; } ระดับสาธารณะ getLevel () {ระดับคืน; }} การตอบสนองของคลาส {} ตัวจัดการคลาสบทคัดย่อ {handler ส่วนตัว nexthandler; การตอบสนองครั้งสุดท้ายสาธารณะ handlerequest (คำขอคำขอ) {ตอบสนองการตอบกลับ = null; if (this.getHandlerLevel (). ด้านบน (request.getLevel ())) {response = this.Response (คำขอ); } else {ถ้า (this.nexthandler! = null) {this.nexthandler.handlerequest (คำขอ); } else {system.out.println ("----------"); }} การตอบกลับส่งคืน; } โมฆะสาธารณะ Setnexthandler (Handler Handler) {this.nexthandler = Handler; } การป้องกันระดับนามธรรม GethandlerLevel (); การตอบสนองแบบนามธรรมสาธารณะ (คำขอคำขอ); } คลาส ConcreteHandler1 ขยายตัวจัดการ {ระดับป้องกัน GethandlerLevel () {ส่งคืนระดับใหม่ (1); } การตอบกลับสาธารณะ (คำขอคำขอ) { System.out.println ("------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ ConcreteHandler2 ขยายตัวจัดการ {ระดับการป้องกัน GethandlerLevel () {ส่งคืนระดับใหม่ (3); System.out.println ("------ คำขอถูกประมวลผลโดยโปรเซสเซอร์ 3 -----"); Handler1.SetNexthandler (Handler2); Handler2.SetNexthandler (Handler3);ในรหัสชั้นเรียนระดับจำลองเงื่อนไขการกำหนด; คำขอและการตอบกลับสอดคล้องกับคำขอและการตอบกลับตามลำดับ ตัวจัดการระดับนามธรรมส่วนใหญ่ตัดสินเงื่อนไขและระดับการประมวลผลถูกจำลองที่นี่ เฉพาะระดับการประมวลผลของคลาสการประมวลผลเท่านั้นที่สูงกว่าระดับของคำขอเท่านั้นที่สามารถประมวลผลได้มิฉะนั้นจะถูกส่งไปยังโปรเซสเซอร์ถัดไปสำหรับการประมวลผล
ตั้งค่าความสัมพันธ์ในการดำเนินการด้านหน้าและด้านหลังของห่วงโซ่ในคลาสไคลเอนต์และส่งคำขอไปยังคลาสการประมวลผลครั้งแรกระหว่างการดำเนินการ นี่คือรูปแบบห่วงโซ่ความรับผิดชอบ ฟังก์ชั่นที่เสร็จสมบูรณ์นั้นเหมือนกับ IF ... อื่น ... ในบทความก่อนหน้า
ข้อดีและข้อเสียของรูปแบบห่วงโซ่ความรับผิดชอบ
เมื่อเทียบกับถ้า…อื่น…รูปแบบห่วงโซ่ความรับผิดชอบมีความสามารถในการมีเพศสัมพันธ์ที่ต่ำกว่าเพราะมันกระจายการตัดสินตามเงื่อนไขไปยังคลาสการประมวลผลที่หลากหลายและลำดับการประมวลผลลำดับความสำคัญของคลาสการประมวลผลเหล่านี้สามารถตั้งค่าได้ รูปแบบห่วงโซ่ความรับผิดชอบยังมีข้อเสียซึ่งเป็นเช่นเดียวกับคำสั่งถ้า ... อื่น ... นั่นคือก่อนที่จะค้นหาคลาสการประมวลผลที่ถูกต้องเงื่อนไขการตัดสินทั้งหมดจะต้องดำเนินการ เมื่อห่วงโซ่ความรับผิดชอบค่อนข้างยาวปัญหาประสิทธิภาพจะรุนแรงขึ้น
สถานการณ์ที่ใช้งานได้สำหรับรูปแบบความรับผิดชอบ
เช่นเดียวกับตัวอย่างเริ่มต้นหากคุณรู้สึกว่าถูกครอบงำเมื่อใช้คำสั่ง IF …อื่น…เพื่อจัดระเบียบห่วงโซ่ความรับผิดชอบและรหัสดูไม่ดีคุณสามารถใช้โหมดความรับผิดชอบในการปรับเปลี่ยนใหม่
สรุป
แบบจำลองห่วงโซ่ความรับผิดชอบเป็นเวอร์ชันที่ยืดหยุ่นของ IF ... อื่น ... คำสั่ง มันทำให้เงื่อนไขการตัดสินเหล่านี้ลงในแต่ละคลาสการประมวลผล ข้อดีของสิ่งนี้คือมันมีความยืดหยุ่นมากขึ้น แต่ก็นำมาซึ่งความเสี่ยง ตัวอย่างเช่นเมื่อตั้งค่าความสัมพันธ์ระหว่างคลาสการประมวลผลก่อนและหลังคลาสการประมวลผลคุณต้องระมัดระวังอย่างมากในการตัดสินความสัมพันธ์ระหว่างตรรกะตามเงื่อนไขก่อนและหลังคลาสการประมวลผลและระวังไม่ให้มีการอ้างอิงแบบวงกลมในห่วงโซ่
ข้างต้นเป็นเนื้อหาทั้งหมดของบทความนี้ ฉันหวังว่ามันจะเป็นประโยชน์ต่อการเรียนรู้ของทุกคนและฉันหวังว่าทุกคนจะสนับสนุน wulin.com มากขึ้น