بایگانی

Posts Tagged ‘Design Pattern’

Singleton Pattern

مارس 27, 2010 4 دیدگاه

Singleton یکی از الگوهای معمولی است که بسیاری از برنامه نویسان ازآن به وفور استفاده می کنند.هدف از این الگو این است که اطمینان حاصل شود که از یک کلاس فقط یک نمونه وجود داشته باشد.این نوع الگو می تواند در موارد زیادی مفید باشد از جمله:

  • وقتی منابع بار زیادی داشته باشند مانند Linq Data Context
  • برنامه های چند نخی که ممکن است در نخ های دیگر سعی به ایجاد نمونه دیگری ازکلاس مورد نظر باشد
  • Global Resources
  • و موارد زیادی از این قبیل

در یک کلاس Singleton دو چیز مورد نیاز خواهد بود:

  1. یک متغیر private static که نمونه مورد نظر از کلاس را نگه می دارد
  2. یک متد static که این نمونه را برمی گرداند

البته این موارد به موارد زیر جهت بهبود الگو تغییر پیدا میکنند:

  1. یک سازنده private که البته اگر این سازنده static باشد بهتر است
  2. یک متغیر private static که نمونه مورد نظر از کلاس را نگه می دارد
  3. یک پروپرتی public static که این نمونه را برمی گرداند

یک نمونه که با توجه به تعاریف موجود می توان نشان داد کد زیر است:

1 public class SingletonPattern

2 {

3 private SingletonPattern() { }

4

5 private static SingletonPattern instance = new SingletonPattern();

6 public static SingletonPattern GetInstance

7 {

8 get

9 {

10 return instance;

11 }

12 }

13 }

و نحوه فراخوانی آن هم به شکل زیر خواهد بود:

1 SingletonPattern s = SingletonPattern.GetInstance;

خوب همانطور که از این نحوه پیاده سازی پیداست، متغیر ما static است.یعنی فقط یکبار ایجاد خواهد شد.برای اینکه این موضوع را متوجه بشوید اجازه بدید دو نمونه از این کلاس ایجاد کنیم:

1 SingletonPattern s1 = SingletonPattern.GetInstance;

2 SingletonPattern s2 = SingletonPattern.GetInstance;

اگرچه این کد دو نمونه متفاوت را ایجاد میکند، اما هردو نمونه به یک شی ارجاع داده می شوند.کد زیر این مسئله را نشان میدهد:

1 public class Program

2 {

3 public static void Main(string[] args)

4 {

5 SingletonPattern s1 = SingletonPattern.GetInstance;

6 SingletonPattern s2 = SingletonPattern.GetInstance;

7

8 if (s1 == s2)

9 Console.WriteLine(«Refer to the same object»);

10

11 Console.ReadLine();

12 }

13 }

اما الگویی که تا الان ما طراحی کردیم thread-safe نخواهد بود.یعنی ممکن است نخ دیگری همزمان اقدام به ایجاد کلاس کند.یک راه این است که ایجاد کلاس را lock کنید.به کد زیر توجه کنید:

1 public class SingletonPattern

2 {

3 private SingletonPattern() { }

4

5 private static SingletonPattern instance = new SingletonPattern();

6 public static SingletonPattern GetInstance

7 {

8 get

9 {

10 lock (typeof(SingletonPattern))

11 {

12 if (instance != null)

13 instance = new SingletonPattern();

14 }

15 return instance;

16 }

17 }

18

19 }

اما مشکلی که این روش دارد این است که احتمال وقوع بن بست را افزایش خواهد داد.بهترین راه برای این کار Lazy Instantiation خواهد بود.در این روش نمونه گیری از کلاس Singleton در یک کلاس تودرتو (Nested Class) انجام میشود.

1 public class SingletonPattern

2 {

3 private SingletonPattern() { }

4

5 class SingletonCreator

6 {

7 private static SingletonCreator() { }

8 internal static readonly SingletonPattern instance =

9 new SingletonPattern();

10 }

11

12 public static SingletonPattern GetInstance

13 {

14 get

15 {

16 return SingletonCreator.instance;

17 }

18 }

19

20 }

نکته ای که می توان به آن اشاره کرد این است که در Perfoemance این روش نسبت به روش قبل کارایی بیشتری دارد.

Vote on iDevCenter

Advertisements
دسته‌ها:C#.Net برچسب‌ها: , , ,