การวิเคราะห์รูปแบบการออกแบบอินสแตนซ์แบบง่าย ๆ
คำนำ
วันนี้ฉันจะให้บทสรุปที่ครอบคลุมเกี่ยวกับรูปแบบการออกแบบที่ใช้กันมากที่สุดในการพัฒนา Android - โหมด Singleton
เกี่ยวกับการแนะนำรูปแบบการออกแบบคุณสามารถอ่านสิ่งที่ฉันเขียนก่อนหน้านี้: 1 นาทีเพื่อทำความเข้าใจอย่างเต็มที่ "รูปแบบการออกแบบ"
สารบัญ
1. แนะนำ
1.1 ปัญหาใดบ้างที่ได้รับการแก้ไข
ดังที่ได้กล่าวไว้ก่อนหน้านี้รูปแบบการออกแบบ = วิธีแก้ปัญหาเฉพาะบางประเภทดังนั้น รูปแบบ Singleton ปัญหาอะไร
ความหมาย: Singleton = ตัวอย่าง;
แก้ไขปัญหา: ลดการมีเพศสัมพันธ์ระหว่างวัตถุ
วิธีแก้ปัญหา: รูปแบบ Singleton นั่นคือการใช้งานที่คลาสมีวัตถุอินสแตนซ์เพียงชิ้นเดียวและให้จุดเชื่อมต่อทั่วโลก
1.2 การแนะนำอินสแตนซ์
ต่อไปฉันใช้อินสแตนซ์เพื่อแนะนำรูปแบบ Singleton
ความเป็นมา: Xiaocheng มีโรงงานพลาสติก แต่มีคลังสินค้าเพียงแห่งเดียวเท่านั้น
วัตถุประสงค์: ฉันต้องการใช้รหัสเพื่อใช้การจัดการคลังสินค้า
แนวทางปฏิบัติในปัจจุบัน: สร้างคลังสินค้าและคนงาน
ในหมู่พวกเขาปริมาณในคลาสคลังสินค้า = ปริมาณสินค้า; คนงานมีวิธีการจัดการ movein (int i) และ moveout (int i)
ปัญหา: จากการทดสอบพบว่าทุกครั้งที่คนงานเคลื่อนไหวคลังสินค้าใหม่จะถูกสร้างขึ้นนั่นคือสินค้าจะไม่ถูกวางไว้ในคลังสินค้าเดียวกัน เกิดอะไรขึ้น? (ดูรหัสด้านล่าง)
แพ็คเกจ scut.designmodel.singletonpattern; // คลังเก็บคลาสของคลังสินค้า {ปริมาณ int ส่วนตัว = 100; โมฆะสาธารณะ setquantity (ปริมาณ int) {this.quantity = ปริมาณ; } public int getQuantity () {ปริมาณคืน; }} // ผู้ให้บริการระดับมนุษย์เดิน {คลังสาธารณะ Mstorehouse; ผู้ให้บริการสาธารณะ (คลังเก็บคลังเก็บ) {Mstorehouse = คลังเก็บ; } // การย้ายสินค้าไปยังโมฆะสาธารณะคลังสินค้า Movein (int i) {mstorehouse.setQuantity (mstorehouse.getquantity ()+i); } // ย้ายออกจากโมฆะสาธารณะคลังสินค้า Moveout (int i) {mstorehouse.setQuantity (mstorehouse.getquantity ()-i); }} // การจัดการคนงานทดสอบระดับสาธารณะ Public Pattern {โมฆะคงที่สาธารณะหลัก (สตริง [] args) {คลังเก็บ mstorehouse1 = new Storehouse (); คลังเก็บ MSTOREHOUSE2 = New Storehouse (); Carrier Carrier1 = ผู้ให้บริการใหม่ (Mstorehouse1); carrier carrier2 = ผู้ให้บริการใหม่ (mstorehouse2); System.out.println ("ทั้งสองเหมือนกันหรือไม่"); if (mstorehouse1.equals (mstorehouse2)) {// ใช้เท่ากับที่นี่แทนที่จะเป็นสัญลักษณ์ == เพราะสัญลักษณ์ == เป็นเพียงการเปรียบเทียบที่อยู่ของวัตถุทั้งสอง System.out.println ("เหมือนกัน"); } else {system.out.println ("ไม่เหมือนกัน"); } // หลังจากพนักงานยกกระเป๋าย้ายสินค้ารายงานปริมาณสินค้าในคลังสินค้าผู้ให้บริการ 1.Movein (30); System.out.println ("ระยะขอบผลิตภัณฑ์คลังสินค้า:"+carrier1.mstorehouse.getquantity ()); carrier2.moveout (50); System.out.println ("ระยะขอบผลิตภัณฑ์คลังสินค้า:"+carrier2.mstorehouse.getquantity ()); -ผลลัพธ์:
ทั้งสองเหมือนกันหรือไม่? มาร์จิ้นผลิตภัณฑ์ในคลังสินค้าเดียวกัน: 130 คลังสินค้ามาร์จิ้นผลิตภัณฑ์: 50
2. บทนำสู่รูปแบบ Singleton
2.1 ปัญหาที่แก้ไขแล้ว (สถานการณ์แอปพลิเคชัน)
ความขัดแย้ง: จากผลลัพธ์ข้างต้นจะเห็นได้ว่าคนงานทำงานอย่างชัดเจนไม่ใช่อินสแตนซ์คลังสินค้าเดียวกัน
เป้าหมาย: คนงานทุกคนดำเนินการอินสแตนซ์คลังสินค้าเดียวกัน
รูปแบบ Singleton เป็นวิธีแก้ปัญหาประเภทนี้: ใช้คลาสที่มีวัตถุอินสแตนซ์เพียงหนึ่งชิ้นเท่านั้น
ใน Java เราใช้งานคลาสเหล่านี้โดยใช้วัตถุ (หลังการสร้างอินสแตนซ์ในชั้นเรียน) การสร้างอินสแตนซ์ในชั้นเรียนจะดำเนินการผ่านตัวสร้าง หากเราต้องการใช้งานคลาสนั้นมีวัตถุอินสแตนซ์เพียงชิ้นเดียวเราต้องทำงานกับตัวสร้างของคลาส:
การใช้งานทั่วไปของโหมด Singleton: (รวมถึงขั้นตอนการใช้งาน)
Singleton คลาสสาธารณะ {// 1 สร้างตัวแปรส่วนตัว ourinstance (ใช้เพื่อบันทึกอินสแตนซ์ที่ไม่ซ้ำกันของ Singleton) // 2 อินสแตนซ์อินสแตนซ์ส่วนตัวแบบสแตติกส่วนตัว ourinstance = ใหม่ Singleton (); // 3 แปรรูปคอนสตรัคเตอร์ของคลาสและป้องกันการโทรภายนอกเพื่อสร้างอินสแตนซ์ส่วนตัว Singleton () {} // 4 กำหนดวิธีการสาธารณะเพื่อให้จุดเชื่อมต่อที่ไม่ซ้ำกันระดับโลกสำหรับชั้นเรียน // 5 ส่งคืนอินสแตนซ์ที่ไม่ซ้ำกันจากภายนอกโดยเรียกวิธีการ getInstance () สาธารณะ Singleton Newinstance () {return ourinstance; -ตกลงคุณควรเข้าใจการแนะนำและหลักการของรูปแบบซิงเกิลใช่ไหม? ดังนั้นเรามาแก้ปัญหาที่“ คลังสินค้าไม่เหมือนกัน” ที่ปรากฏเหนือ Xiaocheng!
2.3 ตัวอย่างบทนำ
Xiaocheng ใช้โหมด Singleton เพื่อปรับปรุงรหัสสำหรับตัวอย่างข้างต้น:
แพ็คเกจ scut.designmodel.singletonpattern นำเข้า java.util.concurrent.locks.lock; นำเข้า java.util.concurrent.locks.reentrantlock; // คลังเก็บคลังสินค้าซิงเกิล // อินสแตนซ์คลังสินค้าคงที่ส่วนตัว ourinstance = New Storehouse () ;; // ให้เมธอด getInstance () ภายนอกเพื่อส่งคืนอินสแตนซ์ที่ไม่ซ้ำกัน คลังเก็บของสาธารณะคงที่ getInstance () {ส่งคืน ourinstance; } // constructor constructor private corsturhouse () {} public void setquantity (ปริมาณ int) {this.quantity = ปริมาณ; } public int getQuantity () {ปริมาณคืน; }} // ผู้ให้บริการชั้นพาหะของผู้ให้บริการ {คลังสาธารณะ Mstorehouse; ผู้ให้บริการสาธารณะ (คลังเก็บคลังเก็บ) {Mstorehouse = คลังเก็บ; } // ย้ายสินค้าไปยังโมฆะสาธารณะคลังสินค้า Movein (int i) {mstorehouse.setQuantity (mstorehouse.getquantity ()+i); } // ย้ายออกจากโมฆะสาธารณะคลังสินค้า Moveout (int i) {mstorehouse.setQuantity (mstorehouse.getquantity ()-i); }} // การจัดการคนงานทดสอบระดับสาธารณะ singlepattern {โมฆะคงที่สาธารณะหลัก (สตริง [] args) {คลังเก็บ mstorehouse1 = storehouse.getInstance (); Storehouse Mstorehouse2 = Storehouse.getInstance (); Carrier Carrier1 = ผู้ให้บริการใหม่ (Mstorehouse1); carrier carrier2 = ผู้ให้บริการใหม่ (mstorehouse2); System.out.println ("ทั้งสองเหมือนกันหรือไม่"); if (mstorehouse1.equals (mstorehouse2)) {system.out.println ("เหมือนกัน"); } else {system.out.println ("ไม่เหมือนกัน"); } // หลังจากพนักงานยกกระเป๋าย้ายสินค้ารายงานปริมาณสินค้าในคลังสินค้า, carrier1.movein (30); System.out.println ("ระยะขอบผลิตภัณฑ์คลังสินค้า:"+carrier1.mstorehouse.getquantity ()); carrier2.moveout (50); System.out.println ("ระยะขอบผลิตภัณฑ์คลังสินค้า:"+carrier2.mstorehouse.getquantity ()); -ผลลัพธ์:
ทั้งสองเหมือนกันหรือไม่? มันเป็นอัตรากำไรขั้นต้นของคลังสินค้าเดียวกัน: 130 คลังสินค้ามาร์จิ้น: 80
จากการวิเคราะห์ผลลัพธ์หลังจากใช้โมเดล Singleton มีเพียงอินสแตนซ์คลังสินค้าเพียงแห่งเดียวในคลาสคลังสินค้าและไม่จำเป็นต้องกังวลเกี่ยวกับ Porters ที่เข้าสู่คลังสินค้าที่ไม่ถูกต้อง! - -
2.4 ข้อดี
2.5 ข้อเสีย
3. การใช้งานโหมดซิงเกิลตัน
3.1 สถานการณ์ทั่วไป
Hungry Style (วิธีการใช้งาน Singleton ที่ง่ายที่สุด)
Class Singleton {Private Static Singleton OurInstance = New Singleton (); Private Singleton () {} Singleton Static Public Newinstance () {return ourinstance; -สถานการณ์แอปพลิเคชัน:
สไตล์ขี้เกียจ
ความแตกต่างที่ใหญ่ที่สุดระหว่าง Lazy และ Hungry คือ ช่วงเวลาของการดำเนินการเริ่มต้นของ Singletons :
Class Singleton {Private Static Singleton OurInstance = NULL; Private Singleton () {} Singleton Static Public Newinstance () {ถ้า (ourinstance == null) {ourinstance = new singleton (); } ส่งคืน ourinstance; -สถานการณ์แอปพลิเคชัน:
3.2 การใช้โหมด Singleton ภายใต้ multithreading
ในกรณีของมัลติเธรด:
โซลูชัน 1: ซิงโครไนซ์ล็อค
ใช้การซิงโครไนซ์ล็อคซิงโครไนซ์ (singleton.class) เพื่อป้องกันหลายเธรดจากการป้อนพร้อมกันทำให้อินสแตนซ์เป็นอินสแตนซ์หลายครั้ง
Class Singleton {Private Static Singleton OurInstance = NULL; Private Singleton () {} Singleton Static Public Newinstance () {ซิงโครไนซ์ (singleton.class) {ถ้า (ourinstance == null) {ourinstance = ใหม่ซิงเกิล (); }} ส่งคืน ourinstance; -โซลูชัน 2: ตรวจสอบอีกครั้งล็อค
เลเยอร์ของ IF จะถูกเพิ่มบนพื้นฐานของการล็อคการซิงโครไนซ์ (ยกเว้นซิงโครไนซ์ (singleton.class)) คือการปรับปรุงประสิทธิภาพหลังจากอินสแตนซ์ได้รับการสร้างอินสแตนซ์และในครั้งต่อไปที่มันเข้ามามันไม่จำเป็นต้องดำเนินการซิงโครไนซ์
Class Singleton {Private Static Singleton OurInstance = NULL; Private Singleton () {} Singleton Static Public Newinstance () {ถ้า (ourinstance == null) {ซิงโครไนซ์ (singleton.class) {ถ้า (uryinstance == null) {ourinstance = New Singleton (); }}} return ourinstance; -โซลูชัน 3: ชั้นในแบบคงที่
เมื่อคลาส JVM โหลดข้อมูลจะรับประกันว่าจะซิงโครไนซ์ เราใช้การใช้งานคลาสภายใน: สร้างอินสแตนซ์วัตถุในคลาสภายใน
ตราบใดที่แอปพลิเคชันไม่ได้ใช้ JVM คลาสภายในคลาส Singleton จะไม่ถูกโหลดและวัตถุซิงเกิลจะไม่ถูกสร้างขึ้นดังนั้นจึงไม่สามารถสร้าง "ขี้เกียจ" ขี้เกียจและความปลอดภัยของด้าย
คลาส Singleton {// วัตถุซิงเกิลตันจะถูกสร้างขึ้นเฉพาะเมื่อคลาสชั้นในโหลดคลาสสแตติกส่วนตัว Singleton2 {ส่วนตัวคงที่ Singleton ourinstance = ใหม่ Singleton (); } Private Singleton () {} Public Static Singleton Newinstance () {return Singleton2.ourinstance; -วิธีแก้ปัญหา 4: ระบุประเภท
วิธีการใช้งาน Singleton ที่ง่ายที่สุดและง่ายที่สุด (แนะนำโดย "Java ที่มีประสิทธิภาพ")
Public Enum Singleton {// กำหนดองค์ประกอบ enum ซึ่งเป็นอินสแตนซ์ของอินสแตนซ์ซิงเกิล โมฆะสาธารณะ Dosomething () {}}วิธีใช้เป็นดังนี้:
Singleton Singleton = Singleton.Instance; Singleton.dosomething ();
5. สรุป
บทความนี้ส่วนใหญ่แนะนำรูปแบบ Singleton รวมถึงหลักการและวิธีการดำเนินการ ต่อไปฉันจะอธิบายโมเดลการออกแบบอื่น ๆ ต่อไป หากคุณสนใจคุณสามารถให้ความสนใจต่อไปได้
ขอบคุณสำหรับการอ่านฉันหวังว่ามันจะช่วยคุณได้ ขอบคุณสำหรับการสนับสนุนเว็บไซต์นี้!