سؤال

ما فائدة استخدام المفرد بدلاً من العمومي لاتصالات قاعدة البيانات في PHP؟أشعر أن استخدام المفرد بدلاً من العمومي يجعل الكود معقدًا بلا داع.

كود مع العالمية

$conn = new PDO(...);

function getSomething()
{
    global $conn;
    .
    .
    .
}

كود مع سينجلتون

class DB_Instance
{
    private static $db;

    public static function getDBO()
    {
        if (!self::$db)
            self::$db = new PDO(...);

        return self::$db;
    }
}

function getSomething()
{
    $conn = DB_Instance::getDBO();
    .
    .
    .
}

إذا كانت هناك طريقة أفضل لتهيئة اتصال قاعدة البيانات بخلاف الاتصال العام أو الفردي، فيرجى ذكرها ووصف المزايا التي تتمتع بها مقارنة بالاتصال العمومي أو الفردي.

هل كانت مفيدة؟

المحلول

أعرف أن هذا قديم، لكن إجابة Dr8k كانت كذلك بالكاد هناك.

عندما تفكر في كتابة جزء من التعليمات البرمجية، افترض أنه سيتغير.هذا لا يعني أنك تفترض أنواع التغييرات التي ستطرأ عليها في مرحلة ما في المستقبل، بل يعني أنه سيتم إجراء شكل من أشكال التغيير.

اجعله هدفًا يخفف من ألم إجراء التغييرات في المستقبل:العالمية خطيرة لأنه من الصعب إدارتها في مكان واحد.ماذا لو كنت أرغب في جعل سياق اتصال قاعدة البيانات هذا واعيًا في المستقبل؟ماذا لو كنت أرغب في إغلاقه وإعادة فتحه في كل مرة خامسة يتم استخدامه فيه.ماذا لو قررت أنه من أجل توسيع نطاق تطبيقي، أريد استخدام مجموعة مكونة من 10 اتصالات؟أو عدد شكلي من الاتصالات؟

أ مصنع مفرد يمنحك تلك المرونة.لقد قمت بإعداده مع القليل جدًا من التعقيد الإضافي واكتسبت أكثر من مجرد الوصول إلى نفس الاتصال؛لقد اكتسبت القدرة على تغيير كيفية تمرير هذا الاتصال إليّ لاحقًا بطريقة بسيطة.

لاحظ أن أقول مصنع مفرد على عكس ببساطة مفرد.هناك فرق بسيط ثمين بين المفردة والعالمية، هذا صحيح.ولهذا السبب، ليس هناك سبب لوجود اتصال فردي:لماذا تقضي الوقت في إعداد ذلك بينما يمكنك إنشاء عالمي عادي بدلاً من ذلك؟

ما يحصل عليه المصنع هو سبب حصولك على الاتصالات، ومكان منفصل لتحديد الاتصالات (أو الاتصال) التي ستحصل عليها.

مثال

class ConnectionFactory
{
    private static $factory;
    private $db;

    public static function getFactory()
    {
        if (!self::$factory)
            self::$factory = new ConnectionFactory(...);
        return self::$factory;
    }

    public function getConnection() {
        if (!$this->db)
            $this->db = new PDO(...);
        return $this->db;
    }
}

function getSomething()
{
    $conn = ConnectionFactory::getFactory()->getConnection();
    .
    .
    .
}

بعد ذلك، في غضون 6 أشهر، عندما يصبح تطبيقك مشهورًا جدًا ويتم البحث عنه وتقطيعه وتقرر أنك بحاجة إلى أكثر من اتصال واحد، كل ما عليك فعله هو تنفيذ بعض التجميع في طريقة getConnection().أو إذا قررت أنك تريد برنامج تضمين يقوم بتنفيذ تسجيل SQL، فيمكنك تمرير فئة فرعية PDO.أو إذا قررت أنك تريد اتصالاً جديدًا في كل استدعاء، فيمكنك القيام بذلك.انها مرنة، بدلا من جامدة.

16 سطرًا من التعليمات البرمجية، بما في ذلك الأقواس، مما سيوفر لك ساعات وساعات وساعات من إعادة البناء لشيء مشابه بشكل مخيف في المستقبل.

لاحظ أنني لا أعتبر هذا "زحف الميزات" لأنني لا أقوم بتنفيذ أي ميزة في الجولة الأولى.إنه خط حدودي "زحف المستقبل"، ولكن في مرحلة ما، تكون فكرة "الترميز للغد اليوم". دائماً شيء سيء لا يريحني.

نصائح أخرى

لست متأكدًا من أنني أستطيع الإجابة على سؤالك المحدد، ولكني أردت أن أقترح أن كائنات الاتصال العامة/المفردة قد لا تكون أفضل فكرة إذا كان ذلك لنظام قائم على الويب.تم تصميم أنظمة إدارة قواعد البيانات بشكل عام لإدارة أعداد كبيرة من الاتصالات الفريدة بطريقة فعالة.إذا كنت تستخدم كائن اتصال عمومي، فأنت تفعل أمرين:

  1. إجبارك على القيام بجميع اتصالات قاعدة البيانات بالتتابع وقتل أي محاولات في تحميل الصفحة غير المتزامنة.

  2. يحتمل أن يحمل أقفال مفتوحة على عناصر قاعدة البيانات لفترة أطول من اللازم ، مما يتباطأ أداء قاعدة البيانات بشكل عام.

  3. الحد من إجمالي عدد الاتصالات المتزامنة التي يمكن أن تدعم قاعدة البيانات الخاصة بك ومنع المستخدمين الجدد من الوصول إلى الموارد.

أنا متأكد من أن هناك عواقب محتملة أخرى أيضًا.تذكر أن هذه الطريقة ستحاول الحفاظ على اتصال قاعدة البيانات لكل مستخدم يصل إلى الموقع.إذا كان لديك مستخدم واحد أو اثنين فقط، فلا مشكلة.إذا كان هذا موقعًا عامًا وتريد حركة المرور، فستصبح قابلية التوسع مشكلة.

[يحرر]

في المواقف الأكبر حجمًا، قد يكون إنشاء اتصالات جديدة في كل مرة تضغط فيها على قاعدة البيانات أمرًا سيئًا.ومع ذلك، فإن الإجابة لا تكمن في إنشاء اتصال عالمي وإعادة استخدامه في كل شيء.الجواب هو تجمع الاتصالات.

مع تجمع الاتصالات، يتم الحفاظ على عدد من الاتصالات المتميزة.عندما يطلب التطبيق الاتصال، يتم استرداد أول اتصال متاح من المجمع ثم يتم إعادته إلى المجمع بمجرد انتهاء مهمته.إذا تم طلب الاتصال ولم يكن أي اتصال متاحًا، فسيحدث أحد أمرين:أ) إذا لم يتم الوصول إلى الحد الأقصى لعدد الاتصال المسموح به، فسيتم فتح اتصال جديد، أو ب) يضطر التطبيق إلى الانتظار حتى يصبح الاتصال متاحًا.

ملحوظة: في لغات .Net، تتم معالجة تجمع الاتصالات بواسطة كائنات ADO.Net بشكل افتراضي (تقوم سلسلة الاتصال بتعيين كافة المعلومات المطلوبة).

شكرا لكراد للتعليق على هذا.

تم إنشاء الطريقة المفردة للتأكد من وجود مثيل واحد فقط لأي فئة.ولكن لأن الناس يستخدمونها كوسيلة لاختصار العولمة، فإنها تصبح معروفة بالبرمجة الكسولة و/أو السيئة.

لذلك، سأتجاهل global وSingleton نظرًا لأن كلاهما ليسا OOP حقًا.

ما كنت تبحث عنه هو حقن التبعية.

يمكنك التحقق من المعلومات المستندة إلى PHP سهلة القراءة والمتعلقة بحقن التبعية (مع أمثلة) على http://components.symfony-project.org/dependency-injection/trunk/book/01-Dependency-Injection

يحقق كلا النمطين نفس التأثير الصافي، مما يوفر نقطة وصول واحدة لاستدعاءات قاعدة البيانات الخاصة بك.

فيما يتعلق بالتنفيذ المحدد، يتمتع المفرد بميزة صغيرة تتمثل في عدم بدء اتصال قاعدة البيانات حتى تطلبه إحدى الطرق الأخرى على الأقل.من الناحية العملية، في معظم التطبيقات التي كتبتها، لا يُحدث هذا فرقًا كبيرًا، ولكنها ميزة محتملة إذا كان لديك بعض الصفحات/مسارات التنفيذ التي لا تقوم بأي استدعاءات لقاعدة البيانات على الإطلاق، نظرًا لأن هذه الصفحات لن تقوم بذلك من أي وقت مضى طلب اتصال بقاعدة البيانات.

أحد الاختلافات الطفيفة الأخرى هو أن التنفيذ الشامل قد يدوس على أسماء المتغيرات الأخرى في التطبيق عن غير قصد.من غير المحتمل أن تعلن عن مرجع عالمي آخر $db عن طريق الخطأ، على الرغم من أنه من الممكن أن تقوم بالكتابة فوقه عن طريق الخطأ (على سبيل المثال، تكتب if($db = null) عندما تقصد الكتابة if($db == null).الكائن المفرد يمنع ذلك.

إذا كنت لن تستخدم اتصالًا مستمرًا، وكانت هناك حالات لعدم القيام بذلك، أجد أن الاتصال الفردي أكثر قبولًا من الناحية النظرية من الاتصال العالمي في تصميم OO.

في بنية OO الحقيقية، يكون المفرد أكثر فعالية من إنشاء مثيل جديد للكائن في كل مرة.

في المثال المذكور، لا أرى أي سبب لاستخدام المفردات.كقاعدة عامة، إذا كان اهتمامي الوحيد هو السماح بمثيل واحد لكائن ما، وإذا كانت اللغة تسمح بذلك، فإنني أفضل استخدام العناصر العالمية

بشكل عام سأستخدم مفردًا للاتصال بقاعدة البيانات ...لا تريد إنشاء اتصال جديد في كل مرة تحتاج فيها إلى التفاعل مع قاعدة البيانات...قد يؤدي هذا إلى الإضرار بالأداء وعرض النطاق الترددي لشبكتك ...لماذا إنشاء واحدة جديدة، عندما يكون هناك واحدة متاحة...فقط 2 سنتي...

روندي

انها بسيطة جدا.لا تستخدم أبدًا Global OR Singleton.

كنصيحة على حد سواء مفرد و عالمي صالحة ويمكن الانضمام إليها في نفس الوقت النظام، المشروع، البرنامج المساعد، المنتج، الخ ...في حالتي، أقوم بصنع منتجات رقمية للويب (مكون إضافي).

أنا استخدم فقط مفرد في الفصل الرئيسي وأنا استخدامه من حيث المبدأ.لا أستخدمه تقريبًا لأنني أعلم أن الفصل الرئيسي لن يقوم بإنشاء مثيل له مرة أخرى

<?php // file0.php

final class Main_Class
{
    private static $instance;
    private $time;

    private final function __construct()
    {
        $this->time = 0;
    }
    public final static function getInstance() : self
    {
        if (self::$instance instanceof self) {
            return self::$instance;
        }

        return self::$instance = new self();
    }
    public final function __clone()
    {
        throw new LogicException("Cloning timer is prohibited");
    }
    public final function __sleep()
    {
        throw new LogicException("Serializing timer is prohibited");
    }
    public final function __wakeup()
    {
        throw new LogicException("UnSerializing timer is prohibited");
    }
}

عالمي يستخدم لجميع الصفوف الثانوية تقريبًا، على سبيل المثال:

<?php // file1.php
global $YUZO;
$YUZO = new YUZO; // YUZO is name class

أثناء وقت التشغيل يمكنني استخدامه عالمي لاستدعاء أساليبهم وسماتهم في نفس المثيل لأنني لا أحتاج إلى مثيل آخر لفئة المنتج الرئيسية الخاصة بي.

<?php // file2.php
global $YUZO;
$YUZO->method1()->run();
$YUZO->method2( 'parameter' )->html()->print();

ما أتعامل معه مع العالمية هو استخدام نفس المثيل حتى أتمكن من تشغيل المنتج لأنني لا أحتاج إلى مصنع لمثيلات من نفس الفئة، وعادةً ما يكون مصنع المثيل مخصصًا للأنظمة الكبيرة أو لأغراض نادرة جدًا.

In conclusion:, ، يجب عليك إذا كنت تفهم جيدًا أن هذا هو النمط المضاد سينجلتون وفهم عالمي, ، يمكنك استخدام أحد الخيارين أو المزج بينهما ولكن إذا أوصي بعدم إساءة الاستخدام نظرًا لوجود العديد من المبرمجين الاستثنائيين جدًا والمخلصين للبرمجة OOP، فاستخدمه للفئات الرئيسية والثانوية التي تستخدمها كثيرًا في التنفيذ وقت.(يوفر لك الكثير من وحدة المعالجة المركزية).😉

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top