Напрмер, есть у меня объект "Фирма", он содержит объект "Отдел", а "Отдел" в свою очередь содержит объект "Сотрудник".
К объекту "Сотрудник" можно обратиться так:
Фирма.Отдел.Сотрудник
А теперь я хочу, чтобы для "Сотрудника" можно было узнать в каком "Отделе" на какой "Фирме" он работает, например:
лФирма = Сотрудник.Отдел.Фирма
Если попробовать это реализовать следующим образом:
public class Т_Фирма
{
public Отдел;
public Т_Фирма()
{
Отдел = new Т_Отдел();
Отдел.Фирма = this;
}
}
public class Т_Отдел
{
public Фирма;
public Сотрудник;
public Т_Отдел()
{
Сотрудник = new Т_Сотрудник();
Сотрудник.Отдел = this;
}
}
public class Т_Сотрудник
{
public Отдел;
public Т_Сотрудник()
{
}
}
То естественно будут циклические ссылки и объект "Фирма" никогда не удалится из памяти:
лФирма = new Т_Фирма;
.....
лФирма = 0;
Что говорит теория на этот счет? как правильно реализовать такие связи между объектами?
Re: Как правильно реализовать иерархическую структуру объект
Как альтернативный вариант, можно реализовывать предопределенный интерфейс объектами, учавствующими в циклических зависимостях и явно отпускать объекты. Например:
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]: Как правильно реализовать иерархическую структуру объ
Насчет первого варианта — это хорошо, что есть такой класс WeakReference, а если его нет?
Насчет второго варианта, не совсем понял как его использовать . Можно привести пример?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re: Как правильно реализовать иерархическую структуру объект
Здравствуйте, 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]: Как правильно реализовать иерархическую структуру объ
Идея про ID понятна, так действительно очень часто делается.
Но мне нужно реализовать именно иерархию, объекты "Фирма-Отдел-Сотрудник" я привел только для примера. Так сказать теоретический пример. В реальности я написал несколько программ где есть родительский и вложенный объекты, и всегда приходилось что-то придумывать как удалять такие объекты из памяти.
Вот я и хотел услышать как другие выходят из этой ситуации, и как это делается в профессиональных приложениях
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[2]: Как правильно реализовать иерархическую структуру объ
Здравствуйте, Lloyd, Вы писали:
L>Здравствуйте, pt4h, Вы писали:
P>>В .NET и Java можно вопспользоваться слабыми ссылками.
L>В .NET и Java для данного случая необходимости пользоваться слабыми ссылками нет.
Почему же нет? Если речь идет о большом количестве объектов в памяти, то лучше хранить, скажем ID рядом со слабой ссылкой и при необходимости подгружать объекты...
Re[4]: Как правильно реализовать иерархическую структуру объ
Здравствуйте, pt4h, Вы писали:
P>Почему же нет? Если речь идет о большом количестве объектов в памяти, то лучше хранить, скажем ID рядом со слабой ссылкой и при необходимости подгружать объекты...
А не основании чего вы сделали вывод, что кол-во объектов будет большим. В исходном посте никакого намека на это я не увидел.
Re[3]: Как правильно реализовать иерархическую структуру объ
Здравствуйте, Lloyd, Вы писали:
L>Здравствуйте, pt4h, Вы писали:
P>>Почему же нет? Если речь идет о большом количестве объектов в памяти, то лучше хранить, скажем ID рядом со слабой ссылкой и при необходимости подгружать объекты...
L>А не основании чего вы сделали вывод, что кол-во объектов будет большим. В исходном посте никакого намека на это я не увидел.
Прямого текста о большом количестве объектов действительно нет, вы правы. Однако, если бы автору исходного сообщения не важно было бы количество объектов и объем используемой ими памяти, то зачем ему беспокоиться о сборке объектов? То есть, я скорее сделал предположение относительно количества объектов... Возможно я и не прав на этот счет.
Re[5]: Как правильно реализовать иерархическую структуру объ
Здравствуйте, Lloyd, Вы писали:
L>А не основании чего вы сделали вывод, что кол-во объектов будет большим. В исходном посте никакого намека на это я не увидел.
Я это решил на основании исходной задачи и примерной статистики взятой с потолка (компания где я работаю например). Возможно не до пятого знака точность, но примерный порядок и перспективу увеличения оценить можно.
Re[4]: Как правильно реализовать иерархическую структуру объ
Здравствуйте, es3000, Вы писали:
L>>В .NET и Java для данного случая необходимости пользоваться слабыми ссылками нет.
E>А какое вы предлагаете решение?
Поскольку в .NET и Java проблемы циклических ссылок нет, то решать ее на этих платформах нет необходимости.
Re[6]: Как правильно реализовать иерархическую структуру объ
Здравствуйте, ika, Вы писали:
ika>Здравствуйте, Lloyd, Вы писали:
L>>А не основании чего вы сделали вывод, что кол-во объектов будет большим. В исходном посте никакого намека на это я не увидел.
ika>Я это решил на основании исходной задачи и примерной статистики взятой с потолка (компания где я работаю например). Возможно не до пятого знака точность, но примерный порядок и перспективу увеличения оценить можно.
А ты-то тут причем?
Re[5]: Как правильно реализовать иерархическую структуру объ
На данный момент количество объектов не важно.
Просто я при входе в программу создаю объект, примерно такой как привел в примере, а при выходе обнаруживаю, что он не удаляется из памяти. Проблема понятно в чем — циклические ссылки.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[6]: Как правильно реализовать иерархическую структуру объ
Здравствуйте, pt4h, Вы писали:
L>>А не основании чего вы сделали вывод, что кол-во объектов будет большим. В исходном посте никакого намека на это я не увидел.
P>Прямого текста о большом количестве объектов действительно нет, вы правы. Однако, если бы автору исходного сообщения не важно было бы количество объектов и объем используемой ими памяти, то зачем ему беспокоиться о сборке объектов? То есть, я скорее сделал предположение относительно количества объектов... Возможно я и не прав на этот счет.
Неверное рассуждение. Автор исходил из предпосылки, что "зацикленные" ссылки есть проблема. Ты эту проблему попытался решить. Но решать эту проблему необходимости не было, в силу того, что проблемы в реальности не существует (сборщик мусора прекрасно справляется с циклическими ссылками).
Re[6]: Как правильно реализовать иерархическую структуру объ
Здравствуйте, es3000, Вы писали:
E>На данный момент количество объектов не важно. E>Просто я при входе в программу создаю объект, примерно такой как привел в примере, а при выходе обнаруживаю, что он не удаляется из памяти. Проблема понятно в чем — циклические ссылки.
Ты ошибаешься. Если ты пишешь на .net или java, то проблема не в этом.
Re[5]: Как правильно реализовать иерархическую структуру объ
L>Поскольку в .NET и Java проблемы циклических ссылок нет, то решать ее на этих платформах нет необходимости.
Ну-у-у, это как-то несерьезно
Я же написал на форум "Архитектура ПО", а не на форум "Коллеги улыбнитесь"
Поэтому хочется что-то по делу услышать, ну а потом можно и посмеяться
А то как-то несмешно пока программа не работает
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re: Как правильно реализовать иерархическую структуру объект
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]: Как правильно реализовать иерархическую структуру объ
Здравствуйте, es3000, Вы писали:
E>Ну-у-у, это как-то несерьезно E>Я же написал на форум "Архитектура ПО", а не на форум "Коллеги улыбнитесь" E>Поэтому хочется что-то по делу услышать, ну а потом можно и посмеяться E>А то как-то несмешно пока программа не работает
А так сойдет?
Поскольку в .NET и Java проблемы циклических ссылок нет, то решать ее на этих платформах нет необходимости.
Re[6]: Как правильно реализовать иерархическую структуру объ
E>Просто я при входе в программу создаю объект, примерно такой как привел в примере, а при выходе обнаруживаю, что он не удаляется из памяти. Проблема понятно в чем — циклические ссылки.
А как ты определяеш удалился он из памяти или нет?