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).

  1. server has parameter in constructor: std::function<void(socket)> onaccept called in handleaccept.
  2. i create abstract class, iserverhandler or whatever, has 1 virtual method onaccept. server takes iserverhandler parameter in constructor , class instance owning server instance extends iserverhandler , constructs server *this parameter.

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 iterator interface 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 comparable interface.


Comments

Popular posts from this blog

get url and add instance to a model with prefilled foreign key :django admin -

android - Keyboard hides my half of edit-text and button below it even in scroll view -

css - Make div keyboard-scrollable in jQuery Mobile? -