Как правильно реализовать иерархическую структуру объектов?
От: es3000  
Дата: 14.08.06 08:58
Оценка:
Напрмер, есть у меня объект "Фирма", он содержит объект "Отдел", а "Отдел" в свою очередь содержит объект "Сотрудник".
К объекту "Сотрудник" можно обратиться так:
Фирма.Отдел.Сотрудник
А теперь я хочу, чтобы для "Сотрудника" можно было узнать в каком "Отделе" на какой "Фирме" он работает, например:
лФирма = Сотрудник.Отдел.Фирма
Если попробовать это реализовать следующим образом:

public class Т_Фирма
{
    public Отдел;

    public Т_Фирма()
    {
        Отдел = new Т_Отдел();
        Отдел.Фирма = this;
    }
}

public class Т_Отдел
{
    public Фирма;
    public Сотрудник;

    public Т_Отдел()
    {
        Сотрудник = new Т_Сотрудник();
        Сотрудник.Отдел = this;
    }
}

public class Т_Сотрудник
{
    public Отдел;

    public Т_Сотрудник()
    {
    }
}


То естественно будут циклические ссылки и объект "Фирма" никогда не удалится из памяти:

лФирма = new Т_Фирма;
.....
лФирма = 0;


Что говорит теория на этот счет? как правильно реализовать такие связи между объектами?
Re: Как правильно реализовать иерархическую структуру объект
От: pt4h Беларусь http://dzmitryhuba.blogspot.com/
Дата: 14.08.06 09:17
Оценка:
Здравствуйте, es3000, Вы писали:

В .NET и Java можно вопспользоваться слабыми ссылками.

Пример здесь.

Как альтернативный вариант, можно реализовывать предопределенный интерфейс объектами, учавствующими в циклических зависимостях и явно отпускать объекты. Например:

public interface ICyclicDependencyRoot
{
    void Release();
}

public class CyclicDependencyRoot : ICyclicDependencyRoot
{
    private CyclicDependencyRoot reference1;
    private CyclicDependencyRoot reference2;
    
    public void Release()
    {
        this.reference1 = null;
        this.reference2 = null;
    }
}
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[2]: Как правильно реализовать иерархическую структуру объ
От: es3000  
Дата: 14.08.06 10:27
Оценка:
Здравствуйте, pt4h, Вы писали:

Насчет первого варианта — это хорошо, что есть такой класс WeakReference, а если его нет?
Насчет второго варианта, не совсем понял как его использовать . Можно привести пример?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re: Как правильно реализовать иерархическую структуру объект
От: ika Беларусь  
Дата: 14.08.06 10:36
Оценка: 3 (1)
Здравствуйте, es3000, Вы писали:

E>Напрмер, есть у меня объект "Фирма", он содержит объект "Отдел", а "Отдел" в свою очередь содержит объект "Сотрудник".

E>К объекту "Сотрудник" можно обратиться так:
E> Фирма.Отдел.Сотрудник
E>А теперь я хочу, чтобы для "Сотрудника" можно было узнать в каком "Отделе" на какой "Фирме" он работает, например:
E> лФирма = Сотрудник.Отдел.Фирма
[skipped]
E>Что говорит теория на этот счет? как правильно реализовать такие связи между объектами?

Все IMHO.

Я думаю, что потенциально количество отделов в фирмах гораздо меньше чем количество фирм, количество сотрудников — меньше чем количество отделов. Так? Отсюда => если располагать загруженными в память структурами вида Фирма ( Отдел* (Сотрудник*)), то это похоже на подгрузку в память всей базы данных. Подозреваю, что общая производительность такой системы будет невысока именно из-за большого потребления памяти и обработки объектов в _памяти_ (вместо быстрых sql-запросов например). Пример — нужно показать на экране список фирм г. Москвы. Если делать как описано выше, то нужно пройти в программе по циклу все объекты в памяти и отобрать из них только те, у которых поле City = 'Moscow'. Альтернатива — sql запрос Select CompanyName, ... from Company where City='...' — и отработает гораздо быстрей, и не будет столь ресурсоемким. Суть — если данные можно хранить в базе, которая к тому же предоставляет возможность эффективно ими манипулировать, — пусть так и будет. Не вижу большого смысла брать на себя работу базы и зазря заполнять память дублирующимися данными.

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

Теперь два слова насчет обратной зависимости. Подчиненный объект вполне может включать ссылку на родительские(ие), т.к. даже если их несколько, то немного (нужно все равно проанализировать требования и посмотреть так ли это). Так что по большому счету здесь все ок. Но мне кажется, что включать родительский объект целиком в подчиненный — расточительно. Потому что не факт, что это кому-то потребуется, но из базы то он загружается каждый раз вместе с каждым своим дитем! Пример — 100 сотрудников работают в 1 фирме. Объект фирмы будет загружен для каждого сотрудника. А если от сотрудников нужно посмотреть только фамилии, то сколько лишней работы! Реально тут хватило бы только ID родителя. А если надо — догрузи по нему весь объект и делай с ним что надо.

PS: я предполагаю, что в системе есть некий общий севис для централизованного доступа к объектам, зная их тип (фирма, отдел, сотрудник,...) и ID в базе.
Re[2]: Как правильно реализовать иерархическую структуру объ
От: es3000  
Дата: 14.08.06 10:45
Оценка:
Идея про ID понятна, так действительно очень часто делается.
Но мне нужно реализовать именно иерархию, объекты "Фирма-Отдел-Сотрудник" я привел только для примера. Так сказать теоретический пример. В реальности я написал несколько программ где есть родительский и вложенный объекты, и всегда приходилось что-то придумывать как удалять такие объекты из памяти.
Вот я и хотел услышать как другие выходят из этой ситуации, и как это делается в профессиональных приложениях
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[2]: Как правильно реализовать иерархическую структуру объ
От: Lloyd Россия  
Дата: 14.08.06 10:47
Оценка:
Здравствуйте, pt4h, Вы писали:

P>В .NET и Java можно вопспользоваться слабыми ссылками.


В .NET и Java для данного случая необходимости пользоваться слабыми ссылками нет.
Re[3]: Как правильно реализовать иерархическую структуру объ
От: pt4h Беларусь http://dzmitryhuba.blogspot.com/
Дата: 14.08.06 10:58
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>Здравствуйте, pt4h, Вы писали:


P>>В .NET и Java можно вопспользоваться слабыми ссылками.


L>В .NET и Java для данного случая необходимости пользоваться слабыми ссылками нет.


Почему же нет? Если речь идет о большом количестве объектов в памяти, то лучше хранить, скажем ID рядом со слабой ссылкой и при необходимости подгружать объекты...
Re[4]: Как правильно реализовать иерархическую структуру объ
От: Lloyd Россия  
Дата: 14.08.06 11:01
Оценка:
Здравствуйте, pt4h, Вы писали:

P>Почему же нет? Если речь идет о большом количестве объектов в памяти, то лучше хранить, скажем ID рядом со слабой ссылкой и при необходимости подгружать объекты...


А не основании чего вы сделали вывод, что кол-во объектов будет большим. В исходном посте никакого намека на это я не увидел.
Re[3]: Как правильно реализовать иерархическую структуру объ
От: es3000  
Дата: 14.08.06 11:05
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>В .NET и Java для данного случая необходимости пользоваться слабыми ссылками нет.


А какое вы предлагаете решение?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[5]: Как правильно реализовать иерархическую структуру объ
От: pt4h Беларусь http://dzmitryhuba.blogspot.com/
Дата: 14.08.06 11:08
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>Здравствуйте, pt4h, Вы писали:


P>>Почему же нет? Если речь идет о большом количестве объектов в памяти, то лучше хранить, скажем ID рядом со слабой ссылкой и при необходимости подгружать объекты...


L>А не основании чего вы сделали вывод, что кол-во объектов будет большим. В исходном посте никакого намека на это я не увидел.


Прямого текста о большом количестве объектов действительно нет, вы правы. Однако, если бы автору исходного сообщения не важно было бы количество объектов и объем используемой ими памяти, то зачем ему беспокоиться о сборке объектов? То есть, я скорее сделал предположение относительно количества объектов... Возможно я и не прав на этот счет.
Re[5]: Как правильно реализовать иерархическую структуру объ
От: ika Беларусь  
Дата: 14.08.06 11:10
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>А не основании чего вы сделали вывод, что кол-во объектов будет большим. В исходном посте никакого намека на это я не увидел.


Я это решил на основании исходной задачи и примерной статистики взятой с потолка (компания где я работаю например). Возможно не до пятого знака точность, но примерный порядок и перспективу увеличения оценить можно.
Re[4]: Как правильно реализовать иерархическую структуру объ
От: Lloyd Россия  
Дата: 14.08.06 11:15
Оценка: +1
Здравствуйте, es3000, Вы писали:

L>>В .NET и Java для данного случая необходимости пользоваться слабыми ссылками нет.


E>А какое вы предлагаете решение?


Поскольку в .NET и Java проблемы циклических ссылок нет, то решать ее на этих платформах нет необходимости.
Re[6]: Как правильно реализовать иерархическую структуру объ
От: Lloyd Россия  
Дата: 14.08.06 11:16
Оценка:
Здравствуйте, ika, Вы писали:

ika>Здравствуйте, Lloyd, Вы писали:


L>>А не основании чего вы сделали вывод, что кол-во объектов будет большим. В исходном посте никакого намека на это я не увидел.


ika>Я это решил на основании исходной задачи и примерной статистики взятой с потолка (компания где я работаю например). Возможно не до пятого знака точность, но примерный порядок и перспективу увеличения оценить можно.


А ты-то тут причем?
Re[5]: Как правильно реализовать иерархическую структуру объ
От: es3000  
Дата: 14.08.06 11:19
Оценка:
На данный момент количество объектов не важно.
Просто я при входе в программу создаю объект, примерно такой как привел в примере, а при выходе обнаруживаю, что он не удаляется из памяти. Проблема понятно в чем — циклические ссылки.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[6]: Как правильно реализовать иерархическую структуру объ
От: Lloyd Россия  
Дата: 14.08.06 11:19
Оценка:
Здравствуйте, pt4h, Вы писали:

L>>А не основании чего вы сделали вывод, что кол-во объектов будет большим. В исходном посте никакого намека на это я не увидел.


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


Неверное рассуждение. Автор исходил из предпосылки, что "зацикленные" ссылки есть проблема. Ты эту проблему попытался решить. Но решать эту проблему необходимости не было, в силу того, что проблемы в реальности не существует (сборщик мусора прекрасно справляется с циклическими ссылками).
Re[6]: Как правильно реализовать иерархическую структуру объ
От: Lloyd Россия  
Дата: 14.08.06 11:22
Оценка:
Здравствуйте, es3000, Вы писали:

E>На данный момент количество объектов не важно.

E>Просто я при входе в программу создаю объект, примерно такой как привел в примере, а при выходе обнаруживаю, что он не удаляется из памяти. Проблема понятно в чем — циклические ссылки.

Ты ошибаешься. Если ты пишешь на .net или java, то проблема не в этом.
Re[5]: Как правильно реализовать иерархическую структуру объ
От: es3000  
Дата: 14.08.06 11:23
Оценка:
L>Поскольку в .NET и Java проблемы циклических ссылок нет, то решать ее на этих платформах нет необходимости.

Ну-у-у, это как-то несерьезно
Я же написал на форум "Архитектура ПО", а не на форум "Коллеги улыбнитесь"
Поэтому хочется что-то по делу услышать, ну а потом можно и посмеяться
А то как-то несмешно пока программа не работает
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re: Как правильно реализовать иерархическую структуру объект
От: rsn81 Россия http://rsn81.wordpress.com
Дата: 14.08.06 11:24
Оценка:
Здравствуйте, es3000, Вы писали:

А может просто избавиться от избыточности ссылок?
public class Company {
    public Company() {
        Department department = new Department(this);
    }
}

public class Department {
    public Company company;

    public Department(Company company) {
        this.company = company;
        Worker worker = new Worker(this);
    }
}

public class Worker {
    public Department department;

    public Worker(Department department) {
        this.department = department;
    }
}
... << RSDN@Home 1.2.0 alpha rev. 655>>
Re[6]: Как правильно реализовать иерархическую структуру объ
От: Lloyd Россия  
Дата: 14.08.06 11:26
Оценка:
Здравствуйте, es3000, Вы писали:

E>Ну-у-у, это как-то несерьезно

E>Я же написал на форум "Архитектура ПО", а не на форум "Коллеги улыбнитесь"
E>Поэтому хочется что-то по делу услышать, ну а потом можно и посмеяться
E>А то как-то несмешно пока программа не работает

А так сойдет?

Поскольку в .NET и Java проблемы циклических ссылок нет, то решать ее на этих платформах нет необходимости.

Re[6]: Как правильно реализовать иерархическую структуру объ
От: Andrei N.Sobchuck Украина www.smalltalk.ru
Дата: 14.08.06 11:27
Оценка:
E>Просто я при входе в программу создаю объект, примерно такой как привел в примере, а при выходе обнаруживаю, что он не удаляется из памяти. Проблема понятно в чем — циклические ссылки.

А как ты определяеш удалился он из памяти или нет?
http://www.smalltalk.ru | << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Я ненавижу Hibernate
Автор: Andrei N.Sobchuck
Дата: 08.01.08
!
Re: Как правильно реализовать иерархическую структуру объект
От: GlebZ Россия  
Дата: 14.08.06 11:32
Оценка:
Здравствуйте, es3000, Вы писали:

E>
E>лФирма = new Т_Фирма;
E>.....
E>лФирма = 0;
E>


E>Что говорит теория на этот счет? как правильно реализовать такие связи между объектами?

В Java/Net такой проблемы нет. Там объявляется мусором весь граф объектов незацепленный за root. В COM такое решается подсчетом ссылок именно у "Фирмы". В остальных случаях, зависит от стиля программирования и языка.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[2]: Как правильно реализовать иерархическую структуру объ
От: es3000  
Дата: 14.08.06 11:37
Оценка:
Та это же то же самое что и у меня в примере.
В чем разница?
Если я создам объект Company, он при выходе не освободит память, так как ссылка на него хранится в объекте Department
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re: Как правильно реализовать иерархическую структуру объект
От: es3000  
Дата: 14.08.06 11:37
Оценка:
Вообще я пишу на С++, делаю три компоненты "Фирма", "Отдел" и "Сотрудник"
Поэтому у меня нету никакого сборщика мусора, к сожалению
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[7]: Как правильно реализовать иерархическую структуру объ
От: es3000  
Дата: 14.08.06 11:37
Оценка:
ANS>А как ты определяеш удалился он из памяти или нет?

В деструторе делаю запись в лог-файл. Ни один деструктор не вызывается
Вообще я пишу компоненты на С++
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[7]: Как правильно реализовать иерархическую структуру объ
От: pt4h Беларусь http://dzmitryhuba.blogspot.com/
Дата: 14.08.06 11:38
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>Здравствуйте, pt4h, Вы писали:


L>>>А не основании чего вы сделали вывод, что кол-во объектов будет большим. В исходном посте никакого намека на это я не увидел.


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


L>Неверное рассуждение. Автор исходил из предпосылки, что "зацикленные" ссылки есть проблема. Ты эту проблему попытался решить. Но решать эту проблему необходимости не было, в силу того, что проблемы в реальности не существует (сборщик мусора прекрасно справляется с циклическими ссылками).


Согласен. GC убьет все целиком (если на цикл нет ссылки из корня) или ничего если объекты имеют циклические ссылки...
Re[2]: Как правильно реализовать иерархическую структуру объ
От: es3000  
Дата: 14.08.06 11:42
Оценка:
Здравствуйте, GlebZ, Вы писали:

GZ>В Java/Net такой проблемы нет. Там объявляется мусором весь граф объектов незацепленный за root. В COM такое решается подсчетом ссылок именно у "Фирмы". В остальных случаях, зависит от стиля программирования и языка.


В том-то и проблема "Фирма" и "Отдел" — это СОМ-объекты.
У объекта "Отдел" есть такой метод:

Т_Отдел::SetFirm (IFirm* pFirm)
{
mFirm = pFirm;
mFirm->AddRef();
}

То есть этот метод как раз и увеличивает счетчик ссылок.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[8]: Как правильно реализовать иерархическую структуру объ
От: ika Беларусь  
Дата: 14.08.06 11:50
Оценка:
Здравствуйте, es3000, Вы писали:

ANS>>А как ты определяеш удалился он из памяти или нет?


E>В деструторе делаю запись в лог-файл. Ни один деструктор не вызывается

E>Вообще я пишу компоненты на С++

1.) а деструктор виртуальный? можно вообще код глянуть?
2.) если управление памятью делается вручную, то причем здесь цикличность ссылок и GC ? ты уверен, что сам delete вызываешь нормально, который в свою очередь делитит вложенные объекты?
Re[9]: Как правильно реализовать иерархическую структуру объ
От: es3000  
Дата: 14.08.06 12:03
Оценка:
Здравствуйте, ika, Вы писали:

ika>1.) а деструктор виртуальный? можно вообще код глянуть?

ika>2.) если управление памятью делается вручную, то причем здесь цикличность ссылок и GC ? ты уверен, что сам delete вызываешь нормально, который в свою очередь делитит вложенные объекты?


Код почти весь уже привел
Так выглядит главный модуль программы:

рабФирма = new Т_Фирма
рабФирма.AddRef()
....
рабФирма.ReleaseRef(); // в этом месте проблема
рабФирма = null;

Delete я не вызываю, он должен вызваться в методе ReleaseRef. В общем то и все. Плюс у каждого есть деструктор, который делает только ReleaseRef для вложенного объекта.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[3]: Как правильно реализовать иерархическую структуру объ
От: GlebZ Россия  
Дата: 14.08.06 12:03
Оценка:
Здравствуйте, es3000, Вы писали:

E>То есть этот метод как раз и увеличивает счетчик ссылок.

В данном случае, ссылки от подчиненных объектов должны подсчитываться у объекта "Фирма". Посмотри что такое аггрегация в COM.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[4]: Как правильно реализовать иерархическую структуру объ
От: es3000  
Дата: 14.08.06 12:27
Оценка:
GZ>В данном случае, ссылки от подчиненных объектов должны подсчитываться у объекта "Фирма". Посмотри что такое аггрегация в COM.

Что такое аггрегация знаю, но это мне не подходит
Аггрегация предполагает что я могу получить интерфейс одного СОМ-объекта через аггрегированный объект, и т.д. А мне этого не нужно. Интерфейсы объектов у меня не должны менятся.
Мне просто нужно чтобы один объект имел доступ к другому, а тот в свою очередь к первому.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[5]: Как правильно реализовать иерархическую структуру объ
От: GlebZ Россия  
Дата: 14.08.06 13:07
Оценка:
Здравствуйте, es3000, Вы писали:

GZ>>В данном случае, ссылки от подчиненных объектов должны подсчитываться у объекта "Фирма". Посмотри что такое аггрегация в COM.


E>Что такое аггрегация знаю, но это мне не подходит

E>Аггрегация предполагает что я могу получить интерфейс одного СОМ-объекта через аггрегированный объект, и т.д. А мне этого не нужно. Интерфейсы объектов у меня не должны менятся.
E>Мне просто нужно чтобы один объект имел доступ к другому, а тот в свою очередь к первому.
Аггрегирование также предпологает, что ты перенаправляешь все вызововы методов подсчета ссылок родительскому объекту. А это именно то, что тебе нужно. Тебе нужно всего-лишь воспользоваться этим механизмом в том ракурсе в котором требует задача.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re: Как правильно реализовать иерархическую структуру объект
От: konsoletyper Россия https://github.com/konsoletyper
Дата: 15.08.06 05:51
Оценка:
Здравствуйте, es3000, Вы писали:

E>Напрмер, есть у меня объект "Фирма", он содержит объект "Отдел", а "Отдел" в свою очередь содержит объект "Сотрудник".

E>К объекту "Сотрудник" можно обратиться так:
E> Фирма.Отдел.Сотрудник
E>А теперь я хочу, чтобы для "Сотрудника" можно было узнать в каком "Отделе" на какой "Фирме" он работает, например:
E> лФирма = Сотрудник.Отдел.Фирма
E>Если попробовать это реализовать следующим образом:

[skip]

E>То естественно будут циклические ссылки и объект "Фирма" никогда не удалится из памяти:


А в C++ вообще нет подсчёта ссылок, так что всё надо делать ручками — new/delete. Другое дело, что подсчёт ссылок может быть реализован некоторой библиотекой. Тогда люди совершенно правильно писали, что нужно вести подсчёт ссылок на дочерние объекты. Тогда при выходе за пределы зоны видимости Фирма не будет удалена, пока в ней останутся сотрудники. А Сотрудник у себя в деструкторе должен вычёркивать себя из списка сотрудников Фирмы; для этого Сотрудника можно сделать friend class для Фирмы. Ну и дальше включить фантазию/воображение.
Нужно носить в себе еще хаос, чтобы быть в состоянии родить танцующую звезду.
Re[3]: Как правильно реализовать иерархическую структуру объ
От: Кирилл Лебедев Россия http://askofen.blogspot.com/
Дата: 15.08.06 08:38
Оценка: +1
Здравствуйте, es3000, Вы писали:

E>Но мне нужно реализовать именно иерархию, объекты "Фирма-Отдел-Сотрудник" я привел только для примера. Так сказать теоретический пример. В реальности я написал несколько программ где есть родительский и вложенный объекты, и всегда приходилось что-то придумывать как удалять такие объекты из памяти.


Опишите реальную задачу. Гипотетический пример может исказить суть задачи. Например, относительно иерархии "Фирма-Отдел-Сотрудник" можно сразу сказать, что она неправильна. Ika хорошо обосновал это в своем сообщении. Поэтому непонятно, как дела обстоят с реальной программой. То ли и там допущена та же самая ошибка, то ли задача заключается в другом.
С уважением,
Кирилл Лебедев
Software Design blog — http://askofen.blogspot.ru/
Re[4]: Как правильно реализовать иерархическую структуру объ
От: es3000  
Дата: 15.08.06 11:16
Оценка:
КЛ>Опишите реальную задачу. Гипотетический пример может исказить суть задачи. Например, относительно иерархии "Фирма-Отдел-Сотрудник" можно сразу сказать, что она неправильна. Ika хорошо обосновал это в своем сообщении. Поэтому непонятно, как дела обстоят с реальной программой. То ли и там допущена та же самая ошибка, то ли задача заключается в другом.

Как раз это и есть реальная задача. Почему же вы считаете задачу неправильной?
Ika немного неправильно понял суть задачи. Он пишет:
Пример — 100 сотрудников работают в 1 фирме. Объект фирмы будет загружен для каждого сотрудника. А если от сотрудников нужно посмотреть только фамилии, то сколько лишней работы!
А я не собираюсь грузить для каждого сотрудника отдельный объект фирмы. Этим у меня будет заниматься загрузчик. По первому обращению к фирме он создаст объект "Фирма" и всем остальным объектам будет присваивать этот объект. В результате все отделы и все сотрудники будут ссылаться на одну фирму. Но это мы уходим в сторону реализации загрузки по требованию информации.
Сейчас у меня задача правильно реализовать иерархию. В качестве примера могу привести самую простую иерархию, коорая есть почти во всех языках программировани. Это форма и кнопка, которая содержится в этой форме. Я могу через объект формы к кнопке:
Form.AnyButton

и через объект кнопки к форме:
AnyButton.Parent

Я читал статью по СОМ на предмет циклических ссылок, там предлагается самому реализовать механизм "слабых" ссылок. Но и упоминались и другие подходы, которые почему-то ТОЛЬКО упоминались но не осветились подрбно.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re: Как правильно реализовать иерархическую структуру объект
От: es3000  
Дата: 15.08.06 12:02
Оценка:
Вот как раз попалась статья:
http://users.skynet.be/wvdd2/General_techniques/Cyclic_References/cyclic_references.html
Какие будут мнения?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[5]: Как правильно реализовать иерархическую структуру объ
От: Кирилл Лебедев Россия http://askofen.blogspot.com/
Дата: 15.08.06 13:07
Оценка:
Здравствуйте, es3000, Вы писали:

E>Как раз это и есть реальная задача. Почему же вы считаете задачу неправильной?


Только не задачу, а классификацию. Постараюсь пояснить. Какая польза от того, что Фирма содержит Отделы, а Отдел — Сотрудников? Какую функциональную нагрузку несет такая структура? Я не знаю, чем занимается Фирма. Я не знаю, по какому принципу в ней сформированы Отделы. Я не знаю, как эти Отделы взаимодействуют между собой? Допустим, речь идет о софтверной фирме. В ней отдел маркетинга ставит задачи Отделу Разработки и Отделу Качества. Отдел Разработки и Отдел Качества согласовывает свою работу с Отделом маркетинга, а так же посылает спецификацию в Отдел качества и в Отдел Саппорта. Отдел Саппорта посылает жалобы Клиентов в Отдел Маркетинга и в Отдел Разработки. И т.д. Каким образом Вы собираетесь отобразить взаимодействия между Отделами?

Вот и ответ. Архитектура должна строится, исходя из функциональности.

Еще один пример. Теоретически один Сотрудник может работать в нескольких отделах. Или выполнять разные функции, приписанные разным Отделам. Каким образом Вы собрались отобразить эту ситуацию? Кроме того, Сотрудник может перейти из одного отдела в другой. И т.д. И т.п.
С уважением,
Кирилл Лебедев
Software Design blog — http://askofen.blogspot.ru/
Re[6]: Как правильно реализовать иерархическую структуру объ
От: es3000  
Дата: 17.08.06 04:14
Оценка:
КЛ> Я не знаю, чем занимается Фирма. Я не знаю, по какому принципу в ней сформированы Отделы. Я не знаю, как эти Отделы взаимодействуют между собой?

А зачем вам это знать? Зачем вы копаетесь в ненужных деталях? Есть задача, поставленная заказчиком: сделать программу в которой ведется список фирм, список отделов в каждой фирме, и список работников в отделе. Все. Насчет того может ли один работник сразу числиться в нескольких отделах — я не уточнял.
Но предположим что нет. Давайте просто решим ту задачу, о которой я сказал. Другую задачу мне решать не нужно в данный момент. Если надо будет — тогда и буду что-то менять. В любой программе всегда что-то меняется, все предусмотреть невозможно.
Сейчас меня интересует как все-таки решить проблему циклических ссылок в простой иерархической структуре объектов, которую я привел. Что ж тут поделать, встала такая проблема и решить нужно именно эту проблему, а не придумывать как от нее уйти
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[7]: Как правильно реализовать иерархическую структуру объ
От: ika Беларусь  
Дата: 17.08.06 06:37
Оценка:
Здравствуйте, es3000, Вы писали:
E>Сейчас меня интересует как все-таки решить проблему циклических ссылок в простой иерархической структуре объектов, которую я привел. Что ж тут поделать, встала такая проблема и решить нужно именно эту проблему, а не придумывать как от нее уйти.

У меня закралось подозрение, что, возможно, проблему цикличности решить в полном объеме на c++ не удастся. Возможно, я ошибаюсь. Если только самому не писать надстройку к менеджеру памяти, чтоб он ходил и искал оторванные куски связанных объектов. Либо заворачивать каждый ком-объект в некие прокси, назначение которых — только считать ссылки и говорить результат кому-то выше по первому требованию. Но это едва ли входит в scope прикладной программы.

Основная задача — это освобождение памяти при завершении работы программы? Если так, то достаточно помещать каджый полученный экземпляр com-объекта в какое-то глобальное хранилище, а перед завершением программы вызвать у него очистку — чтобы у всех имеющихся объектов были принудительно вызваны DeleteRef до RefCount==0.
Re[2]: Как правильно реализовать иерархическую структуру объ
От: Нахлобуч Великобритания https://hglabhq.com
Дата: 17.08.06 06:37
Оценка:
Здравствуйте, ika, Вы писали:

ika>Пример — 100 сотрудников работают в 1 фирме. Объект фирмы будет загружен для каждого сотрудника. А если от сотрудников нужно посмотреть только фамилии, то сколько лишней работы! Реально тут хватило бы только ID родителя. А если надо — догрузи по нему весь объект и делай с ним что надо.


Ни в коем случае такого допускать нельзя. И, в основном, не с точки зрения производительности, а потому, что в таком случае отслеживание изменений становится просто таки адски сложной задачей. Пользуясь случаем, хочу передать привет GlebZ, а так же настоятельно рекомендую прочесть про Identity Map.
HgLab: Mercurial Server and Repository Management for Windows
Re[7]: Как правильно реализовать иерархическую структуру объ
От: Кирилл Лебедев Россия http://askofen.blogspot.com/
Дата: 17.08.06 08:33
Оценка: 3 (1) +1
Здравствуйте, es3000, Вы писали:

E>А зачем вам это знать? Зачем вы копаетесь в ненужных деталях? Есть задача, поставленная заказчиком: сделать программу в которой ведется список фирм, список отделов в каждой фирме, и список работников в отделе. Все. Насчет того может ли один работник сразу числиться в нескольких отделах — я не уточнял.


Прежде чем решать задачу, ее нужно сначала грамотно поставить. (Слово "грамотно" — ключевое. В нем есть смысл.) За всю свою 10-летнюю практику разработки и сопровождения программ я пока еще не встречал Заказчика, который бы сам мог бы грамотно поставить задачу. Он специалист в своем деле. И в программировании может (или даже не должен) разбираться. Для этого он и нанимает специалиста, который знает, как ставятся и решаются подобные задачи. За это и платит деньги.

Неверно поставленная задача приводит к неверному решению. Неверное решение порождает массу проблем, которые, как правило, красиво не решаются, а устраняются путем написания "заплаток". Проблема циклических ссылок — из их числа. "Заплатки" постепенно накапливаются, и, в результате, получается тяжелый и несопровождаемый код.

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

Наконец, Вы не учитываете, как и для чего будет использоваться Ваша программа. Между тем, программа пишется не для того, чтобы просто хранить данные, а для того, чтобы с ними работать. При чем работать определенным образом. Каким? Вы выяснили ответ на этот вопрос? Это важно, т.к. способ хранения и представления данных зависит от того, как эти данные будут в дальнейшем использоваться.

E>Сейчас меня интересует как все-таки решить проблему циклических ссылок в простой иерархической структуре объектов, которую я привел. Что ж тут поделать, встала такая проблема и решить нужно именно эту проблему, а не придумывать как от нее уйти


Проблема циклических ссылок решается очень легко. Она просто не создается.

С уважением
и надеясь на понимание,
С уважением,
Кирилл Лебедев
Software Design blog — http://askofen.blogspot.ru/
Re[8]: Как правильно реализовать иерархическую структуру объ
От: ika Беларусь  
Дата: 17.08.06 08:47
Оценка:
Здравствуйте, es3000.

КЛ>Неверно поставленная задача приводит к неверному решению. Неверное решение порождает массу проблем, которые, как правило, красиво не решаются, а устраняются путем написания "заплаток". Проблема циклических ссылок — из их числа. "Заплатки" постепенно накапливаются, и, в результате, получается тяжелый и несопровождаемый код.


В подтверждение слов Кирилла я бы рекомендовал вам пролистать книжку "Жемчужины программирования", хотя бы первае пару глав (http://shop.piter.com/book/978531800715/). Именно это там и написано, когда разбираются неудачные "полеты". Неверное понимание задачи приводит к неверной формальной постановке, а это — к неверным изначальным техническуим предпосылкам, что, в свою очередь, определяет всю архитектуру (структуры данных, алгоритмы, производительность).
Re[8]: Как правильно реализовать иерархическую структуру объ
От: es3000  
Дата: 17.08.06 09:11
Оценка:
ika>У меня закралось подозрение, что, возможно, проблему цикличности решить в полном объеме на c++ не удастся. Возможно, я ошибаюсь. Если только самому не писать надстройку к менеджеру памяти, чтоб он ходил и искал оторванные куски связанных объектов. Либо заворачивать каждый ком-объект в некие прокси, назначение которых — только считать ссылки и говорить результат кому-то выше по первому требованию. Но это едва ли входит в scope прикладной программы.

Спасибо за понимание, наконец-то начали обсуждать задачу
В общем-то идея насчет прокси мне понравилась. Надо это обдумать

Я читал статью по COM где предлагается делать дополнительный объект, который выполняет функции самого объекта. Например:
1) для объекта "Фирма" создать доп.объект "ВнутрФирма"
2) вложить его в объект "Фирма"
3) для объекта "Отдел" установить ссылку на "ВнутрФирма"
Тогда подсчет ссылок будет везде нормальным
Но тогда возникает такая проблема: при обращении Сотрудник.Отдел.Фирма мы получим ссылку не на сам объект "Фирма" , а на его "реализацию" — "ВнутрФирма"

Еще я нашел такую статью:
http://users.skynet.be/wvdd2/General_techniques/Cyclic_References/cyclic_references.html
Только не совсем ее понял


ika>Основная задача — это освобождение памяти при завершении работы программы? Если так, то достаточно помещать каджый полученный экземпляр com-объекта в какое-то глобальное хранилище, а перед завершением программы вызвать у него очистку — чтобы у всех имеющихся объектов были принудительно вызваны DeleteRef до RefCount==0.


Освобождать память хочется не только при завершении, а при каждом освобождении всех "внешних" ссылок на объект. (Если "внешними" назвать ссылки от всех других объектов, кроме вложенных)
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[9]: Как правильно реализовать иерархическую структуру объ
От: ika Беларусь  
Дата: 17.08.06 09:22
Оценка:
Здравствуйте, es3000, Вы писали:

E>1) для объекта "Фирма" создать доп.объект "ВнутрФирма"

E>2) вложить его в объект "Фирма"
E>3) для объекта "Отдел" установить ссылку на "ВнутрФирма"
E>Тогда подсчет ссылок будет везде нормальным

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

E>Еще я нашел такую статью:

E>http://users.skynet.be/wvdd2/General_techniques/Cyclic_References/cyclic_references.html
E>Только не совсем ее понял

Я тоже. IMHO, раздувать каждый геттер проперти в каждом классе затычкой — "не те джунлги" (с). Аргументировать не могу. Только интуитивно чувствую, что нехорошо это — базировать архитектуру на решениях-затычках, позаимствованных из инета да еще и не до конца понятых.
Re: Как правильно реализовать иерархическую структуру объект
От: A.Lokotkov Россия  
Дата: 17.08.06 09:33
Оценка: +2
Здравствуйте, es3000, Вы писали:

E>Напрмер, есть у меня объект "Фирма", он содержит объект "Отдел", а "Отдел" в свою очередь содержит объект "Сотрудник".

E>К объекту "Сотрудник" можно обратиться так:
E> Фирма.Отдел.Сотрудник
E>А теперь я хочу, чтобы для "Сотрудника" можно было узнать в каком "Отделе" на какой "Фирме" он работает, например:
E> лФирма = Сотрудник.Отдел.Фирма

Представьте, что фирма со временем превращается в холдинг, состоящий из нескольких фирм. При этом некий сотрудник неформально числится в холдинге, а по бухгалтерии -- в двух фирмах: в одной он занимается, скажем, разработкой, а в другой -- технической поддержкой. Естественно, ни о какой принадлежности сотрудника какому-либо одному отделу речи быть не может. Кроме того, формально, скажем, директор фирмы тоже является сотрудником, и при этом вряд ли принадлежит какому-либо отделу.

Вы уверены, что Ваша иерархия, непосредственно проистекающая из Вашего текущего представления модели предметной области, может быть приспособлена к таким вещам? Проблемы с зацикливанием ссылок могут потом показаться невинной детской забавой.
bloß it hudla
Re[8]: Как правильно реализовать иерархическую структуру объ
От: es3000  
Дата: 17.08.06 10:29
Оценка:
КЛ>Прежде чем решать задачу, ее нужно сначала грамотно поставить...

Я с вами во всем согласен, я сам всегда отношусь достаточно серьезно к постановке
Но проблема которую я пытаюсь решить не относится к постановке, она относится к реализации. С заказчиком все обговорено, есть понимание того , что нужно от программы.

Возможность обратиться к сотруднику через фирму и к фирме через сотрудника — это чисто внутренняя реализация, можно и не делать такого обращения вовсе, а выполнять например поиск сотрудников для конкретной фирмы и наоборот поиск фирмы для сотрудника по базе данных по идентификатору. Как уже говорили.

Но согласитесь что программу писать было бы намного удобнее, если бы все-таки работал такой механизм: Фирма.Отдел.Сотрудник, Сотрудник.Отдел.Фирма.
Причем этот механизм работает, программа уже написана, программа получилась короткой, хорошо читаемой, ошибок на данный момент нету, и если что-то надо будет поменять — поменять будет легко, так как этот способ взаимодействия объектов никак не влияет на архитектуру всей программы.

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


КЛ>Проблема циклических ссылок решается очень легко. Она просто не создается.

Такая проблема есть, у предлагается много способов ее решения
Посмотрите статью Managing Object Lifetimes in OLE в MSDN
Конечно, там описывается более сложная ситуация, но в принципе очень похожа на мою
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[10]: Как правильно реализовать иерархическую структуру об
От: es3000  
Дата: 17.08.06 10:37
Оценка:
ika>Я тоже. IMHO, раздувать каждый геттер проперти в каждом классе затычкой — "не те джунлги" (с). Аргументировать не могу. Только интуитивно чувствую, что нехорошо это — базировать архитектуру на решениях-затычках, позаимствованных из инета да еще и не до конца понятых.

Согласен,
поэтому я и обратился на форум,
может кто-нибудь что-то придумал более правильное решение
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[2]: Как правильно реализовать иерархическую структуру объ
От: es3000  
Дата: 17.08.06 10:37
Оценка:
AL>Представьте, что фирма со временем превращается в холдинг, состоящий из нескольких фирм. При этом некий сотрудник неформально числится в холдинге, а по бухгалтерии -- в двух фирмах: в одной он занимается, скажем, разработкой, а в другой -- технической поддержкой. Естественно, ни о какой принадлежности сотрудника какому-либо одному отделу речи быть не может. Кроме того, формально, скажем, директор фирмы тоже является сотрудником, и при этом вряд ли принадлежит какому-либо отделу.

AL>Вы уверены, что Ваша иерархия, непосредственно проистекающая из Вашего текущего представления модели предметной области, может быть приспособлена к таким вещам? Проблемы с зацикливанием ссылок могут потом показаться невинной детской забавой.


Ну на похожий вопрос я уже отвечал (посмотрите пожалуйста выше).
Постановка уже есть, сейчас не время ее обсуждать,
сейчас надо решить чисто техническую часть реализации поставленной задачи
Надо попытаться реализовать такую иерархию и все тут,
если не получится — придется реализовать ту же функциональность но по другому
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re: Как правильно реализовать иерархическую структуру объект
От: es3000  
Дата: 17.08.06 11:47
Оценка:
Нашел еще одну статью по проблеме в MSDN:
The COM Programmer's Cookbook
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re: Как правильно реализовать иерархическую структуру объект
От: _doctor Финляндия http://agilesoftwaredevelopment.com
Дата: 17.08.06 20:45
Оценка:
Здравствуйте, es3000, Вы писали:

E>Напрмер, есть у меня объект "Фирма", он содержит объект "Отдел", а "Отдел" в свою очередь содержит объект "Сотрудник".

E>К объекту "Сотрудник" можно обратиться так:
E> Фирма.Отдел.Сотрудник
E>А теперь я хочу, чтобы для "Сотрудника" можно было узнать в каком "Отделе" на какой "Фирме" он работает, например:
E> лФирма = Сотрудник.Отдел.Фирма
E>Если попробовать это реализовать следующим образом:
E>...
E>То естественно будут циклические ссылки и объект "Фирма" никогда не удалится из памяти:

E>Что говорит теория на этот счет? как правильно реализовать такие связи между объектами?


ИМХО, основные трудности у Вас вызывает смешение двух вопросов:
1) Как организовывать общение Отдела и Фирмы ( чтобы было удобно доступаться из Отдела к Фирме и из Фирмы к Отделу)
2) Как хранить (и удалять) Отделы и Фирмы. В частности, чтобы не оставалось зависших ссылок

Попробуйте разделить эти вопросы и решать их по отдельности.

Например,
В целях 1) При создании всей структуры в памяти можно давать ссылку на Фирму конструктору Отдела (либо через метод Отдел::AddФирма), а ссылку на отдел добавлять через Фирма::AddОтдел. Через
В целях 2) можно хранить Отделы и Фирмы совершенно отдельно и реализовать методы вроде Фирма::DeleteItselfИВсеОтделыЕслиОниНеВходятВДругиеФирмы

P.S.
Всё вышесказанное перекликается с уже высказанным в этой ветке
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Chief Software Engineer,
Scrum Master, Symbian
Re[2]: Как правильно реализовать иерархическую структуру объ
От: es3000  
Дата: 18.08.06 04:34
Оценка:
_>В целях 1) При создании всей структуры в памяти можно давать ссылку на Фирму конструктору Отдела (либо через метод Отдел::AddФирма), а ссылку на отдел добавлять через Фирма::AddОтдел. Через
_>В целях 2) можно хранить Отделы и Фирмы совершенно отдельно и реализовать методы вроде Фирма::DeleteItselfИВсеОтделыЕслиОниНеВходятВДругиеФирмы

А в какой момент вызывать метод "Фирма::DeleteItselfИВсеОтделыЕслиОниНеВходятВДругиеФирмы"?
Наличие самого метода не решает проблему. Нужно чтобы он вызвался когда освобождается последняя ссылка на объект. А как это определить? В этом то и суть — что последняя ссылка никогда не освободится, если объекты ссылаются друг на друга.


_>Всё вышесказанное перекликается с уже высказанным в этой ветке


Высказываний то много, только никто не предложил решения
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[3]: Как правильно реализовать иерархическую структуру объ
От: _doctor Финляндия http://agilesoftwaredevelopment.com
Дата: 18.08.06 05:44
Оценка:
Здравствуйте, es3000, Вы писали:

_>>В целях 1) При создании всей структуры в памяти можно давать ссылку на Фирму конструктору Отдела (либо через метод Отдел::AddФирма), а ссылку на отдел добавлять через Фирма::AddОтдел. Через

_>>В целях 2) можно хранить Отделы и Фирмы совершенно отдельно и реализовать методы вроде Фирма::DeleteItselfИВсеОтделыЕслиОниНеВходятВДругиеФирмы

E>А в какой момент вызывать метод "Фирма::DeleteItselfИВсеОтделыЕслиОниНеВходятВДругиеФирмы"?

E>Наличие самого метода не решает проблему. Нужно чтобы он вызвался когда освобождается последняя ссылка на объект. А как это определить? В этом то и суть — что последняя ссылка никогда не освободится, если объекты ссылаются друг на друга.

В C++ понятие "освобождается ссылка" — исключительно логическое и виртуальное
Освобождайте тогда, когда надо освобождать. Например, если объектов немного, то при выходе из программы. Причём, если хранить Фирмы и Отделы в, скажем, разных массивах, то всего-то понадобится поудалять всё из этих массивов.
Кроме того, необязательно именно удалять все Отделы фирмы при удалении фирмы. Очень может быть, что быдет достаточно удалять ссылку на фирму.

В общем, всё зависит от логики хранения.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Chief Software Engineer,
Scrum Master, Symbian
Re[4]: Как правильно реализовать иерархическую структуру объ
От: es3000  
Дата: 18.08.06 06:32
Оценка:
_>В C++ понятие "освобождается ссылка" — исключительно логическое и виртуальное
_>Освобождайте тогда, когда надо освобождать. Например, если объектов немного, то при выходе из программы. Причём, если хранить Фирмы и Отделы в, скажем, разных массивах, то всего-то понадобится поудалять всё из этих массивов.
_>Кроме того, необязательно именно удалять все Отделы фирмы при удалении фирмы. Очень может быть, что быдет достаточно удалять ссылку на фирму.

Да на С++, но работа выполняется с СОМ-объектами, которые сами ведут учет своих ссылок, и сами себя освобождают.
А что значит "Освобождайте тогда, когда надо освобождать"??? Надо освобождать, когда нету ссылок на объект.
Хранить-то эти объекты можно и в массивах только они все равно будут друг на друга ссылаться
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re: Как правильно реализовать иерархическую структуру объект
От: GlebZ Россия  
Дата: 18.08.06 08:57
Оценка:
To all:
Джентельмены. Вам не кажется что не зная полной постановки конкретной задачи вы судите о реализации. Я могу придумать сотню требований, когда идентификация по ссылкам более удовлетворяет задаче, чем идентификация по идентификатору. Каждой постановке, должно быть наиболее подходящее решение, и на основании вышеперечисленных данных, эффективное решение выбрать невозможно.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re: Как правильно реализовать иерархическую структуру объект
От: shev  
Дата: 29.08.06 14:04
Оценка:
Вот как у меня в проекте решается проблема с циклическими ссылками в COM.

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

Все объекты имеют метод Shutdown, в котором объект освобождает все ссылки на другие COM объекты, которые у него имеются.

Так вот, после Commit’a бизнес транзакции объекты не должны использоваться, т.е. они должны быть заново прочитаны. Соответственно после Commit’a UnitOfWork пробегает по ВСЕМ зареганным у него объектам, вызывая метод Shutdown, и затем удаляет все объекты из списка. Все ссылки очищаются, объекты удаляются из памяти… Что и требуется получить! Да и сам UnitOfWork после как правило тоже уничтожается, потому что больше не нужен

Единственное…. пришлось в Set и Get методах у всех сущностей добавить код с проверкой состояния shutdown объекта и генерировать исключение, чтобы случайно не использовать уже «мертвый» объект.
Re: Как правильно реализовать иерархическую структуру объект
От: Beam Россия  
Дата: 29.08.06 17:01
Оценка:
Здравствуйте, es3000, Вы писали:

E>Напрмер, есть у меня объект "Фирма", он содержит объект "Отдел", а "Отдел" в свою очередь содержит объект "Сотрудник".

E>К объекту "Сотрудник" можно обратиться так:
E> Фирма.Отдел.Сотрудник
E>А теперь я хочу, чтобы для "Сотрудника" можно было узнать в каком "Отделе" на какой "Фирме" он работает, например:
E> лФирма = Сотрудник.Отдел.Фирма

E>То естественно будут циклические ссылки и объект "Фирма" никогда не удалится из памяти:


Можно сделать следующее:
— Выкинуть все связи между Фирмой, Отделом и Сотрудником из реализации этих классов
— Управление связями передать сервисному классу
— Для решения задачи дергать соответствующие методы этого сервисного класса
class RelationManager {
  // для решения первой задачи
  найтиОтделПоФирме();
    найтиСотрудникаПоОтделу();
    // для решения второй задачи
    найтиОтделПоСотруднику();
    найтиФирмуПоОтделу();
}

class Отдел {
.....

  Сотрудник(){
    return RelationManager.найтиСотрудникаПоОтделу(this);
  }

.....
}


В этом случае управление связями (и ссылками) будет осуществляться в одном месте, а классы-сущности можно будет безболезненно удалять.
Как развитие данного варианта можно (скорее нужно? ) вообще все запросы осуществлять через сервисный класс (вместо Сотрудник.Отдел.Фирма использовать RelationMAnager.найтиФирмуПоСотруднику), но задача ставилась иначе.

Другие варианты (менее красивые)
— при удалении объекта уведомлять об этом свои внутренние объекты. Так при удалении Фирма вызывает для (каждого) отдела Отдел.обнулитьСвязьСФирмой.
— использовать везде одностороннюю связь, а обратную реализовать через поиск (т.е. связь Фирма.Отдел оставить как есть, а связь Отдел.Фирма удалить и реализовать ее путем поиска — бежи по всем Фирмам, отдел в ней? если ДА — возвращаем результат)
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Best regards, Буравчик
Re[2]: Как правильно реализовать иерархическую структуру объ
От: es3000  
Дата: 07.09.06 08:53
Оценка:
Здравствуйте, shev, Вы писали:

S>Вот как у меня в проекте решается проблема с циклическими ссылками в COM.


S>Все сущности существуют в рамках бизнес транзакции (UnitOfWork). В этом же UnitOfWork реализован IdentityMap, чтобы объекты не грузились заново и просто для хранения списка всех используемых объектов в текущей бизнес транзакции.


S>Все объекты имеют метод Shutdown, в котором объект освобождает все ссылки на другие COM объекты, которые у него имеются.


S>Так вот, после Commit’a бизнес транзакции объекты не должны использоваться, т.е. они должны быть заново прочитаны. Соответственно после Commit’a UnitOfWork пробегает по ВСЕМ зареганным у него объектам, вызывая метод Shutdown, и затем удаляет все объекты из списка. Все ссылки очищаются, объекты удаляются из памяти… Что и требуется получить! Да и сам UnitOfWork после как правило тоже уничтожается, потому что больше не нужен


S>Единственное…. пришлось в Set и Get методах у всех сущностей добавить код с проверкой состояния shutdown объекта и генерировать исключение, чтобы случайно не использовать уже «мертвый» объект.


Спасибо за ответ, а то я уже и не надеялся, что кто-то поможет по делу
Ваш способ решения проблемы интересный, но самое главное это будет работать!
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[2]: Как правильно реализовать иерархическую структуру объ
От: es3000  
Дата: 07.09.06 08:53
Оценка:
Вам тоже большое спасибо за ответ.

Если делать сервисный класс, то он тоже должен хранить ссылки на объекты. Например, в сервисном классе хранится что какому-то объекту "Отдел" соответствует объект "Фирма". Т.е. сервисный класс так же увеличивает счетчики ссылок этих объектов. И "безболезненно удалять классы-сущности" опять не получается.

Допустим моя программа работает с объектом "Фирма", например какая-то функция "РаботаСФирмой" каким-то образом получает этот объект и что-то с ним делает. В программе также будут объекты "МенеджерСвязей" и "Отдел". В результате на объект "Фирма" будет создано две ссылки: из функции и из "МенеджерСвязей". При выходе из функции я освобождаю ссылку на объект "Фирма", но "МенеджерСвязей" еще хранит свою ссылку и объект не освободится.

Правильно?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.