Often I find myself in a situation where I have a class in which I only have one public method and want to call it. Let's imagine we have a class t...
For further actions, you may consider blocking this person and/or reporting abuse
Is there a reason you wouldn't just use the magic method
__invoke()
?Example:
And to invoke it you simply do
Thank you for your comment. I tried your example. But somehow the invoke method is never called 🤔. Could you help me with that?
Here is a link to a "Online PHP Compiler": repl.it/repls/DisastrousViciousFeed
Edit: Sorry, the right way is
I tried your example but it returns an
Fatal Error
. Do you have a working snippet for me?Here is a link to a "Online PHP Compiler": repl.it/repls/ImpressionableCuddly...
Try the following as a replacement of line 11.
Still getting following fatal error
PHP Fatal error: Uncaught Error: Call to undefined function Something() in /home/runner/main.php:12
What am I missing? 😖
repl.it/repls/EssentialMarvelousWe...
You are missing the class instantiation (
new
), but I think that is my fault, I copied the wrong thing.It's working now 🥳 we found the missing key to the puzzle. The invoke variant looked promising but at the end it still requires 2 lines of code.
But thank you Jamieson for showing me this variant. Did not know how to call the magic invoke method #TIL. This can be handy for sure 🤝
I think this approach is bad (for like 99% of the cases, like this one). How are you going to parametrize your send process? How are you going to switch from SMTP to something else?
If you would have properly structured the code, you would you DI (maybe an interface). When using static methods, you will never be able to easily switch the implementation. You are locked into your current implementation.
Thank you for your feedback Christian. Yeah for the use case of sending mails this makes no sense. It is a very simplified example. I use this method in the following case. Imagine you have a pretty big class. Like 500 or more lines and it is pretty hard to read it. You have many functions that perform different tasks. Now you can use this pattern to split the class in different little classes. Let's call the little classes "actions". Each action you can call now on your own and refactor it out of the big class.
We can now refactor it like this.
In my eyes this helps to clean up my big classes. You get following benefits.
I hope this explanation gives you a better understanding.
While I understand your case (and I, for sure, have also written such code) I have two main concerns about your example:
You say „a huge class that performs many tasks“. I‘ll just refer to „Single Responsibility Principle“ here: 1 Class -> 1 Purpose/Task
How would you ever write a Unit test for your RefactoredBigClass? There is no way you could ever test your handle() function there.
Thank you for your concern, Christian.
At your first point: I don't know what you mean by that 🤔
And to your second point: I'm not unit testing this class 😁
For the first point, see: scotch.io/bar-talk/s-o-l-i-d-the-f...
For the second point: Well, that's your fault ;)
This is a wrong way in my opinion. You need split data structures too, coupled with methods.
this is exactly why people say "OOP is stupid and not used correctly". The object in this case has no business with any of its functions, its just a namespace-delivery-system.
A simple function send_email() would be enough, this adds about 5x the bloat and you dont even create objects, just call a single static function.
Thank you for your feedback Maximillian. You are absolutely right. For the use case of sending a mail this pattern does not have any benefit.
Further explanation of this approach if you are interested 😊dev.to/suddenlyrust/comment/e58i
Better way:
Why? You may inject object
$sendmail
into another method. You may simple replace this object with$nullObject
or$stubObject
when you want run tests.I generally support this, as it can also allow extra management logic like sharing object instances (like what's usual with object factories so common in Java).
As long as the number of arguments is kept at an acceptable minimum, that is.
I find this approach difficult to maintain ever once somebody introduces a parametrized constructor: you would have to change the calls in the static methods on every change of the signature.
I was accepting this idea in the past, but for now I think it makes me confusing between concept of static function and 'normal' function. Finally, keep it simple and open the eyes is better solution, IMO.