سؤال

بحسب ال قانون ديميتر, ، هل يمكنك استدعاء طرق على الكائنات التي تم إرجاعها؟

على سبيل المثال

<?php
class O
{
    public function m($http)
    {
        $response = $http->get('http://www.google.com');
        return $response->getBody(); // violation?
    }
}
?>

$ http-> get () إرجاع كائن. هل هذا يعتبر ككائن تم إنشاؤه/إنشاء مثيل له داخل م؟ إذا لم تتمكن من استدعاء أساليبها (وفقًا لـ LOD) ، فكيف ستتعامل مع هذا الموقف؟

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

المحلول

هذا ليس انتهاكًا لقانون ديميتر ، منح:

بشكل أكثر رسمية ، يتطلب قانون Demeter للوظائف أن طريقة M لكائن ما قد تستدعي فقط طرق الأنواع التالية من الكائنات:

  • س نفسها
  • معلمات M.
  • أي كائنات تم إنشاؤها/إنشاء مثيل لها داخل م
  • كائنات المكون المباشر لـ O
  • متغير عالمي ، يمكن الوصول إليه بواسطة O ، في نطاق M

نظرًا لأن استجابة $ هي كائن تم إنشاؤه داخل M ، يمكنك استدعاء طريقة على هذا الكائن دون انتهاك. ومع ذلك ، سيكون انتهاكًا للوصول إلى العقارات بعد ذلك getBody():

$length = $response->getBody()->length;

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

نصائح أخرى

على يدا واحدة، $response يبدو أنه تم إنشاؤه داخل الطريقة m, ، لذلك يبدو أن الإجابة هي نعم.

من ناحية أخرى ، منذ ذلك الحين $http تم نقله إلى m, ، الكائن الذي تم إرجاعه بواسطة $http->get() الذي يمثله الآن $response قد يكون عضوا في $http ربما تم إنشاؤه قبل الدخول إلى m.

النظر في "نقطة واحدة فقط" (أو ، في هذه الحالة سهم) للقانون ، إعادة كتابة جسم وظيفتك كـ return $http->get('http://www.google.com')->getBody(); يشير إلى أنه قد يكون انتهاكًا. يبدو أن إنقاذ الأعضاء المتوسطين كمتغيرات محلية بمثابة وسيلة مراوغة لتجنب مبدأ نقطة واحدة.

لا أستطيع إعطاء إجابة محددة. إلى حد ما ، أعتقد أن هذا يعتمد على مدى تثق في $http->get() لإعطائك كائنًا تم إنشاؤه حديثًا بدلاً من عضو موجود مسبقًا.

أحد إمكانية حل هذا هو إنشاء الكائن داخل M () ، والسماح لـ HTTP-> Get () بملء المعلومات.

class O
{
    public function m($http)
    {
        $response = new HttpResponse();
        $http->get('http://www.google.com', & $response);
        return $response->getBody(); // no violation, since we made $response ourselves.
    }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top