реклама на сайте
подробности

 
 
4 страниц V  < 1 2 3 4 >  
Reply to this topicStart new topic
> си, паттерны ооп, разбиение на объекты, parent's parent, детско-родительские отношения
Idle
сообщение Aug 16 2012, 10:15
Сообщение #16


Местный
***

Группа: Участник
Сообщений: 351
Регистрация: 5-04-05
Пользователь №: 3 874



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

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

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

Сообщение отредактировал Idle - Aug 16 2012, 10:16
Go to the top of the page
 
+Quote Post
Xenia
сообщение Aug 16 2012, 10:49
Сообщение #17


Гуру
******

Группа: Модератор FTP
Сообщений: 4 479
Регистрация: 20-02-08
Из: Москва
Пользователь №: 35 237



Цитата(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
Go to the top of the page
 
+Quote Post
AlexandrY
сообщение Aug 16 2012, 10:54
Сообщение #18


Ally
******

Группа: Модераторы
Сообщений: 6 232
Регистрация: 19-01-05
Пользователь №: 2 050



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


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


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

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


Кстати, так оно физически (на бинарном уровне) в объектных языках и делается.
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Aug 16 2012, 11:29
Сообщение #19


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(Xenia @ Aug 16 2012, 13:49) *
например, таких как MFC или VCL.

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

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

У Вас же всё равно tdd подчинено требованиям более верхнего уровня?
Go to the top of the page
 
+Quote Post
Idle
сообщение Aug 16 2012, 11:41
Сообщение #20


Местный
***

Группа: Участник
Сообщений: 351
Регистрация: 5-04-05
Пользователь №: 3 874



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

не подчинено, иногда в описании явно прописаны контейнеры различного добра, понятно что это отдельный модуль
на сишные модули я выделяю сам, тесты тоже сам придумываю для них
Go to the top of the page
 
+Quote Post
kolobok0
сообщение Aug 16 2012, 14:33
Сообщение #21


практикующий тех. волшебник
*****

Группа: Участник
Сообщений: 1 190
Регистрация: 9-09-05
Пользователь №: 8 417



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


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

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

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

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

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

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

Сообщение отредактировал kolobok0 - Aug 16 2012, 14:37
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Aug 16 2012, 14:46
Сообщение #22


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



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

Сообщение отредактировал _Pasha - Aug 16 2012, 14:48
Go to the top of the page
 
+Quote Post
Idle
сообщение Aug 16 2012, 15:02
Сообщение #23


Местный
***

Группа: Участник
Сообщений: 351
Регистрация: 5-04-05
Пользователь №: 3 874



Цитата(kolobok0 @ Aug 16 2012, 18:33) *
И в каком городе есть супер-пупер чудо помидоры которые орут хозяину что они протухли? Либо вы чего то утаили.

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

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

одна книжка точно есть "Object-oriented programming with ANSI C"

Сообщение отредактировал Idle - Aug 16 2012, 14:56
Go to the top of the page
 
+Quote Post
kolobok0
сообщение Aug 16 2012, 15:11
Сообщение #24


практикующий тех. волшебник
*****

Группа: Участник
Сообщений: 1 190
Регистрация: 9-09-05
Пользователь №: 8 417



Цитата(Idle @ Aug 16 2012, 18:56) *
...есть сетевые потоки, пакеты, таймауты, записи в таблицах, хранилища пакетов одного вида, другого вида, третьего, перетасовка их...не я разбиваю систему на функциональные блоки...


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

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

тут уже прозвучало о супер классе (в плюсах это закос через статик методы). пойдём в эту сторону.
одно из решений...(подчеркну слово одно из)
мысль следующая...
у вас есть типизация сущности. у вас есть типизация события(я так понимаю вы работаете в "событийных рамках" задачи). вам никто не запрещает создавать понятие коллекций по типам сущностей. При этом набор ивентов ограничен. Вам никто не мешает "подписаться" на конкретное событие конкретного типа сущности в любом месте логики... на плюсах это просто. на сях как лучше - тут немного подумать нуна.
Go to the top of the page
 
+Quote Post
Idle
сообщение Aug 16 2012, 18:26
Сообщение #25


Местный
***

Группа: Участник
Сообщений: 351
Регистрация: 5-04-05
Пользователь №: 3 874



Цитата(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_ить метод
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Aug 17 2012, 04:28
Сообщение #26


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(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

Сообщение отредактировал _Pasha - Aug 17 2012, 05:06
Go to the top of the page
 
+Quote Post
andrewlekar
сообщение Aug 17 2012, 04:57
Сообщение #27


Знающий
****

Группа: Участник
Сообщений: 837
Регистрация: 8-02-07
Пользователь №: 25 163



Хотите сделать хорошо - делайте проще. Заведите список для палетт, в нём указатели на списки для ящиков, в них указатели на списки для помидоров. Помидоры - тупо структуры и делать ничё не умеют.
Go to the top of the page
 
+Quote Post
ReAl
сообщение Aug 17 2012, 06:39
Сообщение #28


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



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


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


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
andrewlekar
сообщение Aug 17 2012, 09:04
Сообщение #29


Знающий
****

Группа: Участник
Сообщений: 837
Регистрация: 8-02-07
Пользователь №: 25 163



Цитата
Если они помидоры. А если банки с помидорами, то очень даже ничего бахнуть могут. Поэтому надо таки идти от задачи, не всегда попытка объяснить через простые аналогии заводит куда надо.

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

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

1. pomidor.setManager(pomidorManager)
2. pomidor.onActionEvent = pomidorManager.actionEventHandler
Go to the top of the page
 
+Quote Post
Idle
сообщение Aug 17 2012, 09:48
Сообщение #30


Местный
***

Группа: Участник
Сообщений: 351
Регистрация: 5-04-05
Пользователь №: 3 874



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

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

Сообщение отредактировал Idle - Aug 17 2012, 09:49
Go to the top of the page
 
+Quote Post

4 страниц V  < 1 2 3 4 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 19th July 2025 - 20:10
Рейтинг@Mail.ru


Страница сгенерированна за 0.01437 секунд с 7
ELECTRONIX ©2004-2016