คำจำกัดความ: ห่อหุ้มคำขอลงในวัตถุช่วยให้คุณสามารถกำหนดพารามิเตอร์ไคลเอนต์โดยใช้คำขอที่แตกต่างกันคำขอคิวหรือบันทึกการร้องขอการร้องขอและให้ฟังก์ชั่นการเพิกถอนคำสั่งและฟังก์ชั่นการกู้คืน
ประเภท: รูปแบบพฤติกรรม
แผนภาพชั้นเรียน:
โครงสร้างของโหมดคำสั่ง
ตามชื่อแนะนำโหมดคำสั่งคือการห่อหุ้มคำสั่ง ก่อนอื่นมาดูโครงสร้างพื้นฐานในไดอะแกรมคลาสโหมดคำสั่ง:
คลาสคำสั่ง: เป็นคลาสนามธรรมที่ประกาศคำสั่งที่ต้องดำเนินการ โดยทั่วไปวิธีการดำเนินการจะต้องเผยแพร่ต่อสาธารณะเพื่อดำเนินการคำสั่ง
คลาส Concretecommand: คลาสการใช้งานของคลาสคำสั่งใช้วิธีการที่ประกาศในคลาสนามธรรม
คลาสไคลเอนต์: คลาสการโทรไคลเอนต์สุดท้าย
ฟังก์ชั่นของสามคลาสข้างต้นควรเข้าใจง่ายขึ้น มามุ่งเน้นไปที่คลาส Invoker และคลาส Recevier
คลาส Invoker: ผู้โทรมีหน้าที่เรียกใช้คำสั่ง
คลาสผู้รับ: ผู้รับมีหน้าที่รับผิดชอบในการรับและดำเนินการคำสั่ง
ในการกล่าวอย่างตรงไปตรงมาการห่อหุ้มคำสั่งที่เรียกว่าไม่มีอะไรมากไปกว่าการเขียนชุดการดำเนินการลงในวิธีการแล้วถูกเรียกโดยลูกค้า มันสะท้อนให้เห็นในแผนภาพคลาส ใช้คลาสคอนกรีตคอมมอนและคลาสไคลเอนต์เท่านั้นเพื่อให้การห่อหุ้มคำสั่งเสร็จสมบูรณ์ แม้ว่ามันจะดำเนินต่อไปเพื่อเพิ่มความยืดหยุ่นคลาสคำสั่งสามารถเพิ่มสำหรับสิ่งที่เป็นนามธรรมที่เหมาะสม ฟังก์ชั่นของผู้โทรและตัวรับสัญญาณนี้คืออะไร?
ในความเป็นจริงคุณสามารถคิดจากมุมมองอื่น: หากคุณเพียงแค่ห่อหุ้มการดำเนินการบางอย่างเป็นคำสั่งให้ผู้อื่นโทรหารูปแบบได้อย่างไร ในฐานะที่เป็นแบบจำลองพฤติกรรมโหมดคำสั่งจะต้องมีการมีเพศสัมพันธ์ต่ำก่อน เฉพาะเมื่อระดับการมีเพศสัมพันธ์ต่ำสามารถปรับปรุงความยืดหยุ่นได้ วัตถุประสงค์ของการเพิ่มบทบาทผู้โทรและตัวรับสัญญาณนั้นเป็นสิ่งที่แม่นยำสำหรับเรื่องนี้
ตัวอย่าง:
การจำลองการทำงานของทีวีรวมถึงคำสั่ง Power-On, Shutdown และการเปลี่ยนแปลง รหัสมีดังนี้
// อินเตอร์เฟสสำหรับการดำเนินการคำสั่งคำสั่งอินเตอร์เฟสสาธารณะ {void execute (); } // ตัวรับสัญญาณคำสั่งตัวรับสัญญาณสาธารณะทีวี {สาธารณะ int currentChannel = 0; โมฆะสาธารณะ Turnon () {System.out.println ("Televisino เปิดอยู่"); } โมฆะสาธารณะ turnoff () {system.out.println ("โทรทัศน์ปิด"); } โมฆะสาธารณะ Changechannel (ช่อง int) {this.currentChannel = ช่อง; System.out.println ("ช่องทีวีตอนนี้คือ" + ช่อง); }} // ปิดคำสั่ง concretecommand คลาสสาธารณะ Commandon ใช้คำสั่ง {ทีวีส่วนตัว mytv; Public Commandon (ทีวีทีวี) {mytv = tv; } โมฆะสาธารณะดำเนินการ () {mytv.turnon (); }} // ปิดคำสั่ง concretecommand คลาสสาธารณะ Commandoff ใช้คำสั่ง {ทีวีส่วนตัว mytv; Public Commandoff (ทีวีทีวี) {mytv = tv; } โมฆะสาธารณะดำเนินการ () {mytv.turnoff (); }} // คำสั่งสลับช่องสัญญาณ concretecommand คลาสสาธารณะ commandChange ใช้คำสั่ง {ทีวีส่วนตัว mytv; ช่องสัญญาณส่วนตัว Public CommandChange (ทีวีทีวี, ช่อง int) {mytv = tv; this.channel = channel; } โมฆะสาธารณะดำเนินการ () {mytv.changechannel (ช่อง); }} // มันถือได้ว่าเป็นตัวควบคุมระดับรีโมทคอนโทรลการควบคุมระดับสาธารณะ {คำสั่งส่วนตัว oncommand, OffCommand, Changechannel; การควบคุมสาธารณะ (คำสั่งเปิด, ปิดคำสั่ง, ช่องคำสั่ง) {onCommand = on; OffCommand = ปิด; Changechannel = ช่อง; } โมฆะสาธารณะ turnon () {oncommand.execute (); } โมฆะสาธารณะ turnoff () {OffCommand.execute (); } โมฆะสาธารณะ Changechannel () {changechannel.execute (); }} // ไคลเอ็นต์ระดับไคลเอนต์คลาสสาธารณะ {โมฆะคงที่สาธารณะหลัก (สตริง [] args) {// ผู้รับคำสั่งผู้รับรับทีวี mytv = ทีวีใหม่ (); // power-on command concreteCommond Commandon on = new Commandon (MyTV); // คำสั่ง POWER-OFF ConcreTeCommond Commandoff OFF = New Commandoff (MYTV); // ช่องสัญญาณสลับคำสั่ง concreteCommond channel channel = new CommandChange (MyTV, 2); // คำสั่งควบคุมวัตถุควบคุมตัวควบคุมการควบคุม = ควบคุมใหม่ (เปิด, ปิด, ช่อง); // power-on control.turnon (); // สวิตช์ช่องควบคุม ChangeChannel (); // ปิดการควบคุม Turnoff (); -ผลการดำเนินการ
โทรทัศน์เปิดอยู่ ตอนนี้ช่องทีวีคือ 2 โทรทัศน์ปิดอยู่
ข้อดีและข้อเสียของโหมดคำสั่ง
ก่อนอื่นโหมดคำสั่งนั้นมีการห่อหุ้มอย่างมาก: แต่ละคำสั่งถูกห่อหุ้มและสำหรับไคลเอนต์คำสั่งที่สอดคล้องกันเรียกว่ามากที่สุดเท่าที่ต้องการฟังก์ชั่นโดยไม่ทราบว่าคำสั่งถูกดำเนินการอย่างไร ตัวอย่างเช่นมีชุดคำสั่งการทำงานของไฟล์: สร้างไฟล์ใหม่คัดลอกไฟล์และลบไฟล์ หากการดำเนินการทั้งสามนี้ถูกห่อหุ้มลงในคลาสคำสั่งไคลเอ็นต์จะต้องรู้ว่ามีคลาสคำสั่งทั้งสามนี้ สำหรับตรรกะที่ห่อหุ้มอยู่ในคลาสคำสั่งไคลเอนต์ไม่จำเป็นต้องรู้
ประการที่สองโหมดคำสั่งมีความยืดหยุ่นที่ดี ในโหมดคำสั่งการห่อหุ้มขั้นพื้นฐานที่สุดของการดำเนินการในคลาสผู้รับและการห่อหุ้มระดับรองของคลาสคำสั่งของการดำเนินการพื้นฐานเหล่านี้ เมื่อเพิ่มคำสั่งใหม่การเขียนคลาสคำสั่งโดยทั่วไปจะไม่มาจากศูนย์ มีคลาสผู้รับจำนวนมากสำหรับการโทรและยังมีคลาสคำสั่งจำนวนมากสำหรับการโทรและรหัสสามารถนำกลับมาใช้ใหม่ได้มาก ตัวอย่างเช่นในการดำเนินการของไฟล์เราจำเป็นต้องเพิ่มคำสั่งเพื่อตัดไฟล์และเราจำเป็นต้องรวมสองคำสั่งของการคัดลอกไฟล์และลบไฟล์ซึ่งสะดวกมาก
สุดท้ายเรามาพูดถึงข้อเสียของโหมดคำสั่งนั่นคือถ้ามีคำสั่งมากมายมันจะเป็นอาการปวดหัวในการพัฒนา โดยเฉพาะอย่างยิ่งคำสั่งง่ายๆจำนวนมากเป็นเพียงไม่กี่บรรทัดของรหัสที่จะนำไปใช้ หากคุณใช้โหมดคำสั่งคุณไม่ต้องกังวลเกี่ยวกับคำสั่งง่าย ๆ คุณต้องเขียนคลาสคำสั่งเพื่อห่อหุ้มมัน
สถานการณ์ที่ใช้งานได้สำหรับโหมดคำสั่ง
สำหรับฟังก์ชั่นโหมดการตอบสนองต่อการร้องขอส่วนใหญ่เหมาะสมกว่าที่จะใช้โหมดคำสั่ง ตามที่คำจำกัดความของโหมดคำสั่งระบุว่าโหมดคำสั่งนั้นสะดวกกว่าสำหรับการใช้งานฟังก์ชั่นเช่นการบันทึกและการยกเลิกการดำเนินการ
สรุป
ไม่ว่าจะใช้โหมดในโอกาสเป็นคำถามที่พันกันมากสำหรับนักพัฒนาทุกคน บางครั้งเนื่องจากการเปลี่ยนแปลงความต้องการบางอย่างรูปแบบการออกแบบบางอย่างใช้สำหรับความยืดหยุ่นและความยืดหยุ่นของระบบ แต่ข้อกำหนดที่คาดการณ์ได้นี้ไม่ได้ ในทางตรงกันข้ามข้อกำหนดที่ไม่สามารถคาดเดาได้จำนวนมากเกิดขึ้นส่งผลให้รูปแบบการออกแบบที่ใช้มีบทบาทตรงกันข้ามเมื่อแก้ไขรหัสเพื่อให้ทีมงานโครงการทั้งหมดบ่น ฉันเชื่อว่าโปรแกรมเมอร์ทุกคนได้พบตัวอย่างเช่นนี้ ดังนั้นตามหลักการของการพัฒนา Agile เมื่อเราออกแบบโปรแกรมถ้าเราสามารถแก้ปัญหาได้ดีโดยไม่ต้องใช้รูปแบบที่แน่นอนตามความต้องการในปัจจุบันเราไม่ควรแนะนำเพราะมันไม่ยากที่จะแนะนำรูปแบบการออกแบบ เราสามารถทำได้ในระบบเมื่อเราต้องการใช้มันและแนะนำรูปแบบการออกแบบนี้
ใช้โหมดคำสั่งเป็นตัวอย่าง ในการพัฒนาของเราฟังก์ชั่นโหมดการตอบสนองการร้องขอเป็นเรื่องธรรมดามาก โดยทั่วไปแล้วเราจะห่อหุ้มการตอบสนองต่อการร้องขอลงในวิธีการ วิธีการห่อหุ้มนี้สามารถเรียกได้ว่าเป็นคำสั่ง แต่ไม่ใช่โหมดคำสั่ง ไม่ว่าการออกแบบนี้ควรได้รับการยกระดับความสูงของรูปแบบจะต้องพิจารณาแยกต่างหากหรือไม่เพราะหากใช้โหมดคำสั่งจะต้องแนะนำทั้งสองบทบาทของผู้โทรและตัวรับสัญญาณ ตรรกะที่วางไว้ในที่เดียวนั้นกระจัดกระจายเป็นสามประเภท เมื่อออกแบบจำเป็นต้องพิจารณาว่าค่าใช้จ่ายนี้คุ้มค่าหรือไม่