What are the Slack Archives?

It’s a history of our time together in the Slack Community! There’s a ton of knowledge in here, so feel free to search through the archives for a possible answer to your question.

Because this space is not active, you won’t be able to create a new post or comment here. If you have a question or want to start a discussion about something, head over to our categories and pick one to post in! You can always refer back to a post from Slack Archives if needed; just copy the link to use it as a reference..

🐘

Chemaclass
Chemaclass Tech Lead Spryker Solution Partner Posts: 213 🧑🏻‍🚀 - Cadet

Comments

  • UKN2CGHSB
    UKN2CGHSB Posts: 13 🧑🏻‍🚀 - Cadet

    btw, when we could expect something like:

    $foo = FooTransfer::new()->setBar(BarTransfer::new());
    

    …instead of:

    $foo = (new FooTransfer())->setBar(new BarTransfer());
    

    ?

  • Chemaclass
    Chemaclass Tech Lead Spryker Solution Partner Posts: 213 🧑🏻‍🚀 - Cadet

    well… personally, I don’t see a big difference between these two options. Imho, if the named constructor is not adding value but just a “proxy” to the real constructor, then I wouldn’t advocate using named constructors. I mean, named constructors are great at providing meaning, context, validation, allowing creating an object from different inputs or with different collaborators… TL;DR: I don’t see any benefit for named constructors for DTOs, for example. On the other hand, ValueObjects are a different topic.

  • I can understand the "less ()" typing to be handy. You can open a PR and ticket in support for this and we can then discuss and "use" your PR.
    One issue to be discussed: "new" vs "create" etc. Naming is hard, and we would need to find a naming here for that proxy method.
    In a different context and open source I used that naming for example: https://github.com/dereuromark/cakephp-dto/blob/master/src/Dto/Dto.php#L67

  • UKN2CGHSB
    UKN2CGHSB Posts: 13 🧑🏻‍🚀 - Cadet

    I mean, if looking at some other languages, new is the most common keyword for naming a constructor

    In rust (https://doc.rust-lang.org/std/keyword.struct.html) new is used:

    The most common way to make a new struct is via a constructor method such as new()

    struct Person {
        name: String,
        age:  u32,
    }
    
    impl Person {
        fn new(name: String) -> Self {
             Self { name, 42 } 
        }
    }
    

    In go (https://gobyexample.com/structs) also new is used when creating structures:

    This person struct type has name and age fields.
    newPerson constructs a new person struct with the given name.

    type person struct {
        name string
        age  int
    }
    
    func newPerson(name string) *person {
        p := person{name: name}
        p.age = 42
        return &p
    }
    
  • U018XELUZS9
    U018XELUZS9 Posts: 167 🧑🏻‍🚀 - Cadet

    Real world example from our project:

    final class DeliveryName
    {
        private const MAX_LENGTH_FIRSTNAME = 36;
        private string $firstName;
        private string $lastName;
    
        private function __construct(string $firstName, string $lastName)
        {
            $this->firstName = $firstName;
            $this->lastName = $lastName;
        }
    
        public function __toString(): string
        {
            if ($this->getLength() > self::MAX_LENGTH_FIRSTNAME) {
                $this->firstName = mb_substr($this->firstName, 0, self::MAX_LENGTH_FIRSTNAME - $this->getLength()) ?: '';
                $this->firstName = trim($this->firstName);
            }
    
            return $this->getFullName();
        }
    
        public static function fromPayload(array $payload): self
        {
            $address = $payload['order']['shipping_address'] ?? [];
    
            if (!isset($address['first_name'], $address['last_name'])) {
                throw new InvalidArgumentException('Missing name in payload');
            }
    
            return new self($address['first_name'], $address['last_name']);
        }
    
        private function getFullName(): string
        {
            return trim(sprintf('%s %s', $this->firstName, $this->lastName));
        }
    
        private function getLength(): int
        {
            return mb_strlen($this->getFullName());
        }
    }
    

    We use that in the middleware and create the object from the payload that is available inside the middleware. This is used to get the name that is printed on the shipping label, it shortens the firstname in case of a too long name, but never touches the lastname. Note that the __construct method is private so the only way to create this class is to use DeliveryName::fromPayload, which makes sure, that we have validation in one central place at the very beginning.