dgoosens, (edited )
@dgoosens@phpc.social avatar

OK... here is a question (#PHP but other #dev communities are welcome to comment.

When building a decoupled app, do you consider the usage of something like
ClassWithAnnoyingName::class
(not to call the class, but to reference the name as a string and to simply avoid to type it out) as coupling?

IMHO, it is not

  • it is very trivial to replace with its string value if needed
  • it greatly improves DX
  • it greatly reduces errors because of typos

But what do you think ? And why ?

danielsiepmann,

@dgoosens To me coupling is a concept, not technical aspect. Referencing a foreign class is always coupling. The question is not whether it is a string or anything else.

I would try to avoid it. But I don't have any context. So I can't answer your concrete case as I don't know it.

Crell,
@Crell@phpc.social avatar

@dgoosens IMO it depends on where that class name is used. If the referenced library is missing, what happens? Does the code crash? Then it's coupled. Does it misbehave? Then it's coupled. Does it keep working smoothly, minus some functionality? That's totally fine, and I wouldn't call it coupled.

Eg, using an attribute from a library that's not installed doesn't break anything unless you do something dumb, so that's not coupling. It's optional.

dgoosens,
@dgoosens@phpc.social avatar

@Crell

actually, and I was not aware of this, @heiglandreas showed me this:

https://phpc.social/@dgoosens/112247386776714044

so if the class is missing, it will still interpret it as a string

Crell,
@Crell@phpc.social avatar

@dgoosens @heiglandreas Right. Which may or may not cause a bug if missing, depending on the situation. :-) Usually not, but there are exceptions.

heiglandreas,
@heiglandreas@phpc.social avatar

@Crell What do you mean... There are Exceptions... How can there ever be????

/cc @dgoosens

Image from Microsoft SwiftKey Keyboard

dunglas,
@dunglas@mastodon.social avatar

@dgoosens my 2 cents: it's ok in an application, but probably a sign of the lack of an extension point to do control inversion in a library.

beausimensen,
@beausimensen@phpc.social avatar

@dgoosens Many systems I've used do a bit of encoding to convert to a reversible normalized format (usually dots instead of \ and lowercase first letter) but use raw ::class as input.

Plays better with other languages, especially since \ can be a pain to work with.

All the better if you can work in a namespace without framework details encoded along the way.

dgoosens,
@dgoosens@phpc.social avatar
heiglandreas,
@heiglandreas@phpc.social avatar

@dgoosens as ::class can be used without the class actually being available, it is not really coupling. (see https://3v4l.org/jorQT)

Sometimes code needs to check whether a class is available or not and this is a valid way to do so even when the class is not available. Therefore it is not more coupleded that writing out the full namespaced classname as a string.

dgoosens,
@dgoosens@phpc.social avatar

@heiglandreas

man...
I did not even know that !

even better !

thanks !

heiglandreas,
@heiglandreas@phpc.social avatar

@dgoosens I also learned that just a few weeks back and thought it's nifty 😁

heiglandreas,
@heiglandreas@phpc.social avatar

@dgoosens Works even with use: https://3v4l.org/oLWcT

theshaunwalker,
@theshaunwalker@phpc.social avatar

@dgoosens having to refer to specific classes/interface (basically any “code”) is incredibly tight coupling imo.

I appreciate the DX angle, I would achieve the same kind of DX by instead having an enum/class with constants, which will hold an agnostic string reference (so still not Foo::class, but some alias), then both systems need to understand this alias, but they’re not coupled because they are both free to be implemented in any way.

Skoop,
@Skoop@phpc.social avatar

@dgoosens it really depends (yeah, I know 🙄) on the situation. I'd prefer using interfaces if possible, but if you really must reference the implementation, then I'd find this acceptable (better than using strings of class names)

dgoosens,
@dgoosens@phpc.social avatar

@Skoop

classname of interface, for my question, are the same

the question is, would it be ok to use Class::class of Interface::class in a part of your app that is to be decoupled from them ?

Skoop,
@Skoop@phpc.social avatar

@dgoosens I don't see another option to be honest. If you need to reference it and you can't do it dynamically, then there is no other option and I'd prefer the ::class over strings.

The only thing I could think of is to invert the coupling. So define the interface in your "local" code and make the implementing class that should not be depending upon implement the interface (talking about different domains or bounded contexts). If possible. And if it makes sense.

dgoosens,
@dgoosens@phpc.social avatar

@Skoop

that only inverts the coupling does it not..

the only alternative, IMHO, is to make it dynamic via the usage of attributes (which will not do any harm if not found)

this attribute would tag the referenced class/interface and have a service that indexes their usage somehow and make them available

but IMHO that is quite a lot of overhead just to reference a string

  • All
  • Subscribed
  • Moderated
  • Favorites
  • php
  • kavyap
  • thenastyranch
  • mdbf
  • DreamBathrooms
  • ngwrru68w68
  • magazineikmin
  • InstantRegret
  • Youngstown
  • vwfavf
  • slotface
  • everett
  • osvaldo12
  • rosin
  • khanakhh
  • megavids
  • tester
  • Durango
  • tacticalgear
  • GTA5RPClips
  • cisconetworking
  • ethstaker
  • cubers
  • normalnudes
  • modclub
  • provamag3
  • Leos
  • anitta
  • JUstTest
  • All magazines