powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Циклическая зависимость классов
16 сообщений из 16, страница 1 из 1
Циклическая зависимость классов
    #39732374
fckr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Как лучше решить проблему циклических зависимостей классов? Например, есть многопользовательская игра. Такие классы:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
TPlayer = class
    units: TArray<TUnit>;
    color: cardinal;
    ...
end;

TUnit = class
    owner: TPlayer;
    ..,
end;



Разумеется, оба класса записаны в разных модулях. При выводе изображения объект класса TUnit обращается к объекту TPlayer для получения цвета игрока (имени или любого другого параметра, относящегося непосредственно к игроку). Это создает циклическую зависимость: в разделе uses одного модуля вызывается другой, и наоборот.

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

В моем примере выше, дублировать поле "color" (и любые другие требуемые поля) в классе TUnit было бы неправильно. Каким образом правильно (с точки зрения структуры) разорвать эту циклическую зависимость (либо, просто решить проблему)? Наверняка, многие с этим сталкивались.
...
Рейтинг: 0 / 0
Циклическая зависимость классов
    #39732377
Фотография JayDi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fckrИнтересует именно этот совет: неужели, всегда можно красиво и правильно разорвать эту циклическую зависимость?
Да.
...
Рейтинг: 0 / 0
Циклическая зависимость классов
    #39732397
Фотография Dimonka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fckr,

Ты можешь выделить интерфейсы обоих классов и вынести их в один (третий) юнит, а реализацию интерфейсов и обращение друг к другу через вынесенные интерфейсы в разных юнитах.
...
Рейтинг: 0 / 0
Циклическая зависимость классов
    #39732411
GunSmoker
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Возможно, будет интересно: "Дружественность" в Delphi
...
Рейтинг: 0 / 0
Циклическая зависимость классов
    #39732440
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fckrЕсть, также, совет "изменить структуру программы, потому что ссылка на родителя - плохой
тон". Интересует именно этот совет: неужели, всегда можно красиво и правильно разорвать
эту циклическую зависимость?

Не всегда, но в большинстве случаев это удаётся правильным дизайном иерархии классов и их
взаимодействия. В твоём случае достаточно убрать из TPlayer список его юнитов, поскольку
удобнее иметь один общий список юнитов в игровом мире. Возможно, сгруппированный по
владельцам, которыми могут быть не только игроки, но и NPC, например.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Циклическая зависимость классов
    #39732571
Василий 2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В какой это вселенной ссылка на родителя - плохой тон?

По твоему конкретному случаю: я бы выделил отдельный тип TPlayerProps, которые нужны юниту от плеера.
...
Рейтинг: 0 / 0
Циклическая зависимость классов
    #39732576
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fckr
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
TPlayerAbstract = class
    units: TArray<TUnitAbstract>;
    color: cardinal;
    ...
end;

TUnitAbstract = class
    owner: TPlayerAbstract;
    ..,
end;


Можно вынести эти два класса на абстрактном уровне в свои модули.
В других-же модулях их реализовать с любыми ссылками.
...
Рейтинг: 0 / 0
Циклическая зависимость классов
    #39732895
Valery_B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Эта задача про Корзину с яблоками.
На корзине написано, сколько и каких яблок в ней лежат, а на яблоках - в какой корзине они лежат

DimonkaТы можешь выделить интерфейсы
Да.
Но если далее работать с объектами через интерфейс, то получается, что яблоки всегда ссылаются на корзину, а корзина - на яблоки.
т.е. объекты ссылаются сами на себя и освобождения интерфейса не произойдёт.
Микрософт подумала, и решила эту проблему созданием среды .NET :)

На Delphi можно сделать так:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
  TUnit = class; //Добавить вот эту строчку.

  TPlayer = class
    units: TArray<TUnit>;
    color: cardinal;
   end;

  TUnit = class
    owner: TPlayer;
  end;


Но я бы лучше подумал на сколько это целесообразно.
...
Рейтинг: 0 / 0
Циклическая зависимость классов
    #39732907
Василий 2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Valery_BНа Delphi можно сделать так:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
  TUnit = class; //Добавить вот эту строчку.

  TPlayer = class
    units: TArray<TUnit>;
    color: cardinal;
   end;

  TUnit = class
    owner: TPlayer;
  end;


Но я бы лучше подумал на сколько это целесообразно.
У него трабл в том, что плеер и юнит в разных модулях.
Все же настаиваю на выделении типа свойств плеера. Так юнит будет брать только то, что ему необходимо.
...
Рейтинг: 0 / 0
Циклическая зависимость классов
    #39732939
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fckrЕсть, также, совет "изменить структуру программы, потому что ссылка на родителя - плохой тон". Интересует именно этот совет: неужели, всегда можно красиво и правильно разорвать эту циклическую зависимость?
советчиков полно, а пилить вам
у меня вот другое мнение, пока в языке не реализовали параллельное наследование классов, и не платят за разгребание гемороев я буду писать как проще и работает.

у меня есть два простых совета:
собрать зависимые объекты в один модуль и не париться с глупостями

для автоматизации сделать генерики владетель-владеемый в отдельном модуле и уже от их конкретной специализации наследоваться
...
Рейтинг: 0 / 0
Циклическая зависимость классов
    #39732969
Valery_B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kealon(Ruslan)советчиков полно

kealon(Ruslan)у меня есть два простых совета:

Во, теперь их стало на одного больше )
...
Рейтинг: 0 / 0
Циклическая зависимость классов
    #39732983
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Еще вариант
Код: pascal
1.
2.
3.
4.
TUnit = class
    owner: TPlayer;
    ..,
end;

заменить на

Код: pascal
1.
2.
3.
4.
TUnit = class
    owner: TObject;
    ..,
end;


И где надо делать приведение типов.
...
Рейтинг: 0 / 0
Циклическая зависимость классов
    #39733020
Фотография Квейд
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Valery_BЭта задача про Корзину с яблоками.
На корзине написано, сколько и каких яблок в ней лежат, а на яблоках - в какой корзине они лежат

DimonkaТы можешь выделить интерфейсы
Да.
Но если далее работать с объектами через интерфейс, то получается, что яблоки всегда ссылаются на корзину, а корзина - на яблоки.
т.е. объекты ссылаются сами на себя и освобождения интерфейса не произойдёт.



Код: pascal
1.
[weak]

не предлагать?
...
Рейтинг: 0 / 0
Циклическая зависимость классов
    #39733021
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Квейд,

много народу под ARC пишет? можно вообще забить на такие глупости
...
Рейтинг: 0 / 0
Циклическая зависимость классов
    #39733092
Фотография X-Cite
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Слабость ссылки можно сэмулировать через присвоение
Вместо:
Код: pascal
1.
2.
3.
4.
var
  a, b: IInterface;

a := b;


прописать
Код: pascal
1.
Pointer(a) := Pointer(b);


Важно только понимать кто должен освободиться раньше, а кто позже.
...
Рейтинг: 0 / 0
Циклическая зависимость классов
    #39733104
Фотография Dimonka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Valery_BЭта задача про Корзину с яблоками.
На корзине написано, сколько и каких яблок в ней лежат, а на яблоках - в какой корзине они лежат

DimonkaТы можешь выделить интерфейсы
Да.
Но если далее работать с объектами через интерфейс, то получается, что яблоки всегда ссылаются на корзину, а корзина - на яблоки.
т.е. объекты ссылаются сами на себя и освобождения интерфейса не произойдёт.
Говоря об интерфейсах, я имел обобщённое значение слова интерфейс. Имелось ввиду абстрактное декларирование функций и свойств классов.
...
Рейтинг: 0 / 0
16 сообщений из 16, страница 1 из 1
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Циклическая зависимость классов
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]