I found a bug today with ServerSocket. If you put an instance of the ServerSocket on a window it works as expected.
If you create an instance in code and use AddHandler to connect the events it does not work properly. It will use the first connection and then reject subsequent connections.
In this project I’m talking to the ServerSocket from iOS devices. If I get an error on the iOS side it will be: Socket error operation couldnt be completed Broken pipe. So it’s possible this specific to iOS clients. I have not gone further than that. But it works if the ServerSocket on the desktop is on a Window rather than using AddHandler so I’d have to lean towards the ServerSocket side.
Yeah I understand its semantically the same thing but I have written before for how there are use cases for using the class and using AddHandler. If AddHandler is so bad why is it in the language? Someone saw a use for it… I would expect the class to function the same way regardless of how its used.
Because it seems silly to create a subclass when the subclass gains me NOTHING in terms of functionality. It’s adding an unnecessary layer, IMO, when one isn’t needed.
Sure, I could imagine use cases where creating the subclass is useful, even desirable. MY use case said that creating the sub wasn’t necessary. Seems simpler to just use the two AddHandlers but hey, to each their own.
There are a limited number of places where its the ONLY way to do something
So for those few places it needs to be present
But its become the “go to” way to do everything instead of properly designing a subclasses with a proper API
Its also become a big cause of bug, leaks and misunderstandings
A subclass, in this case, would isloate code to that subclass and provide and REQUIRE a nice clean API between the subclass and whatever wants to use it
Instead Addhandler lets you just grab anything on the class that holds the handler so instead of designing a proper API and having a nice separation you can just grab ANYTHING and now the lines between pieces of you app are not longer clear.
AddHandler lets you write “modern spaghetti”
You cant easily answer the “what data does this THING need/provide” without READING everything because the handlers are not part of it
They are attached OUTSIDE of its scope and run outside of its context
As I said “addhandler” is NOT a good design pattern because it negates many reasons you use an OO language & tool
IN those cases where it is the ONLY way to do something fine, use it.
I’d avoid it for a lot of other places where its used
While I agree with all of the above there is one reason I use AddHandler more often than I’d like:
Xojo does not support classes in external modules.
This means I want to minimize the number of external classes otherwise I end up having to import/drag/drop a ridiculous amount of classes for each project and sub-project.
That’s cool. I mean I don’t want to have to configure that for each project and in some cases repos I don’t control when I am consulting. I’d like to just be able to import my module and everything work as expected.
dont get me wrong
addhandler IS useful
I just wouldn’t recommend using it as frequently as I’ve seen it used
To be honest, except for the cases where you must use addhandler, everything I’ve seen it used for could be solved in other ways prior to the introduction of addhandler.
Yes its more set up
Yes its a tad more work
BUT you end up with a well defined API that is, IMHO, easier to work with long term
Used with abandon addhandler can result in missing toes and hard to find bugs because :
things have leaked because of mismatched add and remove calls and its not obvious WHY there is a leak
the code becomes hard to grok because the code that handles action X isn’t not part of the class and isn’t set up as [art of the class or any of its subclasses
the API a piece of code is no longer clear because you cant say what the codes inputs & outputs are because the handler has access to whatever has the code for the handler so lines are extremely blurry
YMMV but I’d suggest using it sparingly
except of course where its the ONLY answer - then you have no choice
One place I end up using it frequently is for displaying dialogs which do something or report something to the user and the window that showed the dialog needs to know that the dialog is closed or finished with whatever it’s doing. The window will “addHandler” some method on the close event of the dialog.
Is there a better way to do this without building custom dialogs over and over again?
It’s far easier to create the subclass then it is to worry about all the AddHandler nonsense. AddHandler is subtly evil, like Variants. You need to be very judicious in their usage and you have to make sure a RemoveHandler is also involved or you’ll get mysterious leaks.