Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> callback vs dependency injection, что лучше для Си++ 
V
    Опции темы
borisbn
Дата 16.1.2012, 11:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



Здравствуйте.
Частенько приходится организовывать обратные вызовы при наступлении какого-нибудь события.
Поймал себя на том, что в части случаев делаю так
Код

typedef void (*onData_f)( Data * ptr );
class A {
    A( onData_f a_on_Data ) : onData( a_on_Data ) {}
...
    if ( onData )
        onData( ... );
};

а иногда так
Код

struct Listener {
    virtual void onData( Data * ptr ) = 0;
};
class A {
    A ( Listener * listener ) : m_listener( listener ) {}
...
    if ( m_listener )
        m_listener->onData( ... );
};

struct ListenerImpl : public Listener {
    virtual void onData( Data * ptr ) { ... }
...
    A * a = new A( this );
};

Вопрос: как Вы считаете, какой из этих методов предпочтительнее ?
Спасибо.


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
boostcoder
Дата 16.1.2012, 11:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(borisbn @  16.1.2012,  11:41 Найти цитируемый пост)
typedef void (*onData_f)( Data * ptr );

нормальный сишный стиль. но как быть с доступом к приватным данным класса? как с биндингом аргументов?

Цитата(borisbn @  16.1.2012,  11:41 Найти цитируемый пост)
какой из этих методов предпочтительнее ?

чтоб поменьше писать - лямбда/boost::bind().
если же есть требования к производительности - тогда указатели на методы.

но это имхо, естественно.
PM WWW   Вверх
Earnest
Дата 16.1.2012, 12:38 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 53
Всего: 183



Я обычно поступаю так: если колбэк один (одна функция), то использую boost::function (который реализуется через функтор или указатель на функцию или что душа пожелает), а если реакций несколько (на несколько событий), то делаю абстрактный класс-колбэк с соответствующим числом методов.
boostcoder, доступ к переменным значения не имеет: с точки зрения принимающего алгоритма колбэк (или 5 колбэков) должен быть абстракцией типа "а что ты скажешь вот на это?". Так что вопрос реализации - дело чисто вкуса удобства.

Добавлено @ 12:41
С-шный указатель на функцию годится только для реализации колбэка, но не как определение - ибо слишком негибок. Хотя, конечно, бывают ситуации, когда точно известно, что дело будет происходить внутри класса (или иерархии классов), и тогда есть смысл использовать самое простое (указатель на функцию-член).


--------------------
...
PM   Вверх
borisbn
Дата 16.1.2012, 13:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



boostcoderEarnest, спасибо. Но я забыл упомянуть (каюсь) об одном нюансе - в большинстве случаев я не могу пользоваться шаблонами в интерфейсе, т.к. мы частенько "заворачиваем" реализацию в dll-ки, а наружу "торчит" лишь интерфейс. Т.е. связывание происходит не в compile-time, а в runtime.
Цитата(Earnest @  16.1.2012,  12:38 Найти цитируемый пост)
Хотя, конечно, бывают ситуации, когда точно известно, что дело будет происходить внутри класса (или иерархии классов), и тогда есть смысл использовать самое простое (указатель на функцию-член).

В этом случае (указатель на функцию-член) я должен знать о классе, который принимает колобок, а это нехорошо... Разве что как во втором примере с абстрактным классом, но тогда и разницы никакой нет.
Мне лично больше нравится второй вариант. Единственный плюс отдельных колбэков - некоторые можно оставить NULL, указывая тем самым, что они не используются. С абстрактным интерфейсом типа Listener такой трюк не пройдёт.


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
boostcoder
Дата 16.1.2012, 13:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



в таком случае, старый, добрый, но опасный, способ - указатель на void.
для функции - используешь один.
для методов - два.
и бинарная совместимость обеспечена.
PM WWW   Вверх
kosmonaFFFt
Дата 16.1.2012, 15:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 538
Регистрация: 14.4.2008
Где: Иннополис

Репутация: нет
Всего: 5



Цитата(borisbn @  16.1.2012,  17:10 Найти цитируемый пост)
Единственный плюс отдельных колбэков - некоторые можно оставить NULL, указывая тем самым, что они не используются. С абстрактным интерфейсом типа Listener такой трюк не пройдёт. 


Почему не пройдет?


Цитата(borisbn @  16.1.2012,  15:41 Найти цитируемый пост)
if ( m_listener )
        m_listener->onData( ... );


Вот и проходит, как вы, кстати, и писали.

А я бы сделал не один указатель на листенер, а список указателей и методы addListener(Listener*) и removeListener(Listener*). Но возможно это всего лишь Java наложила отпечаток на мой способ мышления. smile

Это сообщение отредактировал(а) kosmonaFFFt - 16.1.2012, 15:14


--------------------
user posted image
PM MAIL ICQ   Вверх
Earnest
Дата 16.1.2012, 17:03 (ссылка) |  (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 53
Всего: 183



Цитата(borisbn @  16.1.2012,  14:10 Найти цитируемый пост)
Единственный плюс отдельных колбэков - некоторые можно оставить NULL, указывая тем самым, что они не используются. С абстрактным интерфейсом типа Listener такой трюк не пройдёт. 

Это с какой стороны смотреть. Я вот считаю, что не плюс, а минус - надо проверять метод прежде чем вызвать
А что касается наследников колбэка-интерфейса - так я обычно не парюсь насчет "абстрактной чистоты", а делаю некоторые методы определения интерфейса не чистыми, а "пустыми" (чтобы не требовалось обязательное переопределение). Это же C++, а не IDL: делай что хочешь, только отвечай за то, что делаешь.


--------------------
...
PM   Вверх
mes
Дата 16.1.2012, 22:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(borisbn @  16.1.2012,  12:10 Найти цитируемый пост)
Единственный плюс отдельных колбэков

плюс отдельных функторов это легкая комбинируеммость... однако не всегда она нужна.. 



--------------------
PM MAIL WWW   Вверх
spyswamp
Дата 17.1.2012, 16:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 349
Регистрация: 18.8.2006

Репутация: 1
Всего: 7



Я пользуюсь сигналами.


--------------------
- why you call it beta?
- cuz it's betta then nothin'
PM MAIL   Вверх
borisbn
Дата 17.1.2012, 16:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



Цитата(spyswamp @  17.1.2012,  16:16 Найти цитируемый пост)
Я пользуюсь сигналами.

Это если есть 0x64%-ная уверенность в том, что тот, кто использует твою dll-ку, пользует тот же фреймворк (boost, Qt etc.), что и ты. Конкретно в моём случае есть ровно такая же уверенность в том, что dll-ка будет юзаться на разных фреймворках разными (по уровню знаний программирования) людьми.


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
spyswamp
Дата 17.1.2012, 17:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 349
Регистрация: 18.8.2006

Репутация: 1
Всего: 7



Я тему не читал, только первое сообщение. Тогда мне больше нравится второй вариант.


--------------------
- why you call it beta?
- cuz it's betta then nothin'
PM MAIL   Вверх
mes
Дата 17.1.2012, 18:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(borisbn @  16.1.2012,  10:41 Найти цитируемый пост)
Частенько приходится организовывать обратные вызовы при наступлении какого-нибудь события.

как много в этой фразе.. © 
1. наступление события можно ассоциировать с разным методом ( как у вас в примерах), а можно с разной структорой данных.. 
2. нет общего решения на все случаи жизни, для каждой модели ответного взаимодействия наиболее полно подходит разное решение..

Добавлено через 2 минуты и 33 секунды
для рантайм совместимости можно делать стык в С-стиле, и удобную обертку для пользования.. 



--------------------
PM MAIL WWW   Вверх
borisbn
Дата 17.1.2012, 18:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



Цитата(mes @  17.1.2012,  18:15 Найти цитируемый пост)
нет общего решения на все случаи жизни, для каждой модели ответного взаимодействия наиболее полно подходит разное решение..

Что ж. Кратко и понятно (впрочем, как всегда).
Походу, нет в жизни щазтья smile (It was a joke, если чо)
Всем откликнувшимся спасибо. Закрываю.


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.3123 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.