0

The class Foo has a method that must return a DateTime object.

Foo can be considered a parameter object (it implements an interface)

class Foo implements CustomInterface{

   function dateTime():\DateTimeInterface{}
}

The class "Bar" requires a Foo object in the constructor

Does it violate the law of Demeter if Foo's DateTime object is called within Bar constructor?

class Bar{

   public function __construct(CustomInterface $interface){

      $this->field = $interface->dateTime()->format('Ymd');
   }
}

I cannot pass the DateTime object directly in the constructor because Foo is parameter object and has other fields required to make Bar work.

I understand A.B.C violates the Demeter law if C return an object we would work on, but is it still an issue if C returns a "final" result like any string or boolean value?

Update

Here is the exact subtlety I was looking for regarding the law of Demeter:

The data structure behind the Position property is immutable, and that means it’s safe to expose it directly. The client code is unable to mess up with the position’s internal state because it simply doesn’t have any. int positionX = player.Position.X; The law of Demeter is not applicable to the world of purely functional (immutable) data structures.

Source: https://enterprisecraftsmanship.com/posts/law-of-demeter-and-immutability

if in a method you're working with data structures, law of demeter is not applied to them because is natural for a data structure to expose their internal structure.

Source: https://www.fabrizioduroni.it/2018/04/25/clean-code-objects-data-structures-law-demeter/

Vincent
  • 1,651
  • 9
  • 28
  • 54
  • The Law of Demeter would say your `CustomInterface` should have something like a `getFormattedDateTime` function. In practice, this causes some of the [disadvantages noted in the Wikipedia entry on the law](https://en.wikipedia.org/wiki/Law_of_Demeter#Disadvantages). Whether it's worthwhile is up to you. – ceejayoz May 17 '23 at 15:56
  • This is where I was stuck. I "know" I should implement a `getFormattedDateTime` method but this method would have to return a string, whereas typehinting the method with a specific object to be returned guarantees it can be properly manipulated later for specific purposes. Returning any string could make the construct of B fail. – Vincent May 17 '23 at 16:03
  • 2
    IMO, part of the evolution from junior to senior dev is knowing when to violate "laws" and "best practices". See https://www.joelonsoftware.com/2001/04/21/dont-let-architecture-astronauts-scare-you/ for a good article on this. – ceejayoz May 17 '23 at 17:07
  • @ceejayoz, unfortunately that evolution requires years of experience. The worst advice I see senior devs giving to junior devs amounts to, "When best practices are hard to follow, then break them." If this is an edge-case scenario, so be it; but without an explanation of _why_ this scenario is an edge cage, "just use your judgement" is the worst kind of advice to give a junior dev who doesn't have the experience necessary to attain good judgement. – jaco0646 May 17 '23 at 18:12
  • 3
    I would argue that most objects built into the language are roughly equivalent to scalar types in this context. Something conforming to `DateTimeInterface` is not some unknown, optional, or esoteric class from elsewhere, it's part of the fundamental landscape in which your code exists. If PHP had complex scalar types, eg: `$some_string->length()`, would these not also violate an overly-strict interpretation of LoD? Not to mention that laws like these cannot be held as absolutes outside of an ideal world, which is not where we live. – Sammitch May 17 '23 at 18:27
  • 1
    https://javadevguy.wordpress.com/2017/05/14/the-genius-of-the-law-of-demeter/ – jaco0646 May 17 '23 at 19:18

0 Answers0