سؤال

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

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

المحلول

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

تحرير: منذ أن تم قبول هذه الإجابة، قررت تقديم مثال، لصالح القراء في المستقبل. أيضا، لا تنس تحديد كل فصولك نهائيا.

الطبقة الأساسية:

final class myPrimaryClass {

    private static $instance = null;

    private function __construct() {
        // do something or not
        return $this;
    }

    public static function getInstance() {
        if (is_null(self::$instance) || !(self::$instance instanceof myPrimaryClass))
            self::$instance = new myPrimaryClass;
        return self::$instance;
    }
}

Singleton Subclass:

final class mySingletonSubClass {

    private static $instance = null;

    private function __construct(myPrimaryClass $primaryClassInstanceRef) {
        return $this;
    }

    public static function getInstance(myPrimaryClass $primaryClassInstanceRef) {
        if (is_null(self::$instance) || !(self::$instance instanceof mySingletonSubClass))
            self::$instance = new mySingletonSubClass($primaryClassInstanceRef);
        return self::$instance;
    }
}

Subclass المصنع:

final class myFactorySubClass {

    private function __construct(myPrimaryClass $primaryClassInstanceRef) {
        return $this;
    }

    public static function getNewInstance(myPrimaryClass $primaryClassInstanceRef) {
        return new myFactorySubClass($primaryClassInstanceRef);
    }
}

اثنين من الملاحظات حول هذا المثال؛ أولا، بالطبع أنا أكثر تباطؤ بالمسألة. ثانيا، خدعة أنيقة واحدة يمكنك استخدامها هي تعديل الفئات الفرعية قليلا بحيث getInstance() لا تحتاج الأساليب دائما إلى أن يكون لديك مثيل للفئة الأساسية التي تم تمريرها كوسيطة بعد المرة الأولى. سأقدم مثالا هنا مع فئة Singleton:

final class mySingletonSubClass {

    private static $instance = null;
    private static $classInstanceRef = null;

    private function __construct(myPrimaryClass $primaryClassInstanceRef) {
        return $this;
    }

    public static function getInstance(myPrimaryClass $primaryClassInstanceRef = null) {
        if (!is_null($primaryClassInstanceRef))
            self::$classInstanceRef = $primaryClassInstanceRef;

        if (is_null(self::$instance) || !(self::$instance instanceof mySingletonSubClass))
            self::$instance = new mySingletonSubClass(self::$classInstanceRef);

        return self::$instance;
    }
}

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

نصائح أخرى

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

أعلم أنه قبيح، وليس آمنا جدا (نعم لا أحد يحب الغموض الأمني)، ولكن قد يعمل بما يكفي لحالتك المحددة ...

أعلم أن هذا الموضوع قديم الآن الآن، لكنني كنت أفكر فقط في كيفية القيام بذلك في Java هو مع التفتيش على مكدس المتصل، ولا تحتوي PHP على شيء مشابه؟ في الواقع، على الرغم من أنها وحدة Pecl:

http://www.php.net/manual/en/function.apd-callstack.php.

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

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