-
-
Notifications
You must be signed in to change notification settings - Fork 76
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Remove final keyword #169
Remove final keyword #169
Conversation
fb6329d
to
a8f35b9
Compare
I also really dislike this, because extending a PSR implementation tends to people relying on the extended version, which in turn means they have just limited themselves to never be able to switch implementations. A problem that does not happen if you follow a decorator pattern. The entire point is interoperability. I almost feel this is just helping someone else get into trouble down the line. I have been thinking about ways to help people build decorators, and wonder if it might be better to offer some sort of abstract class to extend that implements all the methods. E.g. we'd be providing the abstract class called interface AnInterface { // Imagine this is a PSR-7 value object interface.
public function action(): bool;
}
final class AnImplementation implements AnInterface { // Imagine this is our implementation of said interface.
public function action(): bool {
return true;
}
}
abstract class ADecoratorBase implements AnInterface { // Imagine this is a "decorator" we provide.
protected AnInterface $base;
public function action(): bool {
return $this->base->action();
}
}
class MyDecorator extends ADecoratorBase { // Now all a user needs to do to decorate is this.
public function __construct(AnInterface $base)
{
$this->base = $base;
}
}
$obj = new MyDecorator(new AnImplementation());
assert($obj->action() === true, 'Accessing expected method from base.'); Alternatively shipping something like the Grav traits that @mahagr linked to in #139 (comment). Just wondering if we can do some sort of educative good by doing that, rather than just dropping the final keyword that we both believe as correct for this library 🤔 |
I have to say that extending class also sounds tempting as it would allow customization without too much work. This is also where the traits come -- it will save a lot of work. The reason why I ended up using traits was to be able to inject the PSR-7 interface into any (existing) class. I think it's also a good idea to separate decorator/traits from this library in order to prevent fixating code into a single library. |
@Zegnat, Yeah, but looking at the implementations, most methods just have a few lines, I don't think it make much sense to also add a bunch of abstract classes. What if we add a page in the documentation to better explain why extending classes are a bad idea. We can also show what one should do instead. The |
The PR is updated |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, but looking at the implementations, most methods just have a few lines, I don't think it make much sense to also add a bunch of abstract classes.
Yet apparently people do not want to copy the few lines and make their own class. I also wouldn’t put the actual implementation in the abstract classes, only make an abstract decorator (wrapper) class that calls the methods from the actual wrapped value object.
But the more I think about that, the less I would want that as part of the Psr7 library. I might just create a Psr7Decorator package later…
What if we add a page in the documentation to better explain why extending classes are a bad idea. We can also show what one should do instead. The
@final
comment can link to that page.
I like adding implicit the docs.
I wonder if we should point to some patterns that people might actually be looking for, rather than extending. Such as decorating. There is nothing wrong with wanting to wrap a value object adding additional logic to match the application.
Co-authored-by: Martijn van der Ven <martijn@vanderven.se>
Thank you. Let me improve the docs with some more references. |
First of all; I like the quality of your work - which is why I decided to use your PSR-7 implementation. Unfortunately, I have to drop it or fork it due to the The PSR does not define the signature for the I'm sad to learn that you have decided to mark your class with |
I don't think there is any benefit to remove the
final
keyword. All the good software scientists and best practises says that you should never efter extend these value objects.However, some people insists on writing code that I don't approve of and from their perspective the
final
keyword is just annoying.This PR does not change the concept, but technically it allows some people to write the code they want to write even tough I consider it suboptimal.
Edit: When I read this description again, it looks that Im condescending. Im really not. Im trying to be pragmatic.