Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: си, паттерны ооп, разбиение на объекты, parent's parent
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
Страницы: 1, 2
Idle
не использую си++, использую си, абстрактные типы данных через incomplete structure pointer-ы
собственно вопрос, как правильно организовывать взаимодействие объектов, когда "вложенный объект" должен вызывать родителя родителя?

sm.gif ну например, есть палета ящиков с помидорами, ящик с помидорами, и помидор
помидор портится через неделю и вызывает владельца всей палеты, что я мол испорчен sm.gif

что почитать на эту тему с учётом языка?
ig_z
QUOTE (Idle @ Aug 15 2012, 21:57) *
помидор портится через неделю и вызывает владельца всей палеты, что я мол испорчен sm.gif

что почитать на эту тему с учётом языка?


Если речь о паттернах, то это похоже на обозреватель (он же наблюдаталь, он же подписчик)
http://ru.wikipedia.org/wiki/Design_Patterns
Idle
Цитата(ig_z @ Aug 15 2012, 23:54) *
Если речь о паттернах

да, речь о том как правильно спроектировать - выделить модули и определить взаимодействие между ними, в литературе по си такого не встречал

поясню вопрос из примера: помидор, при протухании должен вызвать функцию менеджера склада, сообщив, в какой палете он находится, но помидор, как объект, про палету ничего знать не должен, иначе или надо сохранять её номер при заполнении ящика (и протаскивать номер насквозь через модули) или открывать структуру ящика и палеты для помидора
Lotor
Цитата(Idle @ Aug 16 2012, 00:17) *
поясню вопрос из примера: помидор, при протухании должен вызвать функцию менеджера склада, сообщив, в какой палете он находится, но помидор, как объект, про палету ничего знать не должен, иначе или надо сохранять её номер при заполнении ящика (и протаскивать номер насквозь через модули) или открывать структуру ящика и палеты для помидора

Callback обычный же.
_Pasha
Цитата(Lotor @ Aug 16 2012, 08:03) *
Callback обычный же.

Ага, щаз!
Помидорр обращается с челобитной к самому Путину,не забыв при этом оставить свой адрес, а он, опускаясь по иерархии, идентифицирует все координаты несчастного.
Долго (бюрократия, йо!), но остальные методы требуют накладных расходов. Зато голова списка подшефного хозяйства видна всем. Ага?
Idle
Цитата(_Pasha @ Aug 16 2012, 10:20) *
Долго (бюрократия, йо!), но остальные методы требуют накладных расходов. Зато голова списка подшефного хозяйства видна всем. Ага?

мда, сейчас я так и делаю - структура палеты открыта для всех, но её приходится протаскивать "насквозь" сверху донизу до последнего помидора, чтобы помидор указал хозяину на палету
вот эта вся детско-родительская история наводняет мне интерфейсы, ломает абстракцию и мешает делать TDD
вот я пришёл к выводу что я что-то делаю не так и чего-то не знаю
Cosmojam
А если callback-и сохранять указателем в каком-то глобальном массиве? Тогда у помидоров есть доступ только к глобальному массиву, но нет и не нужно знать об "объекте" на "метод" которого указывает конкретный элемент массива.
AHTOXA
Цитата(_Pasha @ Aug 16 2012, 12:20) *
Помидорр обращается с челобитной к самому Путину,не забыв при этом оставить свой адрес

Во-первых, это злостное нарушение субординации. Во-вторых, максимум, что известно помидору - это то, что он сидит в ящике. Поэтому так: помидор сообщает ящику, а тот - дальше по иерархии.
Ответная реакция такая же, только вниз по цепочке.
_Pasha
Цитата(AHTOXA @ Aug 16 2012, 10:32) *
Во-первых, это злостное нарушение субординации. Во-вторых, максимум, что известно помидору - это то, что он сидит в ящике. Поэтому так: помидор сообщает ящику, а тот - дальше по иерархии.
Ответная реакция такая же, только вниз по цепочке.

Аа, точно! Злостная ошибка у меня. Без поля owner не получится. А также peer_next, peer_prev ... селяви. Иначе - поиски по деревьям роняют всю производительность.
Idle
эволюция примерно такая, сначала всё изолированно и отлично тестируется, в конце всё наводняется родителем родителя, т.к. менеджером дело-то не ограничивается, взаимодействия-то могут происходить не только с менеджером, а ещё с уборщицей, которая это всё дело протухшее будет убирать и т.п.

собственно вопрос не в том, как "моргнуть светодиодом", а как это делается - ссылки, ссылки sm.gif

CODE
--------------------------------------------------------------------------------
/*
* manager doesn't care about the box
*/
tomato.c
---
struct tomato {
int weight;
/* ... */
};
struct tomato *tomato_create(void)
void tomato_destroy(struct tomato *tomato);
int tomato_set_weight(struct tomato *tomato, int weight);
int tomato_get_weight(const struct tomato *tomato);
/* ... */
static void tomato_rot(struct tomato *tomato)
{
manager_call();
}

box.c
---
struct box {
struct tomato *tomatos;
int count;
/* .. */
};

struct box *box_create(void);
int box_destroy(struct box *box);
int box_add(struct box *box, struct tomato *tomato);
--------------------------------------------------------------------------------
/*
* manager does care about the box
*/
tomato.c
---
struct tomato {
struct box *parent;
/* ... */
};
struct tomato *tomato_create(const struct *box)
{
/* ... */
tomato->parent = box;
/* ... */
}
static void tomato_rot(struct tomato *tomato)
{
manager_call(box);
}
--------------------------------------------------------------------------------
/*
* pallet comes into play!
*/

pallet.h
---
struct pallet {
struct box *box;
/* ... */
}

box.c
---
struct box {
struct pallet *pallet;
struct tomato *tomatos;
int count;
/* .. */
};

struct box *box_create(struct pallet *pallet);
int box_destroy(struct pallet *pallet, struct box *box);
int box_add(struct pallet *pallet, struct box *box, struct tomato *tomato);

tomato.c
---
struct tomato {
struct pallet *pallet; /* instead of the box */
/* ... */
};
struct tomato *tomato_create(struct pallet *pallet)
{
/* ... */
tomato->pallet = pallet
/* ... */
}
void tomato_destroy(struct pallet *pallet, struct tomato *tomato);
int tomato_set_weight(struct pallet *pallet, struct tomato *tomato, int weight);
int tomato_get_weight(struct pallet *pallet, const struct tomato *tomato);
/* ... */
static void tomato_rot(struct tomato *tomato)
{
manager_call(tomato->pallet);
}
_Pasha
Дык... томат говорит "уберите меня!!!" т.е отправляет сообщение.
Тот, кому по должностной инструкции положено, обрабатывает сообщение и убирает.
Т.е., поскольку "всё уже украдено до нас" - основные дебри сложности переносятся на обработку и маршрутизацию эвентов. А Вы хотите их сразу же удобно типизировать sm.gif а оно требует софта для принятия решения, куда это дальше перенаправить.
SSerge
Цитата(Idle @ Aug 16 2012, 01:57) *
не использую си++,
................
что почитать на эту тему с учётом языка?

А вот про исключения и их распространение в С++ и почитать. И вообще про механизм исключений (exeptions) в других языках.
Ибо то, что хочется это и есть типичное применение этого механизма, который можно и на С реализовать, если очень захотеть.
ARV
имхо, все с ног на голову! яйцо курице ничего не сообщает, это курица за яйцом следит, поворачивает его, греет и т.д.! помидор понятия не имеет, кто им владеет, и НЕ ДОЛЖЕН (имхо) никому САМ сообщать о своем самочувствии! палетта, тарелка, повар или иной владелец помидора должен запросить его состояние сам.

в этом раскладе отсутствует необходимость СНИЗУ ВВЕРХ знать своих "владельцев". СКЛАД имеет коллекцию СТЕЛЛАЖЕЙ, стеллаж - коллецию ПАЛЛЕТ, паллета - коллекцию ЯЩИКОВ, а ящик - коллецию ОВОЩЕЙ. каждые имеет метод GetState(). Начинается все с того, что мы запрашиваем СКЛАД.GetState(). В этом методе склад делает для каждого элемента коллекции стеллажей СТЕЛЛАЖ[i].GetState() и так далее.

по-моему, так гораздо логичнее.

P.S. кстати, тут отношения владелец-объект, а вовсе не родитель-ребенок. помидор никак не может быть ребенком палетты или ящика.
Idle
Цитата(_Pasha @ Aug 16 2012, 12:57) *
Тот, кому по должностной инструкции положено, обрабатывает сообщение и убирает.

обрабатывать положено объекту менеджера, тут вопрос как правильно довести сообщение до менеджера от вложенной сущности палеты так, чтобы сохранить абстракции и избежать "сквозняка" будь он хоть в виде проходных обратных пробросов по цепочке родителей, хоть в виде проходного сохранения главного родителя внизу

Цитата(_Pasha @ Aug 16 2012, 12:57) *
А Вы хотите их сразу же удобно типизировать sm.gif.

ну менеджер(компоненты системы) типизирован и абстрагирован без меня, моё дело - палета и ниже
а внутри я удобно типизирую ввиду тестирования и tdd из-за оболваненности западной пропагандой sm.gif


Цитата(SSerge @ Aug 16 2012, 13:29) *
А вот про исключения и их распространение в С++ и почитать. И вообще про механизм исключений (exeptions) в других языках.
Ибо то, что хочется это и есть типичное применение этого механизма, который можно и на С реализовать, если очень захотеть.

посмотрю, спасибо

Цитата(ARV @ Aug 16 2012, 13:47) *
имхо, все с ног на голову! яйцо курице ничего не сообщает
...
по-моему, так гораздо логичнее.

это всё классно, но "поллинг" штука накладная, поэтому в спецификации на склад мне специфицировали именно "прерывание"
но если именно так и принято, то спасибо за ответ
ARV
Цитата(Idle @ Aug 16 2012, 13:56) *
это всё классно, но "поллинг" штука накладная, поэтому в спецификации на склад мне специфицировали именно "прерывание"
но если именно так и принято, то спасибо за ответ


принято или нет - это вопрос вкуса. лично я учился ООП по парадигме "ООП лучше отражает структуру реального мира". В реальном мире никогда помидор никому о себе ничего не сообщает, разве что вонью на весь склад sm.gif и если бы я решал эту задачу, я бы сводил ее к созданию иерархии классов, наиболее адекватно отражающей объекты реального мира.


в случае с "сообщениями" вы просто вынуждены породить некий класс "диспетчера", который должен знать, как с сообщениями поступать и т.д. в конечном счете, обработка очереди сообщений - тот же поллинг, только вынесенный в отдельный объект, наделенный особыми свойствами. В реальном мире диспетчер тоже есть - менеджер, но в реальном мире он сам решает, когда и откуда взять данные о состоянии склада, палетты и т.д. а в вашей модели вы заставляете гнилые помидоры самостоятельно жаловаться менеджеру... имхо, как-то не нормально это...

Idle
да, у меня есть текcтовое описание того, какие есть компоненты у системы и как они взаимодействуют; разбивать сиситему на объекты сам я не властен
то есть у меня описано что вот мол есть палета, есть менеджер, есть холодильник, есть ещё что-то, описана начинка и взаимодействие этого добра друг с другом
моё дело - реализация согласно описания

Цитата
принято или нет - это вопрос вкуса

может быть, просто это всё поддерживать надо, вопрос у меня именно про best practices
Xenia
Цитата(Idle @ Aug 15 2012, 22:57) *
не использую си++, использую си, абстрактные типы данных через incomplete structure pointer-ы собственно вопрос, как правильно организовывать взаимодействие объектов, когда "вложенный объект" должен вызывать родителя родителя?


Нет ничего нового под солнцем sm.gif - практически все механизмы взаимодействия объектов уже открыты и где-то используются. Общение дочерних объектов с родительскими широко применяется в библиотеках классов GUI, например, таких как MFC или VCL.

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

А для большего удобства в этом же супербазовом классе (superbase) лучше сразу создать переменную (указатель), в которой каждый объект будет помнить указатель на своего родителя (естественно, приведенного к типу superbase*). Например, классу superbase достаточно выглядеть так:

class superbase
{
Piblic:
superbase *myParent;
superbase(superbase *parent) { myParent = parent; }
};

В принципе родительские и дочерние объекты могут быть совершенно разными по своим структурам классами, их переписывать не надо, а достаточно ОБЪЕДИНИТЬ с классом superbase! Скажем были раньше у вас три класса Object1, Object2 и Object3, на основе которых вы порождали состоящие в родстве объекты: бабушку, мать и дочь. А теперь создайте для них новую тройку объектов:

class Family1 : public superbase, public Object1 // это для бабушки
{
Family1(superbase *parent, ...) : superbase(parent), Object1(...) { ... }
};

class Family2 : public superbase, public Object2 // это для матери
{
Family2(superbase *parent, ...) : superbase(parent), Object2(...) { ... }
};

class Family3 : public superbase, public Object3 // это для дочери
{
Family3(superbase *parent, ...) : superbase(parent), Object3(...) { ... }
};

Мы видим, что новые семейные классы (Family1, Family2, Family3) функционально тождественны старым индивидуальным классам (Object1, Object2 и Object3) соответственно. А троеточием я обозначила список тех параметров, которыми инициируются старые классы. Фактически, семейные классы отличаются от старых только одним - дополнительным параметром parent и способностью его запоминать в своей переменной myParent.

Процесс рождения чада сопровождается тем, что родитель при вызове конструктора сообщает, помимо прочего, указатель на самого себя (this), чтобы ребенок мог его запомнить:

new Family3 child1( this, ...);

Теперь дитя child1 всегда будет помнить свою маму в child1.myParent. Ну а самый старый патриарх, которого порождает уже не семья, а само приложение, инициируется с парамером NULL вместо указателя на parent. В смысле, что родителя у него среди семьи нет.

Весь смак в том, что теперь любой потомок будет способным не только узнать адрес своего родителя по myParent, но и обратиться к нему (вызвать по этому поинтеру какую-нибудь родительскую функцию). А если возникнут затруднения с доступом, то поинтер myParent всегда можно привести к полному указателю на родительский класс динамически.

Точно так же можно достучаться до предка в любом поколении через цепочку myParent->myParent->...->myParent. И если на каком-то этапе очередной myParent окажется равным NULL, то это родоначальник династии, и глубже опускаться по генеалогическому древу не надо. Например, послание собственной бабушке будет выглядеть так:

myParent->myParent->Message = "Здравствуй, бабуля!";

А послание прадедушке так:

myParent->myParent->myParent->Message = "Привет, прадед!";

Если последнее поколение - помидор, а предок всего сущего - admin, то жалобу ему помидор может оправить, либо вызвав myParent от myParent столько раз, каким по счету поколением от него является помидор. А если он точно этого не знает, то легко может узнать, проследив эту цепочку до нуля:

superbase *Admin = myParent;
while(Admin->myParent != NULL) Admin = Admin->myParent; // спускаем админа вглубь, пока не достигнем сироты
Admin->Message = "Караул! Загниваю!";
sm.gif
AlexandrY
Цитата(Idle @ Aug 16 2012, 13:15) *
да, у меня есть текcтовое описание того, какие есть компоненты у системы и как они взаимодействуют; разбивать сиситему на объекты сам я не властен
то есть у меня описано что вот мол есть палета, есть менеджер, есть холодильник, есть ещё что-то, описана начинка и взаимодействие этого добра друг с другом
моё дело - реализация согласно описания


может быть, просто это всё поддерживать надо, вопрос у меня именно про best practices


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

Поэтому когда низший уровень не желающий знать о пертурбациях наверху и контекст хочет что-то туда передать он типизирует только первые наиболее абстрактные(или наиболее конкретные, кому-как wink.gif ) записи структур и что-то с ними передает.
Далее сообщение получает промежуточный уровень который типизирует структуры еще глубже для передачи своей информации, и так до верха пока к менеджеру не придет полностью типизированная под него структура со всеми данными.


Кстати, так оно физически (на бинарном уровне) в объектных языках и делается.
_Pasha
Цитата(Xenia @ Aug 16 2012, 13:49) *
например, таких как MFC или VCL.

не, лучше GTK. Там всё по косточкам можно разобрать при стойком желании.

2Idle: ну вот, исключения, теперь RTTI тянется за задачей...
Цитата
а внутри я удобно типизирую ввиду тестирования и tdd из-за оболваненности западной пропагандой

У Вас же всё равно tdd подчинено требованиям более верхнего уровня?
Idle
Цитата(_Pasha @ Aug 16 2012, 15:29) *
У Вас же всё равно tdd подчинено требованиям более верхнего уровня?

не подчинено, иногда в описании явно прописаны контейнеры различного добра, понятно что это отдельный модуль
на сишные модули я выделяю сам, тесты тоже сам придумываю для них
kolobok0
Цитата(Idle @ Aug 15 2012, 22:57) *
...как правильно организовывать взаимодействие объектов, когда "вложенный объект" должен вызывать родителя родителя?..палета .., ящик, ..и помидор. помидор ...вызывает владельца...что почитать на эту тему с учётом языка?


1) Тут господин ARV всё правильно сказал. +100500
Осталось только перечислить и выбрать способ реагирование на протухание(я специально не сказал натификации - потому что и это под вопрос можно поставить)
2) Если говорить об ОО подходе, то всё просто - он идёт от жизни и это принципиально в его юзанье . Почему - отдельная тема, если захотите могу разъяснить это. А теперь отталкиваемся от задачи. И в каком городе есть супер-пупер чудо помидоры которые орут хозяину что они протухли???? ну вот покажите мне, или подскажите где их глянуть можно? Посему глупости это. Потом придётся костыли крутить при таком подходе(предпологать что так лучше - орать помидору про протухание). Либо вы чего то утаили. А если так - то увы это круглый конь в вакууме.
Возвращаясь к баранам...
1) Имеем овощехранилище
2) палетты, ящики, помидоры.
3) Того кто следит. Это либо человек либо автоматика (по температуре, хим состоянию и иже).

Посему...
Помидор выкидывает некий признак(по жизни) - запах, цвет, мягкость. Это и отслеживаем...

НЕТ никакой натификации - это вздор. Если хотите - отсебятина, желание упростить или сделать как знается мне... Вот именно это и ведёт к костылям(отдельная тема).

прелесть в Объектно Ориентированном Анализе и Проектировании - именно взятие от жизни.

4) книг в разрезе си - не найдёте. априори это не ОО язык. Книгу одну только рекомендую - одного из основоположников ООА и ООП - Гради Буча. Для тех кто просто листал или просто читал эту книгу ("Объектно Ориентированный Анализ и Программирование") - рекомендую хотя бы одну задачу сделать стэп-бай-стэп по методике описанной в этой книге.

ЗЫ
5) Вы заметьте - люди которые слабо разбираются в ООА(анализе, а не коде) и ООП(проектировании а не программировании) - начинают свои рассуждения с технической стороны дела - коллекции, циклы, коллбэки, функции, векторы, листы и т.д... и путаются... потому как не понимают что ОО это методология, а не тот или иной язык...
_Pasha
Хорошая мысль, кстати. Про дисциплину инженерной интерпретации задачи. Скажем, сгнившее яблоко, упавшее по этой причине на голову некого Ньютона, имеет право о себе заявить, что оно упало sm.gif ,а сгнивший помидор должен быть замечен. Потому в первом случае - эвент, во втором - поллинг.
Idle
Цитата(kolobok0 @ Aug 16 2012, 18:33) *
И в каком городе есть супер-пупер чудо помидоры которые орут хозяину что они протухли? Либо вы чего то утаили.

да, естественно я ничего не расскажу про задачу, помидоров конечно нет, есть сетевые потоки, пакеты, таймауты, записи в таблицах, хранилища пакетов одного вида, другого вида, третьего, перетасовка их туда-сюда и т.д. и т.п.
не я разбиваю систему на функциональные блоки и не я определяю взаимодействие между ними, моё дело - реализация sm.gif

Цитата(kolobok0 @ Aug 16 2012, 18:33) *
4) книг в разрезе си - не найдёте.

одна книжка точно есть "Object-oriented programming with ANSI C"
kolobok0
Цитата(Idle @ Aug 16 2012, 18:56) *
...есть сетевые потоки, пакеты, таймауты, записи в таблицах, хранилища пакетов одного вида, другого вида, третьего, перетасовка их...не я разбиваю систему на функциональные блоки...


это немного другой коленкор - согласитесь. и мне кажется, лучше спрашивать тут народ именно в разрезе реализации именно сетевых дел. в своё время при реализации протоколов преследовал задачу - меньше копировать данные. по поводу то, что Вы стеснены в выборе всех плюсов "у плюсов" sm.gif это плохо. тут как правило консерватория намудрила...

возвращаясь к нотификации.. и к коду sad.gif

тут уже прозвучало о супер классе (в плюсах это закос через статик методы). пойдём в эту сторону.
одно из решений...(подчеркну слово одно из)
мысль следующая...
у вас есть типизация сущности. у вас есть типизация события(я так понимаю вы работаете в "событийных рамках" задачи). вам никто не запрещает создавать понятие коллекций по типам сущностей. При этом набор ивентов ограничен. Вам никто не мешает "подписаться" на конкретное событие конкретного типа сущности в любом месте логики... на плюсах это просто. на сях как лучше - тут немного подумать нуна.
Idle
Цитата(Xenia @ Aug 16 2012, 14:49) *
Для того, чтобы организовать такое взаимодействие, очень желательно породить (как производные классы) все объекты, участвующие в родственных отношениях, от одного (супер)базового класса, хотя бы и формального

да, то что надо

Цитата(AlexandrY @ Aug 16 2012, 14:54) *

ага

посмотрел на использование структуры kobject в ядре linux - оно
структура вставляется внутрь "класса" и указатель на неё (а не на сам экземпляр родителя) передаётся при создании потомка и сохраняется в kobject потомка в поле parent
и потом по цепочке parent->parent->...->parent можно добраться до самого верха не зная о реализации родителей
указатель на саму структуру (там где её начинка известна) можно получить через container_of
в моём случае нужен дополнительный клей для того чтобы отдать менеджеру указатель именно на палету, а не на встроенный kobject, но это не важно.

CODE
Kobjects are usually embedded in other structures and are generally not interesting on
their own. Instead, a more important structure, such as struct cdev, defined in
<linux/cdev.h>, has a kobj member:
/* cdev structure - object representing a character device */
struct cdev {
struct kobject kobj;
struct module *owner;
const struct file_operations *ops;
struct list_head list;
dev_t dev;
unsigned int count;
};


осталось, собственно, два момента
- как оформить интерфейсы между модулями: если везде передавать kobject, то будет куча container_of даже там, где вызов метода идёт сверху, а если делать разделение вызов сверху/снизу - будет путаница
- как юнит-тестить вызовы снизу вверх, т.е. нужно насоздавать цепочку родителей и только потом за_stub_ить метод
_Pasha
Цитата(Idle @ Aug 16 2012, 21:26) *
посмотрел на использование структуры kobject в ядре linux - оно
структура вставляется внутрь "класса" и указатель на неё (а не на сам экземпляр родителя) передаётся при создании потомка и сохраняется в kobject потомка в поле parent
и потом по цепочке parent->parent->...->parent можно добраться


Полиморфизм вынесен отдельно за пределы реализации класса.
А по отношению к экземплярам класса parent->parent->... превращается в доступ по указателю на указатель.
ЗЫ только что получил в рассылке виртуальные функции на Си
Еще не читал, но осуждаю sm.gif
ЗЗЫ ремарка понравилась
Цитата
C++ doesn't allow straightforward, dynamic changes to vtable entries (such changes inherently change the type of the object), but it does allow the implementation of a state machine just as you describe...

По первой части - таки да, на Си таблица виртуальных функций получается экономнее и интереснее... а стейт-машины и того проще sm.gif
andrewlekar
Хотите сделать хорошо - делайте проще. Заведите список для палетт, в нём указатели на списки для ящиков, в них указатели на списки для помидоров. Помидоры - тупо структуры и делать ничё не умеют.
ReAl
Цитата(_Pasha @ Aug 17 2012, 07:28) *
ЗЫ только что получил в рассылке виртуальные функции на Си
Еще не читал, но осуждаю sm.gif
Ну где-то так у нас и писалась в конце 80-ых на ДВК поддержка печати на разные по набору команд матричные принтеры и в разных граф. режимах.


Цитата(andrewlekar @ Aug 17 2012, 07:57) *
Помидоры - тупо структуры и делать ничё не умеют.
Если они помидоры. А если банки с помидорами, то очень даже ничего бахнуть могут. Поэтому надо таки идти от задачи, не всегда попытка объяснить через простые аналогии заводит куда надо.
andrewlekar
Цитата
Если они помидоры. А если банки с помидорами, то очень даже ничего бахнуть могут. Поэтому надо таки идти от задачи, не всегда попытка объяснить через простые аналогии заводит куда надо.

Активные объекты в природе куда реже встречаются, чем об этом думают апологеты ООП.

Если уж сильно нужно использовать нотификацию от объектов, то вот 2 нормальных варианта (без нагромождений всяких пэрентов, визиторов и прочей лабуды):

1. pomidor.setManager(pomidorManager)
2. pomidor.onActionEvent = pomidorManager.actionEventHandler
Idle
Цитата(andrewlekar @ Aug 17 2012, 13:04) *
1. pomidor.setManager(pomidorManager)

указатель на конкретного менеджера изначально знает только конкретная палета в которой находится коробка в которой находится помидор
собственно вопрос был в том какой подход использовать, чтобы привязать помидор к палете в которой он находится, чтобы сообщить менеджеру о конкретной палете
andrewlekar
Цитата
указатель на конкретного менеджера изначально знает только конкретная палета

Это плохой дизайн, на мой взгляд. Более того, изначально на конкретного менеджера вообще ни у кого не должно быть указателя. Изначально там должна быть заглушка или null, для того, чтобы можно было класс тестировать изолированно.
Idle
Цитата(andrewlekar @ Aug 17 2012, 13:56) *
Это плохой дизайн, на мой взгляд.

а как по другому? оно как происходит: создаётся структурка "менеджер", создаётся структурка "палета", они через некий клей находят друг друга и сохраняют внутри некий абстрактный указатель через который дёргают методы друг друга
это не моя архитектура и ничего сделать я с этим не могу, моё дело - начинка "палеты", дело других программистов - начинка "холодильника" и т.п. sm.gif
мне нужно понятно и с достоинством sm.gif вытащить указатель на менеджера
ARV
сначала программисты "из удобства" создают некий выдуманный мир своих объектов, а потом начинается долгое объяснение того, как это здорово, когда холодильник заказывает продукты в интернет-магазине... в результате система умный дом вызывает наряд полиции для устранения угрозы жизни хозяину, который всего-навсего решил развлечься в стиле BSDM - умный дом увидел у подруги наручники и принял решение...

уважаемые господа программисты! пожалуйста, вернитесь на грешную землю! никогда помидор ни при каких условиях НЕ МОЖЕТ, НЕ ДОЛЖЕН и даже НЕ ИМЕЕТ ПРАВО знать о палетте, о каком-то менеджере и т.д.! НУ НЕ ЕГО ЭТО ПОМИДОРСКОЕ ДЕЛО!

не плодите сущности без нужды! не оправдывайте свое желание сделать франкенштейна "удобством" (для кого?!), скоростью (кого она волнует при нынешних мегагерцах?!) или еще чем-то! остров доктора Моро должен остаться лишь плодом фантазии, не пришивайте руки-ноги помидору!!!!

Цитата(Idle @ Aug 17 2012, 14:06) *
мне нужно понятно и с достоинством sm.gif вытащить указатель на менеджера
похабно впихнутое врядли можно с достоинством вытащить... см. выше
Idle
Цитата(ARV @ Aug 17 2012, 14:49) *

ок, дались тебе эти помидоры, не могу я реальную задачу здесь описать
вопрос не про то как жить дальше, а про то что раз уж есть иерархия объектов, как из этого сделать my best
andrewlekar
Как делать best надо спрашивать того, кто эту архитектуру задумал. В вашем случае, самое грамотное будет - сделать абы как, лишь бы работало. Если есть у "помидора" указатель на его контейнер, то дёргать контейнер, а тот пускай дергает менеджера, так как знает о нём - это в случае, если есть возможность менять код контейнера. Если есть глобальный список всех менеджеров, то можно опросить их всех и попробовать найти свою собственную паллету по ним - это в случае, если апи позволяет.
kolobok0
Цитата(ARV @ Aug 17 2012, 14:51) *
...в результате система умный дом...


+100500

и ышо 5 копеек...
только траблы наступают раньше. ОО сущности от клиента = есть статика. А вот надуманное от программирования = без костылей не будет жить, если клиент всего-то потребовал модернизировать его логику. именно поэтому найденные сущности ОО методологией дают код малоизменяющийся на всём времени жизни проекта. а это существенный плюс, который не могут дать другие методологии разработки софта.
andrewlekar
ОО сущности от клиента - это всегда пассивные объекта, ака структуры. Так что разбиение на структуры присущие предметной области - это и правда плюс. Но ООП тут и не пахнет.
Idle
Цитата(andrewlekar @ Aug 17 2012, 15:19) *
Если есть у "помидора" указатель на его контейнер, то дёргать контейнер, а тот пускай дергает менеджера, так как знает о нём - это в случае, если есть возможность менять код контейнера.

так и делаю, протаскиваю указатель на контейнер сверху вниз, там где "помидорчик протух" он дёргает контейнер, а тот уже дёргает "менеджера"
выглядит всё это паршиво и засоряет интерфейсы, вот и пытаюсь как-то упорядочить доступ к верхнему контейнеру и интерфейсы, цепочка parent->...->parent хотя бы выглядит стандарным подходом

Цитата(andrewlekar @ Aug 17 2012, 15:19) *
Если есть глобальный список всех менеджеров, то можно опросить их всех и попробовать найти свою собственную паллету по ним - это в случае, если апи позволяет.

нет, такого нет
kolobok0
Цитата(andrewlekar @ Aug 17 2012, 15:24) *
...разбиение на структуры присущие предметной области - это и правда плюс. Но ООП тут и не пахнет.


тогда прошу вас подсказать: где по Вашему начинается проектирование?


Цитата(Idle @ Aug 17 2012, 15:33) *
...указатель на контейнер сверху вниз...


вам несколько раз правильно сказали уже - помидор ничего не знает о месте его нахождения. ну нет на нём записи страна-дом-улица-склад-шкаф-палета..нету...
он может известить весь мир что он протух (запах испортить). а вот конкретно ударить в нос менэджеру - этого нету. если палетта умная и по весу(или теплу) определяет протухание - она может придпринять действия. может ловить запах в каждом посадочном месте помидора.

и строго говоря указатель на парэнт - звоночек о том, что консерваторию надо менять...
Idle
Цитата(kolobok0 @ Aug 17 2012, 17:51) *
и строго говоря указатель на парэнт - звоночек о том, что консерваторию надо менять...

ок, менять начальника/работу/страну я не буду по этому поводу, так что вот sm.gif
и что делать в этом случае? опрос проходом сверху вниз? опрашивать сотни объектов? поллинг т.е. ?
как это называется, где написано что это плохо, по каким словам гуглить "c++ code smells" or what?
ARV
Цитата(Idle @ Aug 17 2012, 18:35) *
и что делать в этом случае? опрос проходом сверху вниз? опрашивать сотни объектов? поллинг т.е. ?
а если сотни объектов пошлют месседжи - это, конечно, кардинально изменяет ситуацию?
Цитата(Idle @ Aug 17 2012, 18:35) *
как это называется, где написано что это плохо
где написано, что поллинг - плохо? в ОС Windows ВСЕ события рождаются в результате ПОЛЛИНГА, система callback-ов весьма слабенькая... и Билл Гейтс не рвет пейсы от этого sm.gif
Idle
Цитата(ARV @ Aug 17 2012, 18:59) *
а если сотни объектов пошлют месседжи - это, конечно, кардинально изменяет ситуацию?

так сообщения ожидаются редко, или это не имеет значения?

Цитата(ARV @ Aug 17 2012, 18:59) *
где написано, что поллинг - плохо? в ОС Windows ВСЕ события рождаются в результате ПОЛЛИНГА, система callback-ов весьма слабенькая... и Билл Гейтс не рвет пейсы от этого sm.gif

не знаю, _ты_ мне скажи где написано как надо делать, ссылку пока дали только одну - ни с родителями ни с поллингом не связанную sad.gif

ARV
все, что я хотел, я _вам_ сказал, добавить могу только путем развития темы... но _вас_, очевидно, это не интересует...
_Pasha
Цитата(kolobok0 @ Aug 17 2012, 16:51) *
вам несколько раз правильно сказали уже - помидор ничего не знает о месте его нахождения.
[кусь]
и строго говоря указатель на парэнт - звоночек о том, что консерваторию надо менять...

Это понятИйное sm.gif
Помидор не знает, где находится, но обязан знать, кому жаловаться на свое состояние. Такшта.
Но есть масса чисто технических вопросов: а кто ему, собсна, отдает поток исполнения, этому овосчу?
Становится похоже на то, что и эвенты и поллинг окажутся одинаково хлопотными по ресурсам.
Это всё от постановки задачи biggrin.gif Idle, без хотя бы альтернативной формулировки, тема так и останется флеймообразной. Мсм.
ARV
Цитата(_Pasha @ Aug 17 2012, 19:43) *
Это понятИйное sm.gif
Помидор не знает, где находится, но обязан знать, кому жаловаться на свое состояние. Такшта.
традиционное, как я говорил, для программистов: обязать ни в чем не повинный помидор и потом с него требовать sm.gif в реальной жизни так не бывает. и чем сильнее абстагирование от реальности, тем сложнее объяснить смысловые взаимосвязи... "Заводной апельсин" - читали? wink.gif
Idle
Цитата(ARV @ Aug 17 2012, 19:34) *
добавить могу только путем развития темы... но _вас_, очевидно, это не интересует...

а что мешает развить тему и как ты решил что меня это не интересует?

Цитата(_Pasha @ Aug 17 2012, 19:43) *
Это понятИйное sm.gif
Idle, без хотя бы альтернативной формулировки, тема так и останется флеймообразной. Мсм.

это секретная информация, мне просто заменить поток или фрагмент пакета на помидор, но придумать что-то дальше сложнее - всё равно скажут что у меня всё протухло и надо всё переделывать а вот это мне не надо - всё переделать не в моей власти sad.gif
kolobok0
Цитата(Idle @ Aug 17 2012, 20:58) *
...всё равно скажут что у меня всё протухло и надо всё переделывать а вот это мне не надо - всё переделать не в моей власти sad.gif


вам выше уже не раз сказали и объяснили. чтоб ничего не переделывать в будущем - выход один - делать так как считает(оперирует понятиями) заказчик в реальной работе. т.е. если идёт речь о пакетах протокола - значит это кандидат на сущность. у него есть глаголы(то что он может делать в системе) извещать, пищать, подпрыгивать. Есть место его хранения. Озу - на сущность не подходит, потому как в рассуждениях мало работает как отдельная еденица... но есть контейнеры.... и т.д.. и т.п.. Вы хотите чтоб тут народ родил за вас объектную модель вашего бизнеса(задания)??? А Вы чтоб потом закодили...кхм.. красиво аднака...

возвращаясь к баранам...
только опираясь на эти сущности (которыми оперируют в разговорах спецы рядом с вами) вы сможете выстроить (подчеркну ещё раз - это очень важно!) статическую модель сущностей которые будут константа на протяжении жизни всего объекта. т.е. они будут последними кандидатами на пересмотрение или модификацию. Исходя из этого ничего у вас не протухнет. Это будет означать, что бизнес задача вся сама по себе изменилась. что бывает крайне редко(война, наводнение, потоп, конец света - кстати скоро sm.gif ). Отсюда видно, что переделывать Вам при таком подходе не придётся. Потому как если меняется бизнес задача - обычно делают заново всю структуру и взаимодействие. Это шире(!) чем рефакторинг...
Idle
Цитата(kolobok0 @ Aug 17 2012, 23:18) *
Вы хотите чтоб тут народ родил за вас объектную модель вашего бизнеса(задания)??? А Вы чтоб потом закодили...кхм.. красиво аднака...

ты очень лихо фантазируешь о том что я хочу, всегда так делаешь? в чём сложность спросить у меня "ты хочешь, чтобы я придумал объектную модель?" и подождать мой ответ? тебе так проще? что мне сделать, чтобы упростить наше общение чтобы тебе не пришлось фантазировать?

Цитата(kolobok0 @ Aug 17 2012, 23:18) *
возвращаясь к баранам...

возвращаясь к баранам, я, прочитав толстое описание, которое выдают спецы из отдела по выдаче описаний, сделал себе объектную модель, в которой есть иерархия объектов, у вложенных объектов в контейнерах есть, например таймеры на устаревание очереди фрагментов пакета, прекращения потока, эти вложенные объекты взаимодействуют с другими компонентами системы только через родительский объект
я пришёл сюда и спрашиваю - как достучаться до родителя родителя чтобы это как-то укладывалось в общепринятый подход, раз уж такие дела

ни одной ссылки по делу, ни одной! хоть бы ссылку на главу бесплатной "thinking in с++" про главу с декомпозицией
весь трындёж про то, что мол в реальном мире помидор не говорит менеджеру и про заказчиков с требованиями

Xenia, спасибо! sm.gif


упд
ладно мужики, всем спасибо чесслово, дальше продолжать вряд ли стоит, пока фсб за мной не выехало sm.gif
видимо надо подучить плюсы или питон, с сишным и ядерным бекграундом я в этой теме много не наловлю
_Pasha
Цитата(Idle @ Aug 17 2012, 22:44) *
я пришёл сюда и спрашиваю - как достучаться до родителя родителя чтобы это как-то укладывалось в общепринятый подход, раз уж такие дела

Через вызов виртуального метода объекта, уже ж говорили.
Родитель смотрит, что это не ему, вызывает унаследованный метод. Про VMT , пример kobject и проч. поговорили. Других вариантов не видно. Аминь.
Idle
Цитата(_Pasha @ Aug 17 2012, 23:55) *
Аминь.

ок, "богородица, менеджера палеты прогони!" maniac.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.