-
Здравствуйте, Еще вопрос по проектированию
Допустим у нас есть два объекта А и Б. И есть интерфейс И. Пусть Б реализует И ( Б = class (…, И) ) А классу А нужен посетитель реализующий интерфейс И. Раз он ему нужен, то хорошо бы запросить его при создании: A = class
public
constructor Create(AVisitor: И);
end; Вопрос кто должен передать классу а посетителя. Вариант первый тут все прозрачно: Допустим сам Б инстанцирует А. Тогда MyА := А.Create(Self) Вариант второй, сам вопрос: А что если А и Б синглетоны? Кто и как тогда должен связать А и Б?
-
1. Не обязательно передавать И через конструктор, можно через свойство.
2. Тот, кто обеспечивает "синглтонность". То есть, фабрика класса A или метод A.NewInstance.
-
> 1. Не обязательно передавать И через конструктор, можно > через свойство.
Ну смысл от этого не меняется. Просто будет в 1 варианте: MyА := А.Create
MyA.И := Self Проблемма не исчезает. То есть, фабрика класса A или метод A.NewInstance.А если нет фабрики? Синглетон создается по требованию. или метод A.NewInstance.Хм. Но ведь тогда А будет знать о конкретном Б. Это убьет весь смысл использования посетителя.
-
> Kolan © (27.01.08 11:51) [2]
> Но ведь тогда А будет знать о конкретном Б. Это убьет весь смысл > использования посетителя.
Убъет, но не это. Вы же сами сказали, что Б - синглтон. Вот что убивает смысл конкретного посетителя - его единственность.
-
> Вот что убивает смысл конкретного посетителя его единственность.
Да наверно пример не корректный, синглетон это только А Б не обязательно. Как тогда?
-
А тогда не вижу проблемы. Тот, кто запрашивает А, должен знать посетителя И и в запросе передать ссылку на него. Если это первый запрос А, то произойдет реальное создание А и инициализация его поля (ссылки на И), а если не первый - произойдет переключение А на другого посетителя.
-
> А тогда не вижу проблемы. Тот, кто запрашивает А, должен > знать посетителя
Ан нет
Ток кто запрашивает А не знает (в некоторых случиях) о том, что а нужен посетитель. Вызывающий А говорит ему: А.ДелайСвоюРаботу. И все, а то что для выполнения работы А нужно еще что-то он может незнать. Единственный вариант, который у меня есть это использование класса, который как-бы инициализирует систему. Он то и назначит нужные посетители
Только не очень мне нравится это вариант.
-
> Kolan © (27.01.08 12:37) [6]
> А.ДелайСвоюРаботу.
И тогда A либо использует своего текущего посетителя, либо запрашивает еще кого-то (менеджера, очередь посетителей и т.п.) - "дай мне посетителя".
Вообще, для более предметного разговора надо бы лучше знать задачу. Судя по слову "посетитель" и по тому, что А - синглтон, моделируется что-то вроде процесса обслуживания посететелей одним продавцом. Тогда уместно ввести именно очередь посетителей - она и будет тем менеджером, который назначает продавцу текущего посетителя.
-
> И тогда A либо использует своего текущего посетителя
Так откуда он его возмет этого текущего?
> Судя по слову «посетитель»
Под словом посетитель подразумевается Visitor из GoF.
-
> Kolan © (27.01.08 13:07) [8]
Значит, нужен менеджер посетителей.
-
> Значит, нужен менеджер посетителей.
Это решение и используется
может еще че-нить можно придумать
?
-
> Kolan © (27.01.08 13:26) [10]
Наверное, можно. Но зачем? Просто так, из любви к искусству, или существующее решение чем-то устраивает? Если второе, то чем?
-
> может еще че-нить можно придумать…?
Может. Рассказать задачу и не мудрствовать сверх необходимости.
Многие переболели паттернами, универсализацией, повторным использованием кода и так далее. У кого-то выработался стойкий иммунитет:)
-
> У кого-то выработался стойкий иммунитет:)
Вырабатываю его у себя :).
> Может. Рассказать задачу и не мудрствовать сверх необходимости.
Задачи нет. Есть проблемма.
Так и есть синглетон А, которому для работы нуже кто-то поддерживающий интерфейс. Сейчас я ему этого кого-то даю при старте приложения. То есть у меня есть StartUpConterller, ктороый знает о А, о Б и о интерфейсе.
А проблемма в том, что мне ненравится такой метод связывания.
-
> Задачи нет. Есть проблемма.
Любую проблему можно решить. Причем несколькими способами.
Но возникает другая проблема - какой из способов выбрать?
-
> Причем несколькими способами.
Ну какими? Я вижу только вариант с внешнем классом
ненравится он тем, что этот класс нужен только для связи и не для чего больше
-
> Kolan © (27.01.08 15:48) [13]
> А проблемма в том, что мне ненравится такой метод связывания.
Не нравится на уровне эстетики вообще, или не нравится чем-то конкретным?
Если первое, то никакой проблемы на самом деле нет, она высосана из пальца. А если второе, то начинать надо с точной формулировки того, "чем конкретно мне это решение не нравится". Это будет уже половина решения.
-
> Kolan © (27.01.08 16:15) [15]
Я честно говоря не могу понять, что у тебя за задача и почему посетителю нужно реализовывать интерфейс. Ты ничего не напутал?
Опиши словестно задачу. И чего ты хочешь добиться в итоге. А то я честно не могу понять задачи.
-
> с точной формулировки
Постараюсь уточнить
При использовании посетителя получается что у нас еть два слоя, разделенных интерфейсом: А — И — Б Дупустим что таких слоев не да, а хотябы три: А — И1 — Б — И2 — С. В этом случае если использовать менеджер, то он будет знать о всех. То есть он все эти слои нарушает
А-И1-Б-И2-С.
\ | /
Manager
-
> Kolan © (27.01.08 16:25) [18]
О каких слоях идет речь?
-
> О каких слоях идет речь?
Тебе определение надо? Или пример? Нахрен мне это надо: Пусть в архитектуре А — И1 — Б — И2 — С. 1. «C» реализует низкоуровневый протокол работы с устройством. И2 примерно такой: procedure Send(Arr: array of Byte); А разные С могут послать байты поразному в зав от протокола
2. «Б» глубоко наплевать как надо слать байты, это высокоуровневый протокол. «И» примерно такие команды содержит: procedure WriteFlashPage ит.д. Но «Б» тоже может быть несколько. Интерфейс 1, а потроха разные. 3. «А» это интерфейс пользователя. Ему тоже пофигу как там будет «Б» извращаться. ЗЫ А надо мне все это из-за того, что у меня есть 3 разных устройства. Разные протоколы «С». Немного отличающиеся «Б» и обсалютно одинаковый UI, то етсь А.
-
Так вот я это понимаю как слои. А шас мне придется сделать менеджера, который всю эту конитель слоёную как копьем пробьет сверху донизу
-
> Kolan © (27.01.08 16:36) [20]
А посетитель здесь причем?
1. Кто несет ответственность за инстанцирование C и B.
Если за инстанцирование C и работу с С несет ответственность B, тогда A вообще ничего не надо знать о контракте между B и С.
А если ответственность за инстанцирование С несет и А, тогда ему нужен контракт С по инстанированию. Это может быть например метакласс.
А если А является связующим между работой B,C. Тогда ему нужно знать контракты B и С по работе и инстанцированию в случае этой обязанности.
-
Почему пробет? Менеджер ведь об А ничего не знает.
-
> oxffff © (27.01.08 16:45) [22]
В любой случае контракт это просто набор методов с описанием сигнатур. Например абстрактный класс, интерфейс, делегирующий объект.
-
> Задачи нет. Есть проблемма. > > Так и есть синглетон А, которому для работы нуже кто-то > поддерживающий интерфейс. > Сейчас я ему этого кого-то даю при старте приложения. То > есть у меня есть StartUpConterller, ктороый знает о А, о > Б и о интерфейсе. > > А проблемма в том, что мне ненравится такой метод связывания. >
Ты меня конечно извини, но мне это здорово напоминает посты в конференции для начинающих, когда народ массивы не может отсортировать, файл прочитать и проч. Но их можно понять - у них экзамены там, зачеты, курсовые и прочая жизненно необходимая хрень.
Я к чему - не надо чистой теории, прочитав теорию ты вполне можешь подобрать задачу, которую тебе хотелось бы решить с ее, теории, применением. Вот задачу на форуме вполне помогут решить, тем более, адекватному человеку, коим ты являешься.
А задача "как разруливать классы" без практического применения - это перелив из пустого в порожнее и бессмысленная трата времени. Все книжки про паттерны, рефакторинги и прочее ООП, на мой взгляд, приносят больше пользы тем, кто уже успел набить себе шишек в альтернативных подходах. Как хорошему слесарю микроскоп с микропроцессорным управлением, чтобы ему по гвоздикам удобнее колотить было. От задач надо плясать, хотя бы от выдуманных, а не о критики чистой теории.
-
> А посетитель здесь причем?
Ну потому, что в Б передается И2. Тот кто реализует И2 посетителем зовется.
> Кто несет ответственность за инстанцирование C и B.
Сейчас, в тех проектах, из которых я все составляю. Все это синглетоны.
То есть А инстанцирует(неявно) Б. Б инстанцирует(неявно) С.
В принципе мне ненадо из UI их подменять, но в коде это должно делаться 1 строкой. Вот я и разорвал жесткие связи с пом. интерфейсов.
можно было бы просто поместить в initialization создание синглетонов и назначение нужных посетителей. Но это плохо, так-как я на уровне модулей их свяжу. По идее модули должны получится независимые (А и Б зависят только от объектов предм. области).
-
> Kolan © (27.01.08 16:55) [26] > > А посетитель здесь причем? > > Ну потому, что в Б передается И2. Тот кто реализует И2 — > посетителем зовется.
А я то думал про GOF. это контракт по работе с С.
Зависимый только тот модуль который устанавливает эту связь.
A.create(B.create(c.create))
-
> От задач надо плясать, хотя бы от выдуманных, а не о критики > чистой теории.
Задача вполне реальна. Озвучиваю. Есть 3 вида железок. Чем они отличаются
название железки протокол низкого уровня протокол высокого уровня
программатор байтовый №1 сложный
усилитель текстовый простой
импедансометр байтовый №2 простой
Для них для всех есть софт который умеет с ними работать. Теперь в «усилитель» и «импедансометр» добавили функции аналогичные программатору. Мне надо сделать софт, который их мог бы зашить. То есть UI беру из программы программатора. Логика работы с образами(прошивками) из программатора. А кишки у каждого свои. В результате задача: 1. Встроить ф-ции программирования в «усилитель» и «импедансометр». 2. Модифицировать программатор, чтобы все они использовали 1 и тот же код(чтобы сразу исправления попадали во все проекты). Вот такие дела
-
> Kolan © (27.01.08 17:04) [28]
А что тебе мешает связать A->B, B->С во внешнем для A,B,C модуле? Зависимости между конкретной реализацией A,B,C не будет, если ты вынесишь описание контрактов в общий модуль D либо в три разных модуля без реализации. А связку провести во внешнем модуле для А,B,C,D?
-
> Kolan © (27.01.08 17:04) [28]
Ладно пошел дальше галтельки клеить супермоментом - это конкретная задача с единственным способом решения - НАДО КЛЕИТЬ. :)
-
> А что тебе мешает связать A->B, B->С во внешнем для A,B, > C модуле?
Мешает то, что этот Д обо всех знает и я не уверен что это правильно
-
> Мешает то, что этот Д обо всех знает и я не уверен что это > правильно…
Что есть "правильно" с твоей точки зрения ? Работает - не работает ?
-
> Работает не работает ?
Работать ессно будет.
Правильно = не отхвачу ли я потом каких-либо проблемм или гемороя при добавлении новых функций или изменении чего-нибудь
Не могу понять есть ли тут опасность
-
Kolan © (27.01.08 20:15) [33]
Всегда отхватишь.
За то время, пока живет ветка, уже можно было бы испробовать несколько разных вариантов и уяснить для себя, в чем между ними разница.
-
> несколько разных вариантов
Да вариант только 1 пока внешний объект «связыватель»
Чтое еще?
-
И че тут мудрить? Есть менеджер, который знает все типы железок. Каждый тип железки знает 2 своих протокола. Фабрика протоколов знает, какой протокол каким классом реализован.
UI запрашивает у менеджера список железок и выводит их, например, в комбобокс. Юзер выбирает тип железки, UI передает его менеджеру, менеджер запрашивает выбранную железку, та запрашивает фабрику (передавая ей свои протоколы). Далее, по обратной цепочке, UI получает 2 интерфейса и через них с железкой работает.
UI знает менеджера. Менеджер знает железки. Каждая железка знает свои протоколы. Фабрика знает реализующие классы. Конкретную реализацию знают только сами эти классы.
Ничего "насквозь не пронизывается". Зато, при необходимости, все легко видоизменяется и наращивается.
-
> [36] Семеныч (27.01.08 20:33)
Читаю
-
> Kolan © (27.01.08 20:35) [37]
Дополнение - и неплохо бы, чтобы в секциях initialization каждая железка регистрировалась в менеджере, а каждый реализатор протокола - в фабрике.
-
> Kolan © (27.01.08 20:03) [31] > > А что тебе мешает связать A->B, B->С во внешнем для A, > B, > > C модуле? > > Мешает то, что этот Д обо всех знает и я не уверен что это > правильно…
D знает только о контрактах, а именно о И1 и И2. Конкретная реализация в A, B и С.
Ежели не нравиться такой вариант, я озвучил также и другой.
>ты вынесишь описание контрактов в общий модуль D либо в три разных модуля без реализации.
Контракты И1 и И2 описаны в D1 и D2 и таким образом знание клиента есть о нужном контракте.
|