2012-02-16 4 views
5

E.g. в разработке драйверов Linux можно найти макрос container_of. По сути, это обратный оператор для ->, который дает указатель на содержащую структуру, если у вас есть указатель на член.Настоящее имя шаблона «container_of»

Кроме того, из блога Грега Кроа я нашел этот шаблон в исполнении list и hash Пинтоса.

+3

Просто чтобы добавить в свой список, Windows имеет аналогичный макрос 'CONTAINING_RECORD'. Я не знаю об общем имени для шаблона. –

+1

Когда используется для реализации структур данных контейнера, буксировка вызывает этот метод «навязчивые контейнеры» в мире C++. Хотя container_of является более общим и полезным в других контекстах, чем для реализации общих структур данных, таких как списки и хэш-таблицы. – nos

ответ

2

Настоящее имя этого шаблона - «container_of()». Попытка подогнать этот C-ism в шаблонную схему проектирования Java или C++ бесполезна. Дело не в том, чтобы не связывать ответственность, либо назначать или делегировать что-либо. Если вы должны думать в этих терминах, то это «беспорядочное обобщенное наследование». Если вам не нужно думать в этих терминах, тогда это намного менее беспорядочно.

0

Я бы сказал, что это не очень эффектно Chain Of Responsibility. Единственная причина, по которой вам нужен указатель обратно в родительскую структуру контейнера, - это разместить функциональность родительского контейнера в пределах досягаемости содержащихся элементов. Таким образом, может рассматриваться как деталь реализации, необходимая для того, чтобы запрос просачивал «цепочку», пока он не будет обработан на правильном «уровне».

С отношением к контейнеру/содержанию этот «правильный» уровень находится всего на один уровень вверх, а стекание вверх не достигает достаточных уровней (поскольку существует только один уровень), чтобы вызвать большой интерес в качестве идеального примера шаблон. Тем не менее, общие идеи, стоящие за Chain of Responsibility, все еще сохраняются; запрос делается в точке в цепочке, которая не может ее обрабатывать, и обрабатывается в другой точке изменения, которое может.

С небольшим не общим контейнером/содержащимся соединением, соединение этой двух звеньев цепи может стать довольно плотным. Например, на ваших примерах отсутствует общая инфраструктура обработки команд (поскольку набор командных языков невелик), и такая инфраструктура обычно требует (для безопасности типов) объекта Command/Message. Это много накладных расходов, для списка, который просто хочет, чтобы его элементы непосредственно уведомляли на уровне элементов, которые они хотят удалить из списка.

И да, there is a C2 pattern's page for it ... Если вы согласны с моими рассуждениями.

Смежные вопросы