3

Given this code from the Symfony framework:

use Symfony\Component\HttpFoundation\Request;

public function indexAction(Request $request)
{
    $request->isXmlHttpRequest(); // is it an Ajax request?

    $request->getPreferredLanguage(array('en', 'fr'));

    // retrieve GET and POST variables respectively
    $request->query->get('page');
    $request->request->get('page');

    // retrieve SERVER variables
    $request->server->get('HTTP_HOST');

    // retrieves an instance of UploadedFile identified by foo
    $request->files->get('foo');

    // retrieve a COOKIE value
    $request->cookies->get('PHPSESSID');

    // retrieve an HTTP request header, with normalized, lowercase keys
    $request->headers->get('host');
    $request->headers->get('content_type');
}

I think this way of accessing for example the GET and POST variables is nice. You call the get() method on the query object which is part of the request object. I think the concept of method chaining is short and nice. However, I know the drawbacks of this tight coupling. Here, my controller claims to much knowledge on the method of the query object. That is, when the query object changes its method, I would need to change all these scripts. These drawbacks are manifested in the law of Demeter.

So what is the question? My question is, when there is so much description of "good practice" how come that such popular frameworks as Symfony decide against some of these rules. Or do I misinterpret the law of Demeter? I get the impression that sometimes good practice considerations to a degree depend on personal preference. Am I wrong?

  • Possible duplicate of Law of Demeter and its applicability – gnat Jan 8 '18 at 10:51
  • 1
    Both links are describing the law of Demeter and why it should be followed. I understood that already. I was posting code from a very popular php framework and was asking specifically why they don't follow this law. – agoldev Jan 8 '18 at 10:58
  • 3
    "I was posting code from a very popular php framework and was asking specifically why they don't follow this law". PHP has a well-deserved reputation for being a very poor quality language that all too often seems to positively encourage bad practice. It is therefore not surprising that popular PHP frameworks ignore good practice. – David Arno Jan 8 '18 at 11:01
  • 1
    If you want to know why the developers of Symfony don't follow the Law of Demeter, then the only people who know why the developers of Symfony do something are the developers of Symfony, and you should ask them, not random strangers on the Internet. – Jörg W Mittag Jan 8 '18 at 11:58
  • 1
    I don't agree. Asking random strangers bears the propability to get an objective evaluation. However, asking for an objective evaluation seems utopistic here... – agoldev Jan 8 '18 at 14:00
5

First of all, the Law of Demeter should not be perceived as set-in-stone rule. Is your request's structure prone to changes? Is there any additional behavior that could be invoked when getting your $request's properties? If you get "no" to both answers, I don't think that violating this "law" is such a bad thing.

Or do I misinterpret the law of Demeter?

Probably. To better understand it, I think you could look no further than this.

-1

You are not misinterpreting the Law of Demeter, your example is a good example of what the Law is against.

I do not believe that everything is a question of personal preference. I do believe that architectures / designs can be compared in some fixed context. Unfortunately this is only my opinion at this point :)

To your concrete question about why frameworks don't really give much thought to the LoD, and this from my Java Enterprise perspective:

  1. Culture. Our developer culture is just dominated by other paradigms at the moment. It all came from the "Procedural" paradigm ("C", "Pascal", "Basic" and alike). Then people tried Object-Orientation for a while (the "Smalltalk" people), and its syntax was added to languages ("Java", "C++"). However we do not do OO. We do Component-based designs, Layered designs, Structured design, or even Procedural programming still. Therefore the LoD, which is a Law of Object-Orientation often does not apply.

  2. Seeing no alternatives. There are just too few projects that really do Object-Orientation / Tell don't ask / LoD. There are just not that many examples for people to learn from.

Here is my own article on Law of Demeter. I basically agree with Yegor's article, it can be summarized as: don't write getters.

Ps.: Just to comment on Martin Fowler's "occasionally useful suggestion of Demeter" tweet. It's occasionally useful if you are only occasionally doing Object-Orientation. If you are using Object-Orientation, then you have to follow LoD.

  • I strongly disagree with your answer in both that you shouldn't be writing getters (this is a nonsense, there's no problem with having getters and Yegor's reasoning is dumb - in his example, simply changing the getBall method to give does not eliminate the getter, it renames it) and that the example in the question violates LoD. Sometimes you need to be able to extract data from objects (user input, presentation layer,...) and that's perfectly okay. The Request's API in the example is totally fine. – Andy Jan 9 '18 at 7:59
  • For the record, I didn't say I agree with Yegor's "solution". I actually do not. The code above does violate LoD, look up the rules, it's pretty well defined. Whether sometimes you need to be able to extract data from objects: maybe. That does not in any way change the fact whether you are violating LoD or not. If you – Robert Bräutigam Jan 9 '18 at 8:14
  • Probably this post could resolve the conflict. TL;DR: when you accept a request, you have no choice to keep request object encapsulated. All you need is to get data somehow, just to launch your domain model, which in turn must be encapsulated, exposing behavior instead of data. – Zapadlo Jan 9 '18 at 8:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.