3.1 ซิงเกิลตัน
Singletonเป็นรูปแบบการออกแบบทั่วไปที่รับประกันว่าแอปพลิเคชันแบบเธรดเดียวจะมีอินสแตนซ์เดียวของบางคลาส และจัดเตรียมจุดเชื่อมต่อส่วนกลางให้กับอินสแตนซ์นี้
![ซิงเกิลตัน](https://cdn.codegym.cc/images/article/e1787a38-0ea4-4f60-b524-5d49b9035c5f/800.jpeg)
บ่อยครั้งที่โปรแกรมเมอร์มือใหม่ชอบรวบรวมวิธียูทิลิตี้เป็นคลาสแบบสแตติกบางคลาส - คลาสที่มีเฉพาะเมธอดแบบสแตติก วิธีนี้มีข้อเสียหลายประการ เช่น คุณไม่สามารถส่งการอ้างอิงไปยังออบเจกต์ของคลาสดังกล่าว วิธีการดังกล่าวยากต่อการทดสอบ เป็นต้น
อีกทางเลือกหนึ่ง เสนอโซลูชันคลาส singleton: คลาสที่สามารถมีได้เพียงออบเจกต์เดียวเท่านั้น เมื่อพยายามสร้างวัตถุนี้ จะมีการสร้างก็ต่อเมื่อวัตถุนั้นไม่มีอยู่แล้ว มิฉะนั้น การอ้างอิงถึงอินสแตนซ์ที่มีอยู่แล้วจะถูกส่งกลับ
จำเป็นอย่างยิ่งที่จะสามารถใช้อินสแตนซ์ของคลาสได้ เนื่องจากในหลายกรณีจะมีฟังก์ชันการทำงานที่กว้างขึ้น ตัวอย่างเช่น คลาสนี้สามารถใช้อินเทอร์เฟซบางอย่างได้ และวัตถุสามารถส่งผ่านไปยังเมธอดอื่นเป็นการดำเนินการของอินเทอร์เฟซ สิ่งที่ไม่สามารถทำได้ด้วยชุดของวิธีการคงที่
ข้อดี:
- เมธอดถูกผูกไว้กับอ็อบเจกต์ ไม่ใช่คลาสสแตติก คุณสามารถส่งออบเจกต์โดยการอ้างอิง
- วิธีการของวัตถุนั้นง่ายกว่ามากในการทดสอบและจำลอง
- วัตถุถูกสร้างขึ้นเมื่อจำเป็นเท่านั้น: การเริ่มต้นวัตถุขี้เกียจ
- เร่งการเปิดตัวครั้งแรกของโปรแกรมหากมีหลายซิงเกิ้ลที่ไม่จำเป็นสำหรับการเปิดตัว
- เพียงอย่างเดียวสามารถเปลี่ยนเป็นกลยุทธ์เทมเพลตหรือวัตถุหลายอย่างได้
ข้อเสีย:
- การควบคุมการแข่งขันระหว่างเธรดและความล่าช้าจะยากขึ้น
- เป็นการยากที่จะเขียน "ไม่ฝักใฝ่ฝ่ายใด" แบบหลายเธรด "จากหัว": ไม่ควรเปิด mutex การเข้าถึงซิงเกิลตันที่มีมายาวนาน โซลูชันที่ได้รับการพิสูจน์แล้วดีกว่า
- ความขัดแย้งระหว่างสองเธรดบนเธรดเดียวที่ยังไม่เสร็จจะส่งผลให้เกิดความล่าช้า
- หากวัตถุถูกสร้างขึ้นเป็นเวลานาน ความล่าช้าอาจรบกวนผู้ใช้หรือรบกวนเวลาจริง ในกรณีนี้จะเป็นการดีกว่าที่จะถ่ายโอนการสร้างไปยังขั้นตอนของการเริ่มต้นโปรแกรม
- คุณสมบัติพิเศษจำเป็นสำหรับการทดสอบหน่วย ตัวอย่างเช่น เพื่อให้ไลบรารีอยู่ในโหมด "ไม่โดดเดี่ยว" และแยกการทดสอบออกจากกันโดยสมบูรณ์
- จำเป็นต้องมีกลยุทธ์พิเศษสำหรับการทดสอบโปรแกรมที่เสร็จสมบูรณ์แล้ว เพราะแม้แต่แนวคิดของ "ความสามารถในการเปิดใช้ที่ง่ายที่สุด" ก็หายไป เนื่องจากความสามารถในการเปิดใช้ขึ้นอยู่กับการกำหนดค่า
3.2 โรงงาน [วิธีการ]
วิธีการจากโรงงานคือรูปแบบการออกแบบทั่วไปที่ให้คลาสย่อย (ตัวสืบทอดคลาส) พร้อมอินเทอร์เฟซสำหรับสร้างอินสแตนซ์ของคลาสหนึ่งๆ ในขณะที่สร้าง ลูกหลานสามารถกำหนดได้ว่าจะสร้างคลาสใด
กล่าวอีกนัยหนึ่ง เทมเพลตนี้มอบหมายการสร้างออบเจกต์ให้กับผู้สืบทอดของคลาสพาเรนต์ สิ่งนี้ช่วยให้คุณใช้คลาสที่ไม่เป็นรูปธรรมในรหัสโปรแกรม แต่เพื่อจัดการกับวัตถุนามธรรมในระดับที่สูงขึ้น
![วิธีการโรงงาน](https://cdn.codegym.cc/images/article/4aaa2335-e052-426e-a474-c5b718453439/800.jpeg)
รูปแบบนี้กำหนดอินเทอร์เฟซสำหรับการสร้างออบเจกต์ แต่ปล่อยให้เป็นคลาสย่อยเพื่อตัดสินใจว่าจะใช้ออบเจกต์ใดในคลาสใด เมธอดโรงงานอนุญาตให้คลาสมอบหมายการสร้างคลาสย่อย ใช้เมื่อ:
- คลาสไม่ทราบล่วงหน้าว่าอ็อบเจกต์ใดของคลาสย่อยที่ต้องสร้าง
- คลาสได้รับการออกแบบเพื่อให้วัตถุที่สร้างถูกระบุโดยคลาสย่อย
- ชั้นเรียนมอบหมายความรับผิดชอบให้กับหนึ่งในหลาย ๆ คลาสย่อยของผู้ช่วยเหลือ และมีการวางแผนที่จะกำหนดว่าคลาสใดจะรับช่วงต่อความรับผิดชอบเหล่านี้
3.3 บทคัดย่อโรงงาน
โรงงานนามธรรมเป็นรูปแบบการออกแบบทั่วไปที่ให้อินเทอร์เฟซสำหรับการสร้างครอบครัวของวัตถุที่เกี่ยวข้องหรือพึ่งพากันโดยไม่ต้องระบุคลาสที่เป็นรูปธรรม
รูปแบบนี้ถูกนำไปใช้โดยการสร้างคลาสนามธรรม Factory ซึ่งเป็นอินเทอร์เฟซสำหรับสร้างส่วนประกอบของระบบ (ตัวอย่างเช่น สำหรับอินเทอร์เฟซหน้าต่าง สามารถสร้างหน้าต่างและปุ่มต่างๆ ได้) จากนั้นจึงเขียนคลาสที่ใช้อินเทอร์เฟซนี้
![โรงงานที่เป็นนามธรรม](https://cdn.codegym.cc/images/article/956e8170-2348-4fc4-849d-ebd5526841c4/800.jpeg)
ใช้ในกรณีที่โปรแกรมต้องไม่ขึ้นกับกระบวนการและประเภทของวัตถุใหม่ที่สร้างขึ้น เมื่อจำเป็นต้องสร้างตระกูลหรือกลุ่มของอ็อบเจ็กต์ที่เกี่ยวข้องกัน ยกเว้นความเป็นไปได้ของการใช้อ็อบเจ็กต์จากชุดต่างๆ ของสิ่งเหล่านี้พร้อมกันในบริบทเดียวกัน
จุดแข็ง:
- แยกชั้นเรียนเฉพาะ
- ลดความซับซ้อนในการเปลี่ยนตระกูลผลิตภัณฑ์
- รับประกันความเข้ากันได้ของผลิตภัณฑ์
สมมติว่าโปรแกรมของคุณทำงานร่วมกับระบบไฟล์ จากนั้นในการทำงานใน Linux คุณต้องมีวัตถุ LinuxFile, LinuxDirectory, LinuxFileSystem และในการทำงานใน Windwos คุณต้องมีคลาส WindowsFile, WindowsDirectory, WindowsFileSystem
คลาส Path ซึ่งสร้างผ่าน Path.of() เป็นเพียงกรณีดังกล่าว Path ไม่ใช่คลาสจริงๆ แต่เป็นอินเทอร์เฟซ และมีการใช้งาน WindowsPath และ LinuxPath และวัตถุประเภทใดที่จะถูกสร้างขึ้นจะถูกซ่อนจากโค้ดของคุณและจะถูกตัดสินเมื่อรันไทม์
3.4 ต้นแบบ
Prototypeเป็นรูปแบบการออกแบบเชิงกำเนิด
รูปแบบนี้กำหนดประเภทของวัตถุที่สร้างขึ้นโดยใช้อินสแตนซ์ต้นแบบ และสร้างวัตถุใหม่โดยการคัดลอกต้นแบบนี้ ช่วยให้คุณหลีกหนีจากการใช้งานและปฏิบัติตามหลักการของ "การเขียนโปรแกรมผ่านอินเทอร์เฟซ"
คลาสอินเทอร์เฟซ/นามธรรมที่ด้านบนสุดของลำดับชั้นถูกระบุเป็นประเภทที่ส่งคืน และคลาสที่สืบทอดมาสามารถแทนที่ทายาทที่นำประเภทนี้ไปใช้ได้ พูดง่ายๆ คือรูปแบบการสร้างวัตถุโดยการโคลนวัตถุอื่นแทนการสร้างผ่านตัวสร้าง
![ต้นแบบ](https://cdn.codegym.cc/images/article/3c9f9fce-f53d-41ca-bf4c-d59a0cfb0ff2/800.jpeg)
รูปแบบนี้ใช้เพื่อ:
- หลีกเลี่ยงความพยายามเพิ่มเติมในการสร้างวัตถุด้วยวิธีมาตรฐาน (หมายถึงการใช้ตัวสร้าง เนื่องจากในกรณีนี้จะเรียกตัวสร้างของลำดับชั้นบรรพบุรุษของวัตถุทั้งหมดด้วย) เมื่อสิ่งนี้มีราคาแพงสำหรับแอปพลิเคชัน
- หลีกเลี่ยงการสืบทอดผู้สร้างออบเจกต์ในแอปพลิเคชันไคลเอนต์ อย่างที่รูปแบบโรงงานนามธรรมทำ
ใช้รูปแบบการออกแบบนี้เมื่อโปรแกรมของคุณไม่สนใจวิธีการสร้าง เขียน และนำเสนอผลิตภัณฑ์:
- คลาสอินสแตนซ์ถูกกำหนด ณ รันไทม์ ตัวอย่างเช่น ใช้การโหลดแบบไดนามิก
- คุณต้องการหลีกเลี่ยงการสร้างคลาสหรือลำดับชั้นของโรงงานที่ขนานกับลำดับชั้นของคลาสผลิตภัณฑ์
- อินสแตนซ์ของคลาสสามารถอยู่ในหนึ่งในหลายสถานะที่แตกต่างกัน การกำหนดจำนวนต้นแบบที่เหมาะสมและโคลนอาจสะดวกกว่า แทนที่จะสร้างอินสแตนซ์คลาสด้วยตนเองในสถานะที่เหมาะสมในแต่ละครั้ง