7 วิธีในการสร้าง Singleton ใน Javascript
สวัสดี คน รักบิต ที่ชื่นชอบ วันนี้เราจะพูดถึงสิ่งที่พบได้บ่อยที่สุดที่คุณอาจใช้ในโปรเจกต์ของคุณ นั่นคือSingleton Pattern
สำหรับคุณที่ทราบอยู่แล้วว่าซิงเกิลตันคืออะไร เลื่อนไปเรื่อยๆ ฉันแน่ใจว่าบทความนี้จะทำให้คุณประหลาดใจ
สำหรับคนอื่นๆ…
Singleton Pattern — เป็นที่นิยมใช้มากที่สุดและเป็นหนึ่งในสิ่งที่ถูกถามในการสัมภาษณ์เกือบทุกครั้ง สามารถอธิบายได้ว่าเป็นรูปแบบที่จำกัดการใช้งานคลาสไว้เพียงการใช้งานเดียว กล่าวอีกนัยหนึ่ง ในแอปพลิเคชันของคุณ อนุญาตให้มีคลาสของคุณได้เพียงหนึ่งอินสแตนซ์
เนื่องจากสิ่งนี้ได้รับการตัดสินแล้ว เรามาดูตัวอย่างกัน
บทความนี้จะมีทั้งตัวอย่างJavascriptและTypescript
ซิงเกิลตันคลาสสิก
วิธีที่โดดเด่นและคลาสสิกที่สุดในการติดตั้งซิงเกิลตัน คุณสามารถหาตัวอย่างได้จากบทช่วยสอนทุกเล่มและหนังสือการเขียนโปรแกรมทุกเล่ม
ตัวอย่างจาวาสคริปต์ :
ตัวอย่าง ตัวพิมพ์ :
และนี่คือวิธีการใช้งาน:
ClassicSingleton.instance.invoke();
ข้อดี
- โซลูชันที่เรียบง่าย ตรงไปตรงมา และสะอาดหมดจด
- วิธีการที่พบบ่อยที่สุด
- เริ่มต้นเมื่อบูตแอปพลิเคชัน ซึ่งอาจนำไปสู่การบูตแอปพลิเคชันได้ช้า
- ไม่สามารถสืบทอดได้อย่างถูกต้อง ซึ่งหมายความว่าคุณต้องทำซ้ำรหัสนี้ในทุก ๆ คลาสที่คุณต้องการใช้ซิงเกิลตัน
ส่วนใหญ่จะใช้ Lazy Singletonเมื่อคุณไม่ต้องการเริ่มต้นซิงเกิลตันของคุณทันที และต้องการใช้เมื่อจำเป็นเท่านั้น วิธีที่ดีในการเพิ่มประสิทธิภาพระดับไมโครให้กับแอปของคุณ ในเรื่องอื่นๆ ก็ใกล้เคียงกับClassic Singleton
ตัวอย่างจาวาสคริปต์ :
ตัวอย่าง ตัวพิมพ์ :
และนี่คือวิธีการใช้งาน:
LazySingleton.instance().invoke();
ข้อดี
- เริ่มต้นเมื่อใช้งานและไม่ใช้หน่วยความจำเมื่อไม่ได้ถูกเรียกใช้
- วิธีแก้ปัญหาที่ง่ายและสะอาด
- เริ่มต้นเมื่อใช้งาน ซึ่งอาจทำให้เกิดความล่าช้าเล็กน้อยในการใช้งานครั้งแรก
- ไม่สามารถสืบทอดได้ ซึ่งหมายความว่าคุณต้องทำซ้ำรหัสนี้ในทุก ๆ คลาสที่คุณต้องการใช้ซิงเกิลตัน
เกือบจะเหมือนกับLazy Singletonแต่เราใช้ getter แทนฟังก์ชันธรรมดา ซึ่งช่วยให้เราหลีกเลี่ยงการใช้วงเล็บที่น่ารังเกียจ()ได้
ตัวอย่างจาวาสคริปต์ :
ตัวอย่าง ตัวพิมพ์ :
วิธีใช้:
LazyGetterSingleton.instance.invoke();
มีข้อดีข้อเสียเช่น เดียว กับLazy Singleton
นำเข้าซิงเกิลตัน
คุณไม่สามารถพูดได้ว่าวิธีการนี้เป็นเรื่องธรรมดา เพราะไม่ใช่ทุกภาษาการเขียนโปรแกรมที่เป็นไปตามกระบวนทัศน์ของการประกาศการส่งออก/นำเข้าจากไฟล์
ตัวอย่าง Javascript ES6 (บาเบล):
ตัวอย่าง Javascript (โหนด):
ตัวอย่าง ตัวพิมพ์ :
วิธีใช้Javascript ES6 (Babel) และ เวอร์ชัน Typescript :
import { importSingletion } from "./ImportSingleton";
importSingleton.invoke();
const importSingleton = require("./ImportSingleton");
importSingleton.invoke()
ข้อดี
- โซลูชันที่เรียบง่าย ตรงไปตรงมา และสะอาดหมดจด
- เริ่มต้นเมื่อบูตแอปพลิเคชัน ซึ่งอาจนำไปสู่การบูตแอปพลิเคชันได้ช้า
- ไม่สามารถทำให้เป็นอัตโนมัติได้ ซึ่งนำไปสู่ฐานรหัสซ้ำซ้อน
มัณฑนากรซิงเกิลตัน
แนวทางที่น่าสนใจเมื่อใช้สองรูปแบบร่วมกัน: SingletonและDecorator
แนวคิดหลักคือการลดการทำซ้ำโค้ดให้เหลือน้อยที่สุด
ตัวอย่างจาวาสคริปต์ :
คุณสามารถใช้กับTypescriptได้ แต่น่าเสียดายที่โดยค่าเริ่มต้นTypescriptไม่สังเกตเห็นคุณสมบัติไดนามิก และคุณต้องเขียนโค้ดเพิ่มเติมที่ค่อนข้างสกปรกสำหรับTypescriptเพื่อรองรับ นั่นคือเหตุผลที่ไม่ควรใช้วิธีนี้กับtypescript
วิธีใช้:
DecoratorSingleton.instance.invoke();
- โซลูชันที่เรียบง่าย ตรงไปตรงมา และสะอาดหมดจด
- คุณสามารถรักษาฐานรหัสที่ค่อนข้างสะอาดและหลีกเลี่ยงการทำซ้ำรหัส
- เริ่มต้นเมื่อบูตแอปพลิเคชัน ซึ่งอาจนำไปสู่การบูตแอปพลิเคชันได้ช้า
วิธีการที่ยอดเยี่ยมอีกครั้งที่รวมสองรูปแบบเข้าด้วยกันSingletonและDecoratorแต่ยังช่วยให้คุณดู Singleton ของคุณจากมุมที่แตกต่างกัน และเป็นโบนัส เปิดประตูสู่ความรู้เชิงลึกของJavascript
ตัวอย่างจาวาสคริปต์ :
ตัวอย่าง ตัวพิมพ์ :
และนี่คือวิธีใช้เวอร์ชันJavascriptและTypescript :
new BindSingleton().invoke()
BindSingleton().invoke()
คุณสามารถตรวจสอบความถูกต้องได้โดย:
new ConstructorSingleton() === new ConstructorSingleton() // => true
ConstructorSingleton() === ConstructorSingleton() // => true
ง่ายดี ก่อนอื่น เราBindSingletonไม่เคยเป็นคลาส มันเป็นฟังก์ชัน นั่นเป็นเหตุผลที่เราสามารถใช้BindSingleton()มันได้ เย็นใช่มั้ย?
ทีนี้ แล้วทำไมnew BindSingleton()มันถึงกลับมาเหมือนเดิมล่ะ? ค่อนข้างชัดเจนอีกครั้ง การตรวจสอบตรรกะของเราในinstanceฟังก์ชันตรวจสอบคุณสมบัติคงที่ในคลาส หากไม่มีคุณสมบัติ เราจะสร้างอินสแตนซ์ของคลาสของเรา และหากคุณสมบัตินั้นมีอยู่ เราจะใช้มันแทนการเริ่มต้นอินสแตนซ์ใหม่
ข้อดี
- ให้คุณเข้าถึงซิงเกิลตันได้หลายวิธี
- ถือว่าLazy Singleton
- คุณสามารถรักษาฐานโค้ดของคุณให้สะอาดอยู่เสมอ
- ต้องการความเข้าใจอย่างลึกซึ้งเกี่ยวกับJavascriptและอาจทำให้นักพัฒนาที่ไม่มีประสบการณ์สับสนได้
- เมื่อเปรียบเทียบกับวิธีอื่น — รหัสจำนวนมาก
ตัวสร้างซิงเกิลตัน
สิ่งนี้ต้องการความเข้าใจอย่างลึกซึ้งเกี่ยวกับวิธี การทำงานของ Javascriptแต่เป็นโซลูชันที่สวยงามอย่างแท้จริง
ตัวอย่างจาวาสคริปต์ :
ตัวอย่างตัวพิมพ์:
และนี่คือวิธีใช้:
new ConstructorSingleton().invoke()
new ConstructorSingleton() === new ConstructorSingleton() // => true
เมื่อเรารันโค้ดของเราครั้งแรก — มันจะเริ่มต้นcacheและสร้างอินสแตนซ์ของเราเมื่อไปถึงconstructorตรวจสอบค่าที่ส่งคืน และในตัวสร้างที่เรียกใช้ครั้งแรกจะส่งคืนundefinedซึ่งบังคับให้Javascriptสร้างอินสแตนซ์ใหม่ของคลาส แต่การรันต่อไปนี้ทั้งหมดจะได้รับอินสแตนซ์ของเราcacheและconstructorจะส่งคืนอินสแตนซ์ของเราแทนundefinedซึ่งจะระบุกับJavascriptว่าควรส่งคืนอินสแตนซ์ที่มีอยู่ของเรา
ข้อเสีย :
- ต้องการความรู้เชิงลึกของJavascript
- เริ่มต้นเมื่อบูตแอปพลิเคชัน ซึ่งอาจนำไปสู่การบูตแอปพลิเคชันได้ช้า
- ไม่สามารถสืบทอดได้อย่างถูกต้อง ซึ่งหมายความว่าคุณต้องทำซ้ำรหัสนี้ในทุก ๆ คลาสที่คุณต้องการใช้ซิงเกิลตัน
ทรัพยากร
- เชื่อมโยงไปยังที่เก็บ
อย่าลืมติดตามฉันสำหรับสิ่งเพิ่มเติม!
บิตของคุณ 01101100 01101111 01110110 01100101





































![รายการที่เชื่อมโยงคืออะไร? [ส่วนที่ 1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)