Singleton คืออะไรและควรใช้เมื่อใด
X
จะคุยกับY
อะไรได้แค่ทำY
ซิงเกิล!) ซึ่งจะนำไปสู่ปัญหาในการทดสอบ / การดีบักและรูปแบบการเขียนโปรแกรมตามขั้นตอน บางครั้ง Singletons มีความจำเป็น เวลาส่วนใหญ่ไม่ใช่
Singleton คืออะไรและควรใช้เมื่อใด
X
จะคุยกับY
อะไรได้แค่ทำY
ซิงเกิล!) ซึ่งจะนำไปสู่ปัญหาในการทดสอบ / การดีบักและรูปแบบการเขียนโปรแกรมตามขั้นตอน บางครั้ง Singletons มีความจำเป็น เวลาส่วนใหญ่ไม่ใช่
คำตอบ:
ซิงเกิลตันเป็นคลาสที่อนุญาตให้สร้างอินสแตนซ์ของตัวเองเพียงตัวเดียวเท่านั้นและให้การเข้าถึงอินสแตนซ์ที่ง่ายและสะดวก สมมติฐานเดียวเป็นรูปแบบในการพัฒนาซอฟต์แวร์
มี C # การดำเนินงานคือ"การดำเนินการตามรูปแบบซิงเกิลใน C #"รวมถึงบางคำแนะนำที่ดีเกี่ยวกับการ - ครอบคลุมมากที่สุดของสิ่งที่คุณจำเป็นต้องรู้หัวข้อความปลอดภัย
พูดตามตรงมันเป็นเรื่องยากมากที่คุณจะต้องใช้ซิงเกิลตัน - ในความคิดของฉันมันควรจะเป็นหนึ่งในสิ่งเหล่านั้นที่คุณควรระวังแม้ว่ามันจะไม่ได้ใช้บ่อยเกินไปก็ตาม
Lazy<T> Class
เช่นเดียวกับการเชื่อมโยงไปยังไมโครซอฟท์สำหรับหมอ
คุณถามหา C # ตัวอย่างเล็กน้อย:
public class Singleton
{
private Singleton()
{
// Prevent outside instantiation
}
private static readonly Singleton _singleton = new Singleton();
public static Singleton GetSingleton()
{
return _singleton;
}
}
มันคืออะไร:คลาสที่มีเพียงหนึ่งอินสแตนซ์ที่คงอยู่ตลอดอายุการใช้งานของแอปพลิเคชัน ดูแบบซิงเกิล
เมื่อใดที่คุณควรใช้:น้อยที่สุด เฉพาะเมื่อคุณมั่นใจอย่างแน่นอนว่าคุณต้องการมัน ฉันลังเลที่จะพูดว่า "ไม่เคย" แต่โดยปกติจะมีทางเลือกที่ดีกว่าเช่นการพึ่งพาการฉีดหรือเพียงแค่ระดับคงที่
อีกวิธีหนึ่งในการนำ singleton มาใช้ใน c # ฉันชอบวิธีนี้เป็นการส่วนตัวเพราะคุณสามารถเข้าถึงอินสแตนซ์ของคลาส singeton เป็นคุณสมบัติแทนวิธีการ
public class Singleton
{
private static Singleton instance;
private Singleton() { }
public static Singleton Instance
{
get
{
if (instance == null)
instance = new Singleton();
return instance;
}
}
//instance methods
}
แต่เท่าที่ฉันรู้ว่าทั้งสองวิธีได้รับการพิจารณาว่า 'ถูกต้อง' ดังนั้นมันจึงเป็นแค่เรื่องของรสนิยมส่วนตัว
using System;
using System.Collections.Generic;
class MainApp
{
static void Main()
{
LoadBalancer oldbalancer = null;
for (int i = 0; i < 15; i++)
{
LoadBalancer balancerNew = LoadBalancer.GetLoadBalancer();
if (oldbalancer == balancerNew && oldbalancer != null)
{
Console.WriteLine("{0} SameInstance {1}", oldbalancer.Server, balancerNew.Server);
}
oldbalancer = balancerNew;
}
Console.ReadKey();
}
}
class LoadBalancer
{
private static LoadBalancer _instance;
private List<string> _servers = new List<string>();
private Random _random = new Random();
private static object syncLock = new object();
private LoadBalancer()
{
_servers.Add("ServerI");
_servers.Add("ServerII");
_servers.Add("ServerIII");
_servers.Add("ServerIV");
_servers.Add("ServerV");
}
public static LoadBalancer GetLoadBalancer()
{
if (_instance == null)
{
lock (syncLock)
{
if (_instance == null)
{
_instance = new LoadBalancer();
}
}
}
return _instance;
}
public string Server
{
get
{
int r = _random.Next(_servers.Count);
return _servers[r].ToString();
}
}
}
ฉันเอารหัสจากdofactory.comไม่มีอะไรแฟนซี แต่ฉันพบว่ามันดีกว่าตัวอย่างกับ Foo และ Barนอกจากนี้หนังสือจาก Judith Bishop ใน C # 3.0 รูปแบบการออกแบบมีตัวอย่างเกี่ยวกับแอปพลิเคชันที่ใช้งานใน mac dock
ถ้าคุณดูโค้ดเรากำลังสร้างออบเจ็กต์ใหม่เพื่อลูปดังนั้นมันจะสร้างออบเจ็กต์ใหม่ แต่นำอินสแตนซ์กลับมาใช้ใหม่ซึ่งเป็นผลมาจากการที่โอเพ่นบาลานส์และนิวบาลานเซอร์มีอินสแตนซ์เดียวกัน เนื่องจากคำสำคัญคงที่ใช้ในฟังก์ชั่นGetLoadBalancer ()แม้จะมีค่าเซิร์ฟเวอร์ที่แตกต่างกันซึ่งเป็นรายการแบบสุ่มคงที่ในGetLoadBalancer ()เป็นประเภทของตัวเองมากกว่าวัตถุที่เฉพาะเจาะจง
นอกจากนี้ยังมีการตรวจสอบการล็อคซ้ำที่นี่
if (_instance == null)
{
lock (syncLock)
{
if (_instance == null)
ตั้งแต่จาก MSDN
คีย์เวิร์ด lock ทำให้แน่ใจว่าเธรดหนึ่งไม่ได้ป้อนส่วนที่สำคัญของโค้ดในขณะที่เธรดอื่นอยู่ในส่วนที่สำคัญ หากเธรดอื่นพยายามป้อนรหัสที่ถูกล็อคมันจะรอบล็อกจนกว่าวัตถุจะถูกปล่อยออกมา
ดังนั้นจึงมีการออกการล็อกการยกเว้นซึ่งกันและกันทุกครั้งแม้ว่าจะไม่จำเป็นต้องใช้ซึ่งไม่จำเป็นดังนั้นเราจึงตรวจสอบ null
หวังว่ามันจะช่วยในการล้างข้อมูลเพิ่มเติม
และโปรดแสดงความคิดเห็นหากฉันเข้าใจว่าฉันกำลังกำกับวิธีที่ผิด
Singleton (และนี่ไม่ได้เชื่อมโยงกับ C # มันเป็นรูปแบบการออกแบบ OO) คือเมื่อคุณต้องการอนุญาตให้สร้างคลาสได้เพียงอินสแตนซ์เดียวทั่วทั้งแอปพลิเคชันของคุณ โดยทั่วไปแล้วการใช้งานจะรวมถึงแหล่งข้อมูลทั่วโลกถึงแม้ว่าฉันจะบอกว่าจากประสบการณ์ส่วนตัวพวกเขามักจะเป็นแหล่งของความเจ็บปวดที่ยิ่งใหญ่
ในขณะที่มีเพียงหนึ่งตัวอย่างของซิงเกิลเท่านั้นมันไม่เหมือนกับคลาสแบบสแตติก คลาสสแตติกสามารถมีเมธอดแบบสแตติกเท่านั้นและไม่สามารถอินสแตนซ์ได้ในขณะที่อินสแตนซ์ของซิงเกิลอาจถูกใช้ในลักษณะเดียวกับวัตถุอื่น ๆ
มันเป็นรูปแบบการออกแบบและไม่เฉพาะเจาะจงกับ c # เพิ่มเติมเกี่ยวกับเรื่องนี้ทั้งหมดผ่านทางอินเทอร์เน็ตและอื่น ๆ เช่นนี้บทความวิกิพีเดีย
ในวิศวกรรมซอฟต์แวร์รูปแบบซิงเกิลเป็นรูปแบบการออกแบบที่ใช้เพื่อ จำกัด การสร้างอินสแตนซ์ของคลาสให้เป็นหนึ่งวัตถุ สิ่งนี้มีประโยชน์เมื่อต้องการวัตถุหนึ่งชิ้นเพื่อประสานการทำงานข้ามระบบ บางครั้งแนวคิดถูกทำให้เป็นแนวไปยังระบบที่ทำงานได้อย่างมีประสิทธิภาพมากขึ้นเมื่อมีวัตถุเพียงวัตถุเดียวเท่านั้นหรือ จำกัด การสร้างอินสแตนซ์ให้กับวัตถุจำนวนหนึ่ง บางคนคิดว่าเป็นรูปแบบการต่อต้านโดยตัดสินว่ามีการใช้มากเกินไปแนะนำข้อ จำกัด ที่ไม่จำเป็นในสถานการณ์ที่ไม่จำเป็นต้องใช้อินสแตนซ์ของคลาสเพียงอย่างเดียว
คุณควรใช้มันหากคุณต้องการชั้นเรียนที่สามารถเปิดใช้งานได้เพียงครั้งเดียว
ฉันใช้เพื่อค้นหาข้อมูล โหลดหนึ่งครั้งจาก DB
public sealed class APILookup
{
private static readonly APILookup _instance = new APILookup();
private Dictionary<string, int> _lookup;
private APILookup()
{
try
{
_lookup = Utility.GetLookup();
}
catch { }
}
static APILookup()
{
}
public static APILookup Instance
{
get
{
return _instance;
}
}
public Dictionary<string, int> GetLookup()
{
return _lookup;
}
}
Singleton คืออะไร:
เป็นคลาสที่อนุญาตให้สร้างอินสแตนซ์ของตัวเองเพียงหนึ่งตัวและมักจะให้การเข้าถึงอินสแตนซ์นั้นง่าย
เมื่อใดที่คุณควรใช้:
ขึ้นอยู่กับสถานการณ์
หมายเหตุ: โปรดอย่าใช้กับการเชื่อมต่อ db สำหรับคำตอบโดยละเอียดโปรดดูคำตอบของ @Chad Grant
นี่คือตัวอย่างง่ายๆของSingleton
:
public sealed class Singleton
{
private static readonly Singleton instance = new Singleton();
// Explicit static constructor to tell C# compiler
// not to mark type as beforefieldinit
static Singleton()
{
}
private Singleton()
{
}
public static Singleton Instance
{
get
{
return instance;
}
}
}
นอกจากนี้คุณยังสามารถใช้ในการสร้างของคุณLazy<T>
Singleton
ดูที่นี่สำหรับตัวอย่างโดยละเอียดเพิ่มเติมโดยใช้Lazy<T>
นี่คือความหมายของซิงเกิล: http://en.wikipedia.org/wiki/Singleton_pattern
ฉันไม่รู้ C # แต่จริงๆแล้วมันก็เหมือนกันในทุกภาษา
โดยทั่วไปคุณควรหลีกเลี่ยงซิงเกิลตันเมื่อเป็นไปได้ แต่ในบางสถานการณ์มันสะดวกมาก
ขออภัยภาษาอังกฤษของฉัน;)
คลาส Singleton ใช้เพื่อสร้างอินสแตนซ์เดียวสำหรับโดเมนแอปพลิเคชันทั้งหมด
public class Singleton
{
private static Singleton singletonInstance = CreateSingleton();
private Singleton()
{
}
private static Singleton CreateSingleton()
{
if (singletonInstance == null)
{
singletonInstance = new Singleton();
}
return singletonInstance;
}
public static Singleton Instance
{
get { return singletonInstance; }
}
}
ในบทความนี้มีการอธิบายถึงวิธีการที่เราสามารถสร้างคลาส singleton safe ที่ปลอดภัยโดยใช้ตัวแปร readonly และการใช้งานจริงในแอพพลิเคชัน
ฉันรู้ว่ามันสายเกินไปที่จะตอบคำถาม แต่ด้วยคุณสมบัติอัตโนมัติคุณสามารถทำสิ่งนี้ได้:
public static Singleton Instance { get; } = new Singleton();
อยู่ที่ไหนก็คือคุณระดับและสามารถที่จะผ่านในกรณีนี้อ่านได้อย่างเดียวคุณสมบัติSingleton
Instance
EX คุณสามารถใช้ Singleton สำหรับข้อมูลทั่วโลกที่จำเป็นต้องถูกฉีด
ในกรณีของฉันฉันเก็บรายละเอียดผู้ใช้ที่บันทึกไว้ (ชื่อผู้ใช้สิทธิ์ ฯลฯ ) ใน Global Static Class และเมื่อฉันพยายามที่จะใช้การทดสอบหน่วยไม่มีทางที่ฉันสามารถฉีดการพึ่งพาในชั้นเรียนควบคุมได้ ดังนั้นฉันได้เปลี่ยนรูปแบบการเรียนแบบคงที่เป็นแบบซิงเกิล
public class SysManager
{
private static readonly SysManager_instance = new SysManager();
static SysManager() {}
private SysManager(){}
public static SysManager Instance
{
get {return _instance;}
}
}
http://csharpindepth.com/Articles/General/Singleton.aspx#cctor
เราจำเป็นต้องใช้รูปแบบการออกแบบซิงเกิลตันใน C # เมื่อเราต้องการให้แน่ใจว่าจะมีการสร้างอินสแตนซ์ของคลาสที่เฉพาะเจาะจงเพียงอันเดียวจากนั้นให้การเข้าถึงระดับโลกที่ง่ายต่ออินสแตนซ์นั้นสำหรับแอปพลิเคชันทั้งหมด
สถานการณ์แบบเรียลไทม์ที่คุณสามารถใช้รูปแบบการออกแบบซิงเกิล: Service Proxies: เนื่องจากเรารู้ว่าการเรียกใช้ Service API เป็นการดำเนินการที่กว้างขวางในแอปพลิเคชัน กระบวนการที่ใช้เวลาส่วนใหญ่คือการสร้างไคลเอ็นต์บริการเพื่อเรียกใช้บริการ API หากคุณสร้างบริการพร็อกซี่เป็นซิงเกิลตันมันจะปรับปรุงประสิทธิภาพของแอปพลิเคชันของคุณ
Facades: คุณสามารถสร้างการเชื่อมต่อฐานข้อมูลเป็น Singleton ซึ่งสามารถปรับปรุงประสิทธิภาพของแอปพลิเคชัน
บันทึก: ในแอปพลิเคชันการดำเนินการ I / O บนไฟล์เป็นการดำเนินการที่มีราคาแพง หากคุณสร้าง Logger เป็น Singleton มันจะปรับปรุงประสิทธิภาพของการดำเนินการ I / O
การแบ่งปันข้อมูล: หากคุณมีค่าคงที่หรือค่าการกำหนดค่าคุณสามารถเก็บค่าเหล่านี้ไว้ใน Singleton เพื่อให้ส่วนประกอบเหล่านี้สามารถอ่านได้โดยแอปพลิเคชัน
แคช: เรารู้ดึงข้อมูลจากฐานข้อมูลเป็นกระบวนการที่ใช้เวลานาน ในแอปพลิเคชันของคุณคุณสามารถแคชต้นแบบและการกำหนดค่าในหน่วยความจำซึ่งจะหลีกเลี่ยงการเรียก DB ในสถานการณ์เช่นนี้คลาส Singleton สามารถใช้เพื่อจัดการแคชด้วยการซิงโครไนซ์เธรดในลักษณะที่มีประสิทธิภาพซึ่งช่วยปรับปรุงประสิทธิภาพการทำงานของแอปพลิเคชันได้อย่างมาก
ข้อเสียของรูปแบบการออกแบบ Singleton ใน C # ข้อเสียของการใช้รูปแบบการออกแบบ Singleton ใน C # มีดังนี้:
การทดสอบหน่วยเป็นเรื่องยากมากเพราะจะแนะนำสถานะสากลให้กับแอปพลิเคชัน มันลดโอกาสในการขนานในโปรแกรมเนื่องจากการเข้าถึงอินสแตนซ์ซิงเกิลในสภาพแวดล้อมแบบมัลติเธรดคุณจำเป็นต้องซีเรียลไลซ์วัตถุโดยใช้การล็อก
ฉันได้รับสิ่งนี้จากบทความต่อไปนี้
https://dotnettutorials.net/lesson/singleton-design-pattern/
Thread Singleton Safe โดยไม่ต้องใช้ตัวล็อคและไม่มีการสร้างอินสแตนซ์
การใช้งานนี้มีตัวสร้างแบบคงที่ดังนั้นจึงดำเนินการเพียงครั้งเดียวต่อโดเมนแอปพลิเคชัน
public sealed class Singleton
{
static Singleton(){}
private Singleton(){}
public static Singleton Instance { get; } = new Singleton();
}