آموزش های این وب سایت به صورت رایگان در دسترس است. اطلاعات بیشتر
مشکل عدم دسترسی خریداران پیشین به برخی آموزش ها برطرف شد
بروز خطا
   [message]
اشتراک در سوال
رای ها
[dataList]

Singleton pattern

محسن موحد  9 سال پیش  5 سال پیش
+14 0

سلام.
قبلا مطلبی نوشتم در این لینک , که در اینکلود کردن فایل هاتون به مشکل نخورید.
این مشکل در ساخت آبجکت از یک کلاس هم وجود داره.
در جاهای مختلف پروژه ما از یک کلاس , آبجکتی میسازیم و ممکنه چندین بار در پروژه عمل new کردن و ساختن یک آبجکت از کلاس رو انجام داده باشیم , اما گاهی اوقات سناریو به این شکل است که ما در هر بار اجرای اسکریپت نیاز به ساخت یک آبجکت از کلاس داریم و نمیخوایم چندین بار در پروژه از اون کلاس ,  آبجکت ساخته بشه.

برای حل این مشکل از معماری Singleton استفاده میکنیم.
با استفاده از این معماری , دیگه نیاز نیست به فکر چند بار آبجکت ساختن , باشیم و با خیال راحت در همه ی جای پروژه , آبجکتی از کلاس میسازیم و تنها در صورت وجود نداشتن شی ء , آبجکت جدید ساخته میشه.

در کلاسی که میخوایم از معماری Singleton استفاده کنیم , کافیه یک متد static بسازیم.
یک نمونه از معماری در کلاس دیتابیسمون:

class Database
{
    private static $instance;
 
    public function __construct()
    {
    	// connection
    }
 
 	// Singleton Design Pattern
    public static function getInstance()
    {
        if(self::$instance === null)
        {
            self::$instance = new Database();
        }
        return self::$instance;
    }
}

* متد های static , مانند function های خارج از کلاس هستن و برای فراخوانی آبجکتی نمیسازیم.

حالا برای صدا زدن کلاس , در پروژه متد getInstance رو صدا بزنیم.به این صورت:

// this is an object of db class
$obj = Database::getInstance();

* متد های static برای صدا زدن , اول نام کلاس مربوطه میاد و بعد از (::) , نام متد.

اگر چندین بار پشت سر هم صدا بزنید , باز هم یک آبجکت ساخته میشه.بخاطر وجود این شرط:

if(self::$instance === null)

 

روش دیگری برای پیاده سازی این معماری:

class Singleton
{
    private static $instance;
    public function __construct()
    {
        if(!self::$instance)
        {
            self::$instance = $this;
            echo 'a new object is created...';
        }
        return self::$instance;
    }
}

$obj1 = new Singleton();
$obj2 = new Singleton();
$obj3 = new Singleton();
$obj4 = new Singleton();
$obj5 = new Singleton();

اینجا چون کدهای مربطه رو در constructor نوشتیم , در هر بار new اولین کدهایی که اجرا میشن , کدهای سازنده (constructor) هستن , یعنی با هربار new کردن کلاس , متد constructor صدا زده میشه.

* در تمام new کردن ها ازین کلاس , تنها یکبار , آبجکت ساخته میشه.

+2 0
دوستان , این معماریو ازش آسون نگذرینااااااا.. یکی از بزرگترین معظلات در پروژه ها رو رفع میکنه. فریمورک ها هم ازین معماری ها استفاده میکنن. (9 سال پیش)
 برای این سوال 1 پاسخ وجود دارد.
پاسخ به سوال 
ashiyanehamid  5 سال پیش
+1 0

ممنون از مقاله خوبتون. و این که ببخشید مطلب زیر آبی رو بالا میارم ولی خب من تازه دارم آموزش‌ها رو می‌بینم و رسیدم به مبحث patern design singleton
در داخل constructor کلاس دیتابیسمون، در ابتدا می‌تونیم بهش پارامتر پاس بدیم و بگیم به فلان دیتابیس با فلان مشخصات conect شو. اگرم option ندیم، می‌ره و از فایل config.php اطلاعات اولیه لازم برای ارتباط با دیتابیس رو می‌گیره. استاد توی آموزش فرمودن بسته به این که در اولین با فراخوانی متد getInstance، بهش option بدیم یا ندیم، تا آخر همون option رو در نظر میگیره و دیگه تغییری داخلش نمیده(که البته اینم فرمودن که امکان این که بخوایم option های یه دیتابیس رو تغییر بدیم یک به هزاره. مثلا بخوایم از یه دیتابیس دیگه استفاده کنیم باید نام متفاوتی رو بهش ارسال کنیم داخل آرایه‌ی option) ولی دیگه چون getInstance قبلا یه نمونه از کلاس دیتابیس ساخته، دیگه شرط if بررسی میشه و چون میبینه قبلا یه نمونه ساخته، همون نمونه رو return میکنه. خب حالا اگه با وجود احتمال خیلی ضعیف باز بخوایم یه option جدید بفرستیم چاره چیه(مثلا سایت از 2 تا دیتابیس استفاده میکنه)؟
راه حلی که به ذهن خودم میرسه اینه که یه lastOption از نوع static داشته باشیم و بگیم هر بار که کاربر خواست getInstance بکنه، بیا و بررسی کن option جدیدی که فرستاده شده رو و ببین آیا با lastOption برابری میکنه یا نه. اگه برابر بود و یا کاربر option نفرستاده بود(null فرستاده بود)، پس یعنی درخواستِ اتصال به همون دیتابیس قبلی از طرف کاربر صادر شده و نیازی به تغییر نیست و همون نمونه قبلی رو بهش return کنیم. ولی اگه lastOption با option جدیدی که فرستاده شده همخوانی نداشت، پس نیاز به ساخت نمونه جدید هست.
دوستان میشه راهنمایی بفرمایید که این سناریو مشکل داره یا نه. با تشکر

+2 0
یه راه ساده تر یه متد دیگه درست کنید getIntanseDbNew() و توی این این درخواست رو هندل کنید و یه نمونه دیگه بسازید درکل از دیزاین پترن سینگلتون وقتی استفاده میشه که بخایم فقط یه نمونه از کلاس داشته باشیم اما با یه تابع دیگه میتونید یه نمونه دیگه هم بسازید و ازش استفاده کنید اما اگه تعداد بیشتری هست بنظرم منطقی نیست که از سینگلتون استفاده کنید. (5 سال پیش)
+1 0
بله درسته شما سینگلتون رو با یک شرط پیاده سازی میکنید. دست شما برای پیاده سازی هر نوع کدی بازه. (5 سال پیش)

پاسخگویی و مشاهده پاسخ های این سوال تنها برای اعضای ویژه سایت امکان پذیر است .
چنانچه تمایل دارید به همه بخش ها دسترسی داشته باشید میتوانید از این بخش لایسنس این آموزش را خریداری نمایید .