قانون ديميتر وعودة القيم
-
25-09-2019 - |
سؤال
بحسب ال قانون ديميتر, ، هل يمكنك استدعاء طرق على الكائنات التي تم إرجاعها؟
على سبيل المثال
<?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.
}
}