c++ - Pros & cons of a callback (std::function/std::bind) vs an interface (abstract class) -
i'm creating server application in c++11 using boost.asio. i've created class, server, takes care of accepting new connections. it's just:
void server::accept() { socket_.reset(new boost::asio::ip::tcp::socket(*io_service_)); acceptor_.async_accept(*socket_, boost::bind(&server::handleaccept, this, boost::asio::placeholders::error)); } void server::handleaccept(const boost::system::error_code& error) { if (!error) { // todo } else { trace_error("server::handleaccept: error!"); } accept(); } i've found 2 ways (i'm sure there more) "fix" todo comment, i.e. move socket wherever should go. in case want class instance owns server instance (which wraps in connection class , inserts list).
serverhas parameter in constructor:std::function<void(socket)> onacceptcalled inhandleaccept.- i create abstract class,
iserverhandleror whatever, has 1 virtual methodonaccept.servertakesiserverhandlerparameter in constructor , class instance owning server instance extendsiserverhandler, constructsserver*thisparameter.
what pros , cons of option 1 vs option 2? there better options? i'm having same problem in connection class (onconnectionclosed). also, depending on how decide design system, might need onpacketreceived , onpacketsent callback.
i prefer first way several reasons:
representing concepts/functionality via interfaces/class hierarchies makes code base less generic, flexible, , more difficult mantain or scale in future. kind of design imposes set of requirements on type (the type implementing required functionality) makes difficult modify in future, , prone fail when system changes (consider happens when base class modified in type of designs).
what called the callback approach classic example of duck typing. server class expects callable thing implements required functionality, nothing more, nothing less. no "your type must coupled hierarchy" condition required, the type implements handling free.
also, said server expects a callable thing: expected function signature. gives user more freedom when implementing handler. global function, bound member function, functor, etc.
take standard library example:
almost standard library algorithms based on iterator ranges. there no
iteratorinterface in c++. iterator type implements behaviour of iterator (being dereferenceable, comparable, etc). iterator types free, distinct, , decoupled (not locked given class hierarchy).another example comparators: whats comparator? is signature of boolean comparison function, callable takes 2 parameters , returns boolean value saying if 2 input values equal (less than, bigger than, etc) point of view of specific comparison criteria. there no
comparableinterface.
Comments
Post a Comment