On Fri, May 8, 2026 at 2:42 PM Max Semenik <[email protected]> wrote:

> On Thu, Apr 30, 2026 at 5:10 PM Larry Garfield <[email protected]>
> wrote:
>
>> class User {
>>   friend UserFactory;
>>
>>   public friend(set) string $name;
>> }
>>
>> class UserFactory {
>>   public function makeUser($name) {
>>     $u = new User();
>>     $u->name = $name; // This is OK, because UserFactory is a friend.
>>     return $u;
>>   }
>> }
>
>
> This seems like an overcomplication, in current PHP this would work just
> fine:
>
> class User {
>     public function __construct(
>         public readonly string $name,
>     ) {}
> }
>
> Some of C++ OOP features have always felt like kludges to me, and
> friendships are a good example. A well-written class shouldn't care what
> other classes are using it, as long as they respect its contract.
>
> --
> Best regards,
> Max Semenik
>

That example works for users with just a name, but what about users with
both a name and user id, with the class invariant that the user with the
given name has that specific ID? A class like

```
class User {
    public function __construct(
        public readonly string $name,
        public readonly int $id,
    ) {}
}
```

means that the requirement is on *callers* to get it right, on pain of
breaking a whole bunch of things that assume the user id and username
correspond to the same record. And while you could do that, it makes it a
lot easier to break things. Instead, you would want to have the constructor
private.

But then, how to create new instances of the User class when you have
properly looked up the user id and name in the database? You could add a
public static method on User, which would be able to call the constructor,
but static methods present other complications with dependency injection
and unit testing. And once you move to a separate UserFactory, you wind up
with the original issue this seeks to address - how can UserFactory
interact with the internals of the User class. Other than making those
internals public (which we don't want to do) the only option is to use
reflection (which is generally frowned upon).

Hence, the proposal to add friends.

-Daniel

Reply via email to