digitalmars.D - API question: Delagates/FPs or Interface?
- Robert Fraser (9/9) Apr 17 2007 Hi all,
- Dan (8/21) Apr 17 2007 Hi Robert,
- 0ffh (8/10) Apr 17 2007 Personally, I wouldn't consider it good style to force the library
- Robert Fraser (2/2) Apr 17 2007 Hi Dan,
- Robert Fraser (1/1) Apr 17 2007 Okay, cool, that's what I was thinking, too. I gues sthe real advantage ...
- Jarrett Billingsley (4/7) Apr 17 2007 I like the delegate method better. Implementing interfaces seems too "I...
- Daniel Keep (27/40) Apr 17 2007 My personal feelings would be to use delegate callbacks for singular
Hi all, I'm working on a new NAT/firewall traversal library in D right now, and I have a question for you all: since D has enough expressive power to expose both function pointers and interfaces, which would you prefer for a set of "callback" functions. In particular, the library allows a client to start establishing a connection in a separate thread, and when the state of the connection changes, a function is called to inform the client. I had two possible solutions in mind: 1. Create an interface with the required methods (such as onFailedState, onErrorState, onSuccessState, etc.) specified. The library takes a pointer to an implementing object and calls the methods through that. 2. Accept a set of function pointers or delegates (I'll overload the methods so either is acceptable), and call the functions through that. One advantage of this is that a single callback function is easily interchangeable without having to re-implement the entire interface, and it promotes code reuse because a client might want to implement, for example, only a single onFailedState method, but have a different onSuccessState for different types of connections. If you think the first option would be better for something like this, there are a couple of other places with a single callback function is needed (for example, to deal with an incoming connection invitation) that don't fit into a set... Should these be interfaces as well? Thanks for whatever input you have, All the best, Robert Fraser
Apr 17 2007
Hi Robert, I would write an array of structs such that the function probing/handling the state change already has the appropriate struct in hand, and merely looks up the callback, and also has the name of the callback on hand (such as "onErrorState" as a char[]) Any other relevant metadata may also be attached; according to performance refactoring and such considerations. Does this help, should I rephrase it, or does that not work? Sincerely, Dan ~~~~~~~~ Robert Fraser Wrote:Hi all, I'm working on a new NAT/firewall traversal library in D right now, and I have a question for you all: since D has enough expressive power to expose both function pointers and interfaces, which would you prefer for a set of "callback" functions. In particular, the library allows a client to start establishing a connection in a separate thread, and when the state of the connection changes, a function is called to inform the client. I had two possible solutions in mind: 1. Create an interface with the required methods (such as onFailedState, onErrorState, onSuccessState, etc.) specified. The library takes a pointer to an implementing object and calls the methods through that. 2. Accept a set of function pointers or delegates (I'll overload the methods so either is acceptable), and call the functions through that. One advantage of this is that a single callback function is easily interchangeable without having to re-implement the entire interface, and it promotes code reuse because a client might want to implement, for example, only a single onFailedState method, but have a different onSuccessState for different types of connections. If you think the first option would be better for something like this, there are a couple of other places with a single callback function is needed (for example, to deal with an incoming connection invitation) that don't fit into a set... Should these be interfaces as well? Thanks for whatever input you have, All the best, Robert Fraser
Apr 17 2007
Hi, Robert! Robert Fraser wrote:I'm working on a new NAT/firewall traversal library in D right now, [...]Personally, I wouldn't consider it good style to force the library user (or yourself) into the object-oriented metaphor to accomplish a task where there is no clear advantage in doing so. Consequently, if there is no clear advantage, /just say no/... ;-) Happy hacking, 0ffh
Apr 17 2007
Hi Dan, I'm not quite sure exactly what you mean there. Why would the struct need to contain more than just a function pointer? Making an array of structs containing function pointers and looking them up seems to add a needless level of complication without really gaining anything.
Apr 17 2007
Okay, cool, that's what I was thinking, too. I gues sthe real advantage of the interface option is that a uaer knows exactly what they need to implement without nessescarily referring to the spec.
Apr 17 2007
"Robert Fraser" <fraserofthenight gmail.com> wrote in message news:f034me$u2v$1 digitalmars.com...Thanks for whatever input you have, All the best, Robert FraserI like the delegate method better. Implementing interfaces seems too "I'm Java and I don't have any expressive capabilities" to me.
Apr 17 2007
Robert Fraser wrote:Hi all, I'm working on a new NAT/firewall traversal library in D right now, and I have a question for you all: since D has enough expressive power to expose both function pointers and interfaces, which would you prefer for a set of "callback" functions. In particular, the library allows a client to start establishing a connection in a separate thread, and when the state of the connection changes, a function is called to inform the client. I had two possible solutions in mind: 1. Create an interface with the required methods (such as onFailedState, onErrorState, onSuccessState, etc.) specified. The library takes a pointer to an implementing object and calls the methods through that. 2. Accept a set of function pointers or delegates (I'll overload the methods so either is acceptable), and call the functions through that. One advantage of this is that a single callback function is easily interchangeable without having to re-implement the entire interface, and it promotes code reuse because a client might want to implement, for example, only a single onFailedState method, but have a different onSuccessState for different types of connections. If you think the first option would be better for something like this, there are a couple of other places with a single callback function is needed (for example, to deal with an incoming connection invitation) that don't fit into a set... Should these be interfaces as well? Thanks for whatever input you have, All the best, Robert FraserMy personal feelings would be to use delegate callbacks for singular things, and interfaces for logically connected things. For example, SAX works well using interfaces because if you're going to have a "startElement" callback, odds are you're going to at least use an "endElement" and "characters" callback as well. Since these are logically related to each other, you use an interface to keep them together. On the other hand, if you've got a window with things like onClick, onKeyPress, onLoseFocus, they're not really related to one another. Using one of them doesn't really mean you'll use any of the others. In that case, use delegates and let the user attach a callback to them individually. Finally, I'd be inclined to err on the side of delegates; they're slightly more flexible, and if you find you're always using a particular set of delegates, you can always write a base class that handles registering the delegates for you. Anyway, my AU$0.02 :) -- Daniel -- int getRandomNumber() { return 4; // chosen by fair dice roll. // guaranteed to be random. } http://xkcd.com/ v2sw5+8Yhw5ln4+5pr6OFPma8u6+7Lw4Tm6+7l6+7D i28a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP http://hackerkey.com/
Apr 17 2007