Table of Contents
مقدمه: الگوی تکتون در برنامه های مهندسی چند بعدی
الگوی تکتون یکی از الگوهای طراحی گسترده ترین در مهندسی نرم افزار است.این تضمین می کند که یک کلاس فقط یک نمونه دارد و یک نقطه جهانی از دسترسی به آن نمونه را فراهم می کند.در برنامه های تک-تخوان، پیاده سازی تکتون ساده است: ساخت و ساز خصوصی، ارائه یک روش استاتیک است که یک نمونه را به طور مشتاقانه یا لازی، با این حال، سیستم های تعمیر و نگهداری چند منظوره، سیستم های کنترل دقیق تر، می تواند منجر به عنوان سیستم های تعمیر و سیستم های کنترل دقیق تر شود.
این مقاله رایج ترین اشتباهاتی را که توسعه دهندگان هنگام پیاده سازی الگوی تکتون در محیط های چند رشته ای انجام می دهند، توضیح می دهد علل اساسی و مجموعه ای جامع از بهترین شیوه ها و الگوهای برای جلوگیری از آنها را فراهم می کند.همچنین شامل نمونه های کد عملی در جاوا، با ارجاع به الگوهای معادل در C++ و C#، و توصیه منابع خارجی برای مطالعه بیشتر.
اشتباهات رایج در اجرای تکتون
حتی توسعه دهندگان با تجربه می توانند در هنگام اجرای تکتون ها در سیستم های همزمان، به دام بیفتند.در زیر اغلب خطا هستند، هر کدام با توضیحی درباره اینکه چرا خطرناک هستند.
۱- ساخت و ساز خصوصی
پایه هر تکتون یک سازنده خصوصی است که مانع از فوری سازی خارجی می شود.اگر سازنده قابل دسترس باشد (عمومی، محافظت شده یا بسته خصوصی)، هر رشته می تواند یک نمونه جدید ایجاد کند، قرارداد تکتون را شکستن کند.در کد چند طبقه، این می تواند به طور ناخواسته اتفاق بیفتد زمانی که یک کلاس دوباره محافظت می شود و دید ساختاری به طور تصادفی تغییر می کند یا زمانی که کلاس باید یک زیر کلاس را اعلام کند (اگر یک رفتار خصوصی را تایید کند).
۲- عدم مدیریت ایمنی Thread Safety
در یک محیط تک نفره، یک اولیه ساده تنبل کار می کند:
public class Singleton {
private static Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
در یک برنامه چند نفره، دو یا چند رشته می تواند به طور همزمان وارد [FLT1] بررسی قبل از هر رشته نمونه شده است.هر رشته سپس به ایجاد خود را (FLT:2 شی، نقض الگوی کلاسیک مشکل است که در موارد متعدد و منجر به نشت منابع یا نشت منابع متناقض می شود.
استفاده از Lazy اولیه سازی بدون Synchronization مناسب
حتی توسعه دهندگانی که نیاز به ایمنی ریسمان را تشخیص می دهند، اغلب به طور ساده ای هماهنگ می شوند.برای مثال، همگام سازی کل روش [FLT3] اما یک تنگنا عملکردی را معرفی می کنند:
public static synchronized Singleton getInstance() { ... }
هر کس از این طریق به آن اشاره می کند، پس از آنکه در آن زمان به صورت مستقیم به آن اشاره می کند، در این حالت، این خط به شدت می تواند از طریق خروجی کاهش یابد و از آن استفاده کند، بهتر است که از آن استفاده کند (FLT:0) قفل دو چک شده (داساساساساسه زیر) اما حتی اگر به درستی اجرا نشده باشد.
۴- استفاده از Synchronization
تقسیم بندی در بسیاری از اشکال وجود دارد: روش ها بلوک ها، و غیره [و غیره] بیش از حد ترکیب - به طور قابل توجهی قفل های ضخیم ریشه دار هنگامی که کنترل دانه های ریز در دسترس است - منجر به محتوای غیر ضروری است.
↑ «[[ویرایش] [۱]
در زبان هایی مانند جاوا، C# و ++C (با استفاده از fLT:10)، volatile کلمه کلیدی (یا معادل) برای مشاهده صحیح در کد چند ثانیه ضروری است، بدون آن، کامپایلر یا CPU ممکن است دستورالعمل های جزئی را سفارش دهد، و تغییرات ایجاد شده توسط یک موضوع ممکن است برای قفل کردن یک الگوی دیگر قابل مشاهده نباشد.
بهترین روش برای پیاده سازی تکتون Thread-Safe
برای جلوگیری از این مشکلات، از این استراتژی های اثبات شده پیروی کنید.هر رویکرد به ایمنی، عملکرد و سادگی موضوعات می پردازد.
سازنده خصوصی و Apache
صرف نظر از استراتژی اولیه سازی، سازنده باید خصوصی باشد. نمونه تکتون باید در یک زمینه استاتیک ذخیره شود.
استفاده از بلوک های Synchronized تنها در صورت لزوم
برای شروع تنبل، الگوی قفل دو چک شده باعث کاهش سرعت هماهنگ سازی می شود:
public class Singleton {
private static volatile Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
Singleton result = instance; // Local variable for performance
if (result == null) {
synchronized (Singleton.class) {
result = instance;
if (result == null) {
instance = result = new Singleton();
}
}
}
return result;
}
}
در این کد، چک خارج از بلوک همگام سازی شده اجتناب از قفل سر در زمانی که نمونه وجود دارد. چک داخلی تضمین می کند که تنها یک رشته ایجاد نمونه. [FLT16] کلمه کلیدی جلوگیری از دستور دوباره سفارش و تضمین می کند که تخصیص (FLT:17 به طور کامل قابل مشاهده برای دیگر موضوعات توجه است که ما نمونه را برای یک متغیر حافظه محلی (FLT + C) به طور مشابه کار می کند.
آغاز اولیه سازی Eager
اگر تکتون همیشه مورد نیاز است و ایجاد ارزان است، اولیه مشتاق ساده ترین رویکرد ایمنی است:
public class Singleton {
private static final Singleton INSTANCE = new Singleton();
private Singleton() {}
public static Singleton getInstance() {
return INSTANCE;
}
}
بارگذاری کلاس به طور ذاتی توسط JVM همگام سازی شده است، بنابراین هیچ هماهنگی اضافی مورد نیاز نیست، با این حال، این مثال را در زمان بارگذاری کلاس ایجاد می کند، که ممکن است در سیستم های آموزش دیده منابع نامطلوب باشد یا هنگامی که تکتون به پیکربندی زمان اجرا بستگی دارد که هنوز در دسترس نیست.
الگوی دارندگان استاتیک (Initialization-on-Request)
این الگو ترکیب اولیه تنبلی با ایمنی نخ بدون هماهنگ سازی صریح:
public class Singleton {
private Singleton() {}
private static class Holder {
static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return Holder.INSTANCE;
}
}
کلاس تنها زمانی بارگذاری می شود که [FLT 22] برای اولین بار نامیده می شود، و JVM تضمین می کند انتشار امن از میدان استاتیک در طول بارگذاری کلاس، این به طور گسترده به عنوان زیباترین راه حل برای تکتون جاوا در نظر گرفته شده است.
تکتون های تکتون (Java)
در این میان، جاشوا برک (فَلَهُمْهُمْهُمِنْهُمِهُمِهُمِهُمِهُمِهُمِهُوا) توصیه می کند که از آن استفاده کنید:
public enum Singleton {
INSTANCE;
// methods and fields
}
ثابت های Enum به طور ضمنی (FLT:24) و تضمین زبان جاوا است که موارد enum تنها یک بار ایجاد می شوند، حتی در حملات سریال سازی یا انعکاس، این هم امن و هم مختصر است، با این حال، enum ها نمی توانند کلاس ها را گسترش دهند (فقط رابط های پیاده سازی)، بنابراین آنها برای همه موارد استفاده مناسب نیستند.
الگوهای معادل در C++ و C#
در C++، تکتون های تکتون (FLT:1) از C++11 به صورت زیر ایمن هستند:
Singleton& getInstance() {
static Singleton instance;
return instance;
}
در C#، کلاس [FLT 26] یک شروع تنبل سازی داخلی را فراهم می کند:
public class Singleton {
private static readonly Lazy<Singleton> _lazy =
new Lazy<Singleton>(() => new Singleton());
public static Singleton Instance => _lazy.Value;
}
تست و بررسی در برنامه های مهندسی
در برنامه های مهندسی، الگوی تکتون اغلب منابع مشترک مانند رانندگان سخت افزار، تنظیمات تنظیمات، استخرهای رشته یا خدمات ورود را مدیریت می کند. تست چنین تکتون هایی در تست های چند رشته ای نیاز به طراحی دقیق دارد:
- تکتون ها را تست کنید با ارائه یک راه برای تنظیم مجدد نمونه (به عنوان مثال، یک روش محافظت شده تنها در آزمون استفاده می شود) یا با تزریق وابستگی از طریق یک رابط. بسیاری از برنامه های مدرن به طور کامل به نفع وابستگی به چارچوب های تزریق که مدیریت چرخه عمر.
- پروفایل تعدیل در سیستم های زمان واقعی یا با فرکانس بالا: اندازه گیری سربار هماهنگ سازی.در برخی موارد، یک تکتون بدون قفل با استفاده از [FLT 29] (C#) یا (C++) ممکن است توجیه شود.
- سیستم های توزیع شده نیاز به تکتون برای منحصر به فرد بودن در هر فرایند، نه در سراسر فرآیندها.اگر شما نیاز به یک تکتون خوشه ای، استفاده از هماهنگی خارجی (به عنوان مثال، یک پایگاه داده، باغ وحشKeeper یا انتخابات رهبر).
- بازتاب و سریال سازی می تواند تکتون ها را بشکند (FLT 31) در جاوا و جلوگیری از بازتاب فوری با پرتاب یک استثناء در سازنده اگر در حال حاضر تنظیم شده است.
نتیجه گیری
الگوی تکتون یک ابزار ارزشمند در جعبه ابزار مهندس نرم افزار است، اما پیاده سازی آن در محیط های چند منظوره نیاز به توجه دقیق به جزئیات دارد.با درک و اجتناب از اشتباهات رایج - مانند سازنده های غیر خصوصی، هماهنگ سازی از دست رفته، استفاده نامناسب و اضافه کردن ویژگی های نرم افزار - توسعه دهندگان می توانند قوی، عملکرد بالا تکتون را تولید کنند.
برای مطالعه بیشتر، به منابع زیر اشاره کنید:
- [[ویرایش] [۱] [۱] [۱] [۲] [۱] [۲]] [۱] [۱] [۱] [۱] [۱]
- [[ویرایش] [۱] [۱۰] [۱]
- [[ویرایش] [۱] [۲] [۱] [۲] [۱] [۲] [۱] [۱] [۱] [۱] [۱] [۲] [۱] [۲] [۱] [۱] [۲] [۱]
- مدل تکتون مایکروسافت [FLT 1]
در نهایت، بهترین پیاده سازی تکتون، یکی از ساده ترین گزینه ها برای نیازهای شما است، زمانی که شک دارید، ترجیح می دهید که اولیه سازی مشتاق یا الگوی دارنده استاتیک را ترجیح دهید و همیشه تست های واحد همزمان را برای اعتباربخشی به اصلاح در زیر محتوا بنویسید.