Паттерны. Тестовые задачки.
От: Аноним  
Дата: 20.09.04 13:52
Оценка:
К своему стыду только недавно узнал про Паттерны проектирования. Сейчас читаю всем известную книгу Эриха Гамма, с соавторами про паттерны. Там в качестве практического примера приводится графический редактор Lexi. По мере прочтения хочется самому закреплять на практике прочитанный материал, применяя паттерны на примере не такого относительно большого примера как Lexi, а чего-то в кодировании поменьше объемом, но со всеми сруктурными особенностями. Может быть что-то связанном с вводом/выводом. Не хочется самому придумывать, навереняка уже есть какие-то уже продуманные задачки.
Спасибо.
Re: Паттерны. Тестовые задачки.
От: S.Yu.Gubanov Россия http://sergey-gubanov.livejournal.com/
Дата: 21.09.04 11:34
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Не хочется самому придумывать, навереняка уже есть какие-то уже продуманные задачки.


Задачка — это когда Вам дают что-то решить, а потом показывают правильное решение и сравнивают его с Вашим, так? Да, интересно было бы заиметь подобный задачник с ответами...

Впрочем, попробуйте решить задачу об агрегировании одних объектов другими. Пусть есть пирамида агрегирования. На вершине этой пирамиды находится самый большой агрегат — фабрика (Factory). Фабрика агрегирует несколько разных объектных сред исполнения (runtime system, Environment). Среда исполнения агрегирует в себе (активные) документы (Document). Документы персистентны. Внутри документа есть всякие предметные области (Domain), которые состоят из компонентов (Component), а те в свою очередь состоят из элементарных объектов (Object).
Factory -<- Environment(s) -<- Document(s) -<- Domain(s) -<- Component(s) -<- Object(s)


1) Придумайте способ как, используя GoF-овские паттерны проектирования, можно запрограммировать такую пирамиду агрегации чтобы эту пирамиду можно было "разбирать" сверху вниз не переписывая при этом код нижестоящих агрегатов.

2) Придумайте способ как запрограммировать пирамиду так чтобы можно было вставлять в нее дополнительные слои не переписывая ни строчки кода. Имеется ввиду следующее
Например, было так:
Document -<- Domain

и мы вставили дополнительный слой System
Document -<- System -<- Domain

и при этом нам не надо переписывать код других слоев.

3) Аналогично пункту (2), придумать способ как так запрограммировать пирамиду агрегации, чтобы ее можно было потом разбирать и сверху и снизу и вставляя слои и убирая лишние.
Re[2]: Паттерны. Тестовые задачки.
От: S.Yu.Gubanov Россия http://sergey-gubanov.livejournal.com/
Дата: 21.09.04 11:41
Оценка:
SYG>
SYG>Factory -<- Environment(s) -<- Document(s) -<- Domain(s) -<- Component(s) -<- Object(s)
SYG>


P. S.
Само-собой, подразумевается, что нижележащим агрегатам нужно уметь получать информацию от вышестоящих (и наоборот). Например, только Фабрика умеет создавать объекты. Только Среда исполнения имеет Журнал работы (StdLog), в который все нижележащие агрегаты могут писать. То есть потоки информации идут в обе стороны по линии агрегирования как вглубь так и наверх.
Re[2]: Паттерны. Тестовые задачки.
От: prVovik Россия  
Дата: 21.09.04 21:08
Оценка:
Здравствуйте, S.Yu.Gubanov, Вы писали:

SYG>Впрочем, попробуйте решить задачу об агрегировании одних объектов другими.


SYG>Пусть есть пирамида агрегирования.

Ух, какое название

SYG>На вершине этой пирамиды находится самый большой агрегат — фабрика (Factory).

А разве фабрика должна что-то агрегировать? Ее единственная задача — это скрыть способ создания экземпляров. Разве не так?
... << RSDN@Home 1.1.4 @@subversion >>
лэт ми спик фром май харт
Re[3]: Паттерны. Тестовые задачки.
От: Аноним  
Дата: 22.09.04 06:44
Оценка:
SYG>>Пусть есть пирамида агрегирования.
У предложенной вами задачки решение написано прямо в книге. Т.е. используем паттерн Compose.
Все объекты между Factory и Object — есть суть один объект Composite, который содержит ссулки на родителя и потомков. Родители и потомки могут быть также составными. Т.е можно вводить любое кол-во доп. уровней без перепроектирования приложения.
Прийдется видать что-то придумывать себе самому.
Re[4]: Паттерны. Тестовые задачки.
От: S.Yu.Gubanov Россия http://sergey-gubanov.livejournal.com/
Дата: 22.09.04 07:32
Оценка:
Здравствуйте, Аноним, Вы писали:

SYG>>>Пусть есть пирамида агрегирования.

А>У предложенной вами задачки решение написано прямо в книге. Т.е. используем паттерн Compose.
А>Все объекты между Factory и Object — есть суть один объект Composite, который содержит ссулки на родителя и потомков. Родители и потомки могут быть также составными. Т.е можно вводить любое кол-во доп. уровней без перепроектирования приложения.
А>Прийдется видать что-то придумывать себе самому.

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

Тупой ответ может быть таким:
1) Вниз по уровням агрегации:
Node.View.Location.SetPosition(X, Y);

2) Вверх по уровням агрегации:
node := SELF.Domain.Document.Environment.Factory.NewNode();

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

Было:
Node.View.Location.SetPosition(X, Y);

Хотим вставить между View и Location дополнительный слой агрегации Graphic2D, тогда все строчки кода подобные вышеприведенной придется переписать на новые:
Node.View.Graphic2D.Location.SetPosition(X, Y);



Или так:
Было
node := SELF.Domain.Document.Environment.Factory.NewNode();

Между Environment и Factory появился новый слой агрегации System, тогда все строчки кода подобные вышеприведенной придется переписать на новые:
node := SELF.Domain.Document.Environment.System.Factory.NewNode();


Вопрос в том как реализовать агрегацию (composite) так чтобы потом ее можно было по всякому разбирать и собирать добавляя или удаляя уровни агрегации не переписывая при этом код.
Re[3]: Паттерны. Тестовые задачки.
От: S.Yu.Gubanov Россия http://sergey-gubanov.livejournal.com/
Дата: 22.09.04 07:43
Оценка:
Здравствуйте, prVovik, Вы писали:

SYG>>На вершине этой пирамиды находится самый большой агрегат — фабрика (Factory).

V>А разве фабрика должна что-то агрегировать? Ее единственная задача — это скрыть способ создания экземпляров. Разве не так?

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


Например, в приложении Windows

MainForm--<--Factory(es)--<--Environment(s)--<--(Всё-Всё-Всё)

Можно считать, что главная форма приложения Windows создается автоматически. И она (главная форма приложения) создает Фабрику, поскольку только она знает как ее создать.
Re[5]: Паттерны. Тестовые задачки.
От: Аноним  
Дата: 22.09.04 07:47
Оценка:
Ух ты!!! Я тоже только недавно приобщился к паттернам текущий проект просто по швам затрещал от переделок.

Я бы в текущей задаче встроил систему команд или сообщений.

С уважением.
Re: Паттерны. Тестовые задачки.
От: LaptevVV Россия  
Дата: 22.09.04 07:57
Оценка: 7 (1)
Здравствуйте, Аноним, Вы писали:

А>К своему стыду только недавно узнал про Паттерны проектирования. Сейчас читаю всем известную книгу Эриха Гамма, с соавторами про паттерны. Там в качестве практического примера приводится графический редактор Lexi. По мере прочтения хочется самому закреплять на практике прочитанный материал, применяя паттерны на примере не такого относительно большого примера как Lexi, а чего-то в кодировании поменьше объемом, но со всеми сруктурными особенностями. Может быть что-то связанном с вводом/выводом. Не хочется самому придумывать, навереняка уже есть какие-то уже продуманные задачки.

Нету пока нигде ни фига. Мы тут с пацанами начинаем придумывать сборник задач по ООП, где задачи на паттерны будут. А пока — только самому изощряться.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[4]: Паттерны. Тестовые задачки.
От: prVovik Россия  
Дата: 22.09.04 08:07
Оценка:
Здравствуйте, S.Yu.Gubanov, Вы писали:

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


SYG>>>На вершине этой пирамиды находится самый большой агрегат — фабрика (Factory).

V>>А разве фабрика должна что-то агрегировать? Ее единственная задача — это скрыть способ создания экземпляров. Разве не так?

SYG>Правильно, все так! Но кто создаст экземпляр самой фабрики?

Обычно фабрика — это синглтон.
... << RSDN@Home 1.1.4 @@subversion >>
лэт ми спик фром май харт
Re[5]: Паттерны. Тестовые задачки.
От: S.Yu.Gubanov Россия http://sergey-gubanov.livejournal.com/
Дата: 22.09.04 08:49
Оценка: 1 (1) +1
Здравствуйте, prVovik, Вы писали:

SYG>>Правильно, все так! Но кто создаст экземпляр самой фабрики?

V>Обычно фабрика — это синглтон.

Если фабрика синглетон, значит, тем более, она обязана быть в вершине агрегации. В самом деле, не может же какой-либо динамический объект агрегировать (статический) синглетон. Динамический объект может быть осведомлен о синглетоне, но агрегировать его (владеть им) он не может (время жизни синглетона больше времени жизни динамических объектов).

А вообще, синглетоны вредны тем что жестко фиксируют архитектуру программы. Лучше обходится без них. Вернее, обходится минимально возможным их количеством = 1 сама программа.
Re[5]: Паттерны. Тестовые задачки.
От: Аноним  
Дата: 22.09.04 08:53
Оценка:
Здравствуйте, S.Yu.Gubanov, Вы писали:

SYG>Тупой ответ может быть таким:

SYG>1) Вниз по уровням агрегации:
SYG>
SYG>Node.View.Location.SetPosition(X, Y);
SYG>

SYG>2) Вверх по уровням агрегации:
SYG>
SYG>node := SELF.Domain.Document.Environment.Factory.NewNode();
SYG>

SYG>Но такое решение жестко фиксирует всю архитектуру приложения. Мы не можем разобрать такую пирамиду агрегации ни сверху, ни, тем более, снизу. Мы не можем вставить дополнительные слои и не можем вынуть существующие слои агрегации.

В книге рекомендут использовать паттерн Command.

К примеру

SYG>Было:

SYG>
SYG>Node.View.Location.SetPosition(X, Y);
SYG>

SYG>Хотим вставить между View и Location дополнительный слой агрегации Graphic2D, тогда все строчки кода подобные вышеприведенной придется переписать на новые:
SYG>
SYG>Node.View.Graphic2D.Location.SetPosition(X, Y);
SYG>

Здесь все зависит от конкретной задачи. Мне не очень понятно, что именно нужно. В примере Lexi для добавления ф-ти использовали Decore и Bridge.

SYG>Вопрос в том как реализовать агрегацию (composite) так чтобы потом ее можно было по всякому разбирать и собирать добавляя или удаляя уровни агрегации не переписывая при этом код.

Так весь смысл Composite, что-бы в коде писать Composite.Draw() или другой метод. А сама реализация уже в классе. Добавления еще одного объекта или дополнительной агрегации кода приложения не меняет.
Re[2]: Паттерны. Тестовые задачки.
От: flax Беларусь  
Дата: 22.09.04 09:36
Оценка:
Здравствуйте, LaptevVV, Вы писали:

LVV>Нету пока нигде ни фига. Мы тут с пацанами начинаем придумывать сборник задач по ООП, где задачи на паттерны будут. А пока — только самому изощряться.


К вам будет можно присоединиться?
Мне, в принципе, тоже хотелось бы создать GuideLine по этой тематике с помощью набора задач.

"Т.е. ты прочитал? Ну давай, здесь как? А если чуть посложнее, а если несколько, и вот тебе задача на страндартную ошибку проектирования, справился? Нет, тогда вот тебе четкая линка — читай то и то, потом выполнишь контр. задания и пойдем дальше."
Re[3]: Паттерны. Тестовые задачки.
От: LaptevVV Россия  
Дата: 22.09.04 09:48
Оценка:
Здравствуйте, flax, Вы писали:

F>К вам будет можно присоединиться?

F>Мне, в принципе, тоже хотелось бы создать GuideLine по этой тематике с помощью набора задач.

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


Тогда надо начинать с заданий на простые структурные паттерны типа Adapter, Singleton.
MonoState, Bridge. Потом переходить к простым паттернам поведениявроде итератор, команда, интерпретатор, визитер. Паттерны порождающие оставить на конец.

Беда в том, что для реализации этих заданий нужна задача типа этюда по программированию (Уэзерелл), или курсовой работы. Такие объемные задачи нелегко придумать ( а уж студентам и подавно сложно их делать в качестве упражнения) для некоторых сложных паттернов. С простыми все вроде проще: паттерн команда, как в у банды четырех, привязывается к реализации меню, например. Singleton — единственность приложения.

И еще одна проблема: польза паттернов четко осознается при сопровождении-рефакторинге, когда надо добавлять функциональность или изменять существующую. Получается, что задание должно состоять из 2 частей: сначала написать без использования паттернов, а потом переписать то же самое с паттернами.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[2]: Паттерны. Тестовые задачки.
От: Victor Repetsky Украина  
Дата: 22.09.04 10:33
Оценка:
Здравствуйте, LaptevVV, Вы писали:

LVV>Нету пока нигде ни фига. Мы тут с пацанами начинаем придумывать сборник задач по ООП, где задачи на паттерны будут.

Есть довольное большое число вопросов в разных примерах сертификационных экзаменов Sun, IBM.
Например http://groups.yahoo.com/group/scea_j2ee/files/ (требует регистрации на яхе), файл SCEA Practice Questions.zip .
Бывают вопросы разной сложности, на задачи не тянут а на задачки — вполне

Всего хорошего.
Виктор.
SCJP, SCEA
Re[6]: Паттерны. Тестовые задачки.
От: prVovik Россия  
Дата: 22.09.04 11:33
Оценка:
Здравствуйте, S.Yu.Gubanov, Вы писали:

SYG>Если фабрика синглетон, значит, тем более, она обязана быть в вершине агрегации.

Зачем?

SYG>В самом деле, не может же какой-либо динамический объект агрегировать (статический) синглетон. Динамический объект может быть осведомлен о синглетоне, но агрегировать его (владеть им) он не может (время жизни синглетона больше времени жизни динамических объектов).

А почему кто-то кого-то обязательно должен агрегировать?

SYG>А вообще, синглетоны вредны тем что жестко фиксируют архитектуру программы. Лучше обходится без них. Вернее, обходится минимально возможным их количеством = 1 сама программа.

А я считаю, что не надо придумывать никаких рамок. Если суть объекта предполагает уникальность, то почему бы не зафиксировать это явно, сделав его синглтоном? А может быть вы считаете, что паттерн "синглтон" предполагает уникальность объекта во вселенной? Нет, это не так. Он уникален лишь по отношению к некоторой абстракции: к программе, к подсистеме и пр.
... << RSDN@Home 1.1.4 @@subversion >>
лэт ми спик фром май харт
Re[7]: Паттерны. Тестовые задачки.
От: S.Yu.Gubanov Россия http://sergey-gubanov.livejournal.com/
Дата: 22.09.04 12:52
Оценка:
Здравствуйте, prVovik, Вы писали:

V>А почему кто-то кого-то обязательно должен агрегировать?


Справедливый вопрос. Ответ на него я не знаю. Но так получилось, что все окружающие нас предметы являются агрегатами. Агрегат — значит состоит из чего-то более мелкого. Причем количество типов более мелких агрегатов меньше чем количество типов более крупных агрегатов. Вот например несколько сотен типов атомов таблицы Менделеева состоят всего из трех типов "элементарных" частиц электрон+протон+нейтрон. Бесчисленное количество типов молекул состоит из нескольких сотен типов атомов. "Бесчисленное" количество типов живых существ состоят всего из нескольких типов аминокислот (или чего там еще — я не спец в этом вопросе). Все предметы которые мы видим вокруг себя состоят из чего-то. Еще пример: Слово — агрегат букв. Букв в алфавите мало, а слов построеных из этих букв много. Агрегаты повсюду, а элементарных объектов очень мало. Традиционное ООП дает нам возможность строить элементарные объекты. То что в будущем придет на смену классического ООП даст нам возможность с легкостью работать с агрегатами абстрагируясь от конкретных механизмов агрегации.

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


А я разьве придумываю рамки? Раз он уникален только по отношению к некой подсистеме, это и означает, что эта самая подсистема агрегирует (содержит) один экземпляр этого объекта. А сама эта подсистема агрегируется какой-то более крупной системой.
Re[6]: Паттерны. Тестовые задачки.
От: S.Yu.Gubanov Россия http://sergey-gubanov.livejournal.com/
Дата: 22.09.04 13:03
Оценка:
Здравствуйте, Аноним, Вы писали:

А>В книге рекомендут использовать паттерн Command.


1) Но у классического паттерна Command нет параметров вызова. То есть, как передать X,Y в метод SetPosition(X, Y)?

2) А как получить сам объект Command минуя несколько уровней агрегации?

3) Если использовать механизм сообщений (там можно будет параметры передавать), то скорость работы упадет. Хотелось бы эффективностью не жертвовать...

4) А еще хотелось бы кода поменьше писать для поддержки этого механизма.


А>Так весь смысл Composite, что-бы в коде писать Composite.Draw() или другой метод. А сама реализация уже в классе. Добавления еще одного объекта или дополнительной агрегации кода приложения не меняет.


Но ведь на разных уровнях агрегации (в подавляющем большинстве случаев, короче — всегда) находятся объекты разных типов. То есть у них нет общих методов, типа Draw() или ему подобных. Наверняка присутствующий у всех метод это метод SetAggregate(NewAggregate)...
Re[7]: Паттерны. Тестовые задачки.
От: Аноним  
Дата: 22.09.04 13:25
Оценка:
А>>Так весь смысл Composite, что-бы в коде писать Composite.Draw() или другой метод. А сама реализация уже в классе. Добавления еще одного объекта или дополнительной агрегации кода приложения не меняет.

SYG>Но ведь на разных уровнях агрегации (в подавляющем большинстве случаев, короче — всегда) находятся объекты разных типов. То есть у них нет общих методов, типа Draw() или ему подобных. Наверняка присутствующий у всех метод это метод SetAggregate(NewAggregate)...


Если вы все-таки возьмете эту книгу, то в паттерне Compose, все объекты прикладные объекты, в т.ч и агрегирующий объект наследуются от одного абстарктного объекта-интерфеса. Работа со всей системой ведется только через эти интерфейсы. А сами объекты, получая например вызов draw() с верхнего уровня, уже сами разбираются как себя рисовать в зависимости от его природы.
Спорить дальше не хочу, т.к. сам учу паттерны, но в книге все очень доходчиво расписано именно по тем вопросам, что вы поставили. ТОлько пример текстового редактора, на котором это все рассматривалось — весьма сложен для самостоятельной реализации.
Re[8]: Паттерны. Тестовые задачки.
От: prVovik Россия  
Дата: 22.09.04 14:11
Оценка:
Здравствуйте, S.Yu.Gubanov, Вы писали:


SYG>Справедливый вопрос. Ответ на него я не знаю. Но так получилось, что все окружающие нас предметы являются агрегатами. Агрегат — значит состоит из чего-то более мелкого. Причем количество типов более мелких агрегатов меньше чем количество типов более крупных агрегатов. Вот например несколько сотен типов атомов таблицы Менделеева состоят всего из трех типов "элементарных" частиц электрон+протон+нейтрон. Бесчисленное количество типов молекул состоит из нескольких сотен типов атомов. "Бесчисленное" количество типов живых существ состоят всего из нескольких типов аминокислот (или чего там еще — я не спец в этом вопросе). Все предметы которые мы видим вокруг себя состоят из чего-то. Еще пример: Слово — агрегат букв. Букв в алфавите мало, а слов построеных из этих букв много. Агрегаты повсюду, а элементарных объектов очень мало. Традиционное ООП дает нам возможность строить элементарные объекты. То что в будущем придет на смену классического ООП даст нам возможность с легкостью работать с агрегатами абстрагируясь от конкретных механизмов агрегации.

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

SYG>Раз он уникален только по отношению к некой подсистеме, это и означает, что эта самая подсистема агрегирует (содержит) один экземпляр этого объекта.

Не обязательно. Объект, в принцепе, может передаваться системе из вне.
... << RSDN@Home 1.1.4 @@subversion >>
лэт ми спик фром май харт
Re[4]: Паттерны. Тестовые задачки.
От: Sinclair Россия https://github.com/evilguest/
Дата: 23.09.04 04:44
Оценка: 5 (1)
Здравствуйте, LaptevVV, Вы писали:

LVV>И еще одна проблема: польза паттернов четко осознается при сопровождении-рефакторинге, когда надо добавлять функциональность или изменять существующую. Получается, что задание должно состоять из 2 частей: сначала написать без использования паттернов, а потом переписать то же самое с паттернами.

Не, задание должно быть устроено так:
1. Дано безпаттернное решение известной задачи.
2. Поставлена задача добавить в решение определенную функциональность.

По идее, этого должно быть достаточно для демонстрации преимущества паттернов. Подразумевается, что ученик решает задачу в два хода — сначала рефакторит исходное решение, а уже потом добавляет функциональность. Может быть, потребовать три результата:
1. Решение поставленной задачи на основе исходного кода, в свободном стиле
2. Отрефакторенный код решения исходной задачи (верификация корректности рефакторинга юнит-тестами)
3. Решение поставленной задачи на основе отрефакторенного кода.
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[8]: Паттерны. Тестовые задачки.
От: S.Yu.Gubanov Россия http://sergey-gubanov.livejournal.com/
Дата: 23.09.04 08:01
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Если вы все-таки возьмете эту книгу, то в паттерне Compose, все объекты прикладные объекты, в т.ч и агрегирующий объект наследуются от одного абстарктного объекта-интерфеса. Работа со всей системой ведется только через эти интерфейсы. А сами объекты, получая например вызов draw() с верхнего уровня, уже сами разбираются как себя рисовать в зависимости от его природы.


А что Вы, собственно, привязались к паттерну Compose? Агрегат, в общем случае, не описывается одним лишь только этим паттерном. Это хорошо когда у всех компонентов агрегата на любой глубине агрегации есть метод draw(); а если нет? Вот, например, автомобиль — это агрегат. У автомобильного мотора есть метод Run(); но ни у какого другого компонента этого метода больше нет. И что тогда делать? Паттерн Compose тут недостаточен. Я же Вам говорю, что все компоненты агрегата, в подавляющем большинстве случаев, есть объекты совсем разных типов, то есть общих методов у них ничтожно малое количество.
Re[9]: Паттерны. Тестовые задачки.
От: S.Yu.Gubanov Россия http://sergey-gubanov.livejournal.com/
Дата: 23.09.04 08:32
Оценка:
Здравствуйте, prVovik, Вы писали:

V>Вопрос не в этом. Почему вы считаете, что либо фабрика должна агрегировать создаваемые ею объекты, либо объекты должны агрегировать фабрику, которая их создала. Помоему, это, мягко говоря, странно


В общефилософском смысле это странно, а в рамках парадигмы агрегации это не странно. Логические рассуждение таковы:

Аксиома 1
Все есть агрегат.

Аксиома 2
Агрегат может взаимодействовать только либо со своими компонентами либо со своим непосредственным (вышестоящим) агрегатом.

Следствие 1. О запросах
Если агрегату что-то нужно такое что лично у него нет, то он спрашивает об этом либо у своих компонентов, либо у своего вышестоящего агрегата.

Теорема про фабрику
Если агрегату нужно создать какой-то объект, то для начала ему нужна фабрика. Естественно, у компонетов этой фабрики быть не может иначе они бы пускай и создавали этот объект и проблемы бы не было. Значит про фабрику, этому агрегату можно спросить только у своего вышестоящего агрегата (а больше не у кого!). Стало быть, фабрику агрегат получит (или не получит) от своего непосредственного вышестоящего агрегата. Следовательно фабрика всегда находится выше по уровням агрегации всех тех кто ее использует. Но если фабрика создает все-все-все объекты кроме себя, то она и находится выше по уровням агрегации всех-всех-всех этих объектов. Выше фабрики находится только само приложение, которое может создать объект фабрики самостоятельно (ну, или, какая-то другая супер-фабрика фабрик находящаяся еще выше по уровням агрегации).


SYG>>Раз он уникален только по отношению к некой подсистеме, это и означает, что эта самая подсистема агрегирует (содержит) один экземпляр этого объекта.

V>Не обязательно. Объект, в принцепе, может передаваться системе из вне.

Естественно. Это означает, что он агрегируется какой-то более крупной системой.
Re[10]: Паттерны. Тестовые задачки.
От: Sinclair Россия https://github.com/evilguest/
Дата: 24.09.04 04:04
Оценка: 6 (2)
Здравствуйте, S.Yu.Gubanov, Вы писали:

SYG>В общефилософском смысле это странно, а в рамках парадигмы агрегации это не странно. Логические рассуждение таковы:


SYG>Аксиома 1

SYG>Все есть агрегат.

SYG>Аксиома 2

SYG>Агрегат может взаимодействовать только либо со своими компонентами либо со своим непосредственным (вышестоящим) агрегатом.
Я не столь уверен в правильности этой аксиомы. Обычно мы можем с любого уровня получить доступ к "окружающей среде", хотя она напрямую мало кого агрегирует.
Вот например, колесо может взаимодействовать с машиной, со ступицей и со своим воздухом. Но если ему надо взаимодействовать с дорогой, то что? Дорога, очевидно, не может находиться в отношениях агрегации с колесом ни с какой стороны. Ок, ты наверное забыл добавить Аксиому 3, по которой агрегат может взаимодействовать также и с объектом, ссылку на которую он ранее получил (от другого агрегата, или объекта, который он в свою очередь получил и т.д.).

Нет, конечно, формально можно ввести такой суперобъект Environment который является ультимативным агрегатом. Т.е. сам он ни в чем не агрегирован. При этом достаточно встроить в корневой базовый класс способность получать Environment путем обращения к своему вышестоящему агрегату. Таким образом, мы просовываем окружающую среду сквозь все объекты, даже те, которые в ней не нуждаются. Колесо попросит дорогу у подвески, которая попросит ее у машины, которая попросит ее у гаража, который попросит ее у дачного комплекса, который попросит ее у города, который попросит ее у страны, которая... По-моему, это не очень хороший дизайн. Стало быть, сколь бы логичнывми ни были твои рассуждения, они непригодны для мотивации реальной проектной деятельности.
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[9]: Паттерны. Тестовые задачки.
От: LamerDrv Россия  
Дата: 24.09.04 04:48
Оценка:
Здравствуйте, S.Yu.Gubanov, Вы писали:

SYG>Здравствуйте, Аноним, Вы писали:


А>>Если вы все-таки возьмете эту книгу, то в паттерне Compose, все объекты прикладные объекты, в т.ч и агрегирующий объект наследуются от одного абстарктного объекта-интерфеса. Работа со всей системой ведется только через эти интерфейсы. А сами объекты, получая например вызов draw() с верхнего уровня, уже сами разбираются как себя рисовать в зависимости от его природы.


SYG>А что Вы, собственно, привязались к паттерну Compose? Агрегат, в общем случае, не описывается одним лишь только этим паттерном. Это хорошо когда у всех компонентов агрегата на любой глубине агрегации есть метод draw(); а если нет? Вот, например, автомобиль — это агрегат. У автомобильного мотора есть метод Run(); но ни у какого другого компонента этого метода больше нет. И что тогда делать? Паттерн Compose тут недостаточен. Я же Вам говорю, что все компоненты агрегата, в подавляющем большинстве случаев, есть объекты совсем разных типов, то есть общих методов у них ничтожно малое количество.


Кажется, механизм, примерно удовлетворяющий Вашим требованиям (имеется в виду хождение по иерархии), реализован в библиотеке Stingray Foundation Library. Подробности, к сожалению, уже не помню (но если интересно могу уточнить).Кажется, у Stingray этот механизм, кроме всего прочего, используется совместно с паттерном MVC (который, есть классический пример Composite )
Re[3]: Паттерны. Тестовые задачки.
От: LaptevVV Россия  
Дата: 24.09.04 05:31
Оценка:
Здравствуйте, Victor Repetsky, Вы писали:

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


LVV>>Нету пока нигде ни фига. Мы тут с пацанами начинаем придумывать сборник задач по ООП, где задачи на паттерны будут.

VR>Есть довольное большое число вопросов в разных примерах сертификационных экзаменов Sun, IBM.
VR>Например http://groups.yahoo.com/group/scea_j2ee/files/ (требует регистрации на яхе), файл SCEA Practice Questions.zip .
VR>Бывают вопросы разной сложности, на задачи не тянут а на задачки — вполне
А что делать после регистрации?
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[11]: Паттерны. Тестовые задачки.
От: S.Yu.Gubanov Россия http://sergey-gubanov.livejournal.com/
Дата: 24.09.04 08:17
Оценка: 6 (1)
Здравствуйте, Sinclair, Вы писали:

S>Нет, конечно, формально можно ввести такой суперобъект Environment который является ультимативным агрегатом. Т.е. сам он ни в чем не агрегирован. При этом достаточно встроить в корневой базовый класс способность получать Environment путем обращения к своему вышестоящему агрегату.


Да-да-да! Именно так! Внешняя среда объекта есть его агрегат. Любой агрегат объекта выступает для этого объекта в роли внешней среды или, другими словами, в роли контекста исполнения. Тут можно провести аналогию с первобытным ООП, то есть тем когда ООП было данные+процедуры. К процедуре добавили контекст исполнения, т.е. привязали процедуру к каким-то данным, и все это вместе данные+процедуры обозвали объектом. Потом сказали что все есть объект. Но что мешает сделать следующий шаг? Давайте, теперь уже к каждому объекту прицепим его контекст исполнения — эту штуковину назовем агрегатом. Потом скажем, что все есть агрегат! У каждого агрегата есть свой более крупный агрегат и т.д.


S>Таким образом, мы просовываем окружающую среду сквозь все объекты, даже те, которые в ней не нуждаются. Колесо попросит дорогу у подвески, которая попросит ее у машины, которая попросит ее у гаража, который попросит ее у дачного комплекса, который попросит ее у города, который попросит ее у страны, которая...


В принципе верно, но есть пара замечаний:

1) Когда автомобиль стоит в гараже, вот тогда гараж является его агрегатом. Когда автомобиль едет по дороге, то его агрегатом является дорога (или окружающая местность, если он едет по бездорожью). Агрегаты можно динамически менять.

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

3) Агрегат не знает большинство всех тех интерфейсов, которые у него могут запросить его компоненты, поэтому у него есть механизм, который автоматом переадресует все запросы о неизвестных ему интерфейсах на более высокий уровень агрегации. То есть агрегат может "просунуть" сквозь себя потенциально неограниченное количество интерфейсов и даже не знать каких именно. Реализовать это очень просто (у меня это заняло 7 строчек кода на Delphi):
FUNCTION TAggregate.GetAscentInterface(CONST IID: TGUID; OUT Obj): BOOLEAN;
BEGIN
  RESULT := SELF.GetInterface(IID, Obj);
  IF (NOT RESULT) AND (SELF.FAggregate <> NIL) THEN BEGIN
    RESULT := SELF.FAggregate.GetAscentInterface(IID, Obj)
  END;
END;


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


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


P. S.
Как у меня все это работает:
TYPE
  IAggregate = INTERFACE (Storable)
    ['{B062A88E-1EF8-4D13-918E-2FD0FDAEC811}']
    FUNCTION    GetAscentInterface (CONST IID: TGUID; OUT Obj): BOOLEAN;
    FUNCTION    GetDirectInterface (CONST IID: TGUID; OUT Obj): BOOLEAN;
    FUNCTION    GetDescendInterface(CONST IID: TGUID; OUT Obj): BOOLEAN;
    PROCEDURE   SetAggregate(NewAggregate: IAggregate);
    PROCEDURE   Delete;
  END;

//------------------------------------------------------------------------------
(*

  FUNCTION GetAscentInterface (CONST IID: TGUID; OUT Obj): BOOLEAN;

Запрос интерфейса по восходящей линии агрегирования. Сначала интерфейс ищется
у самого агрегата. Если запрошенный интерфейс самим агрегатом не реализован, то
запрос пересылается вверх по уровням агрегации; и так до тех пор пока он не
дойдет до среды исполнения. Среда исполнения - самый большой агрегат (агрегат
всех агрегатов).

//------------------------------------------------------------------------------

  FUNCTION GetDirectInterface (CONST IID: TGUID; OUT Obj): BOOLEAN;

Запрос интерфейса реализованного непосредственно самим агрегатом.

//------------------------------------------------------------------------------

  FUNCTION GetDescendInterface(CONST IID: TGUID; OUT Obj): BOOLEAN;

Запрос интерфейса по нисходящей линии агрегирования. Сначала интерфейс ищется
у самого агрегата. Если запрошенный интерфейс самим агрегатом не реализован, то
запрос пересылается вниз (вглубь) по уровням агрегации; и так до тех пор пока
он не дойдет до самого последнего компонента из всех компонентов агрегата.

//------------------------------------------------------------------------------

  PROCEDURE SetAggregate(NewAggregate: IAggregate);

Устанавливает агрегат агрегата, то есть тот агрегат внутри которого находится
(агрегирован) исходный агрегат. Благодаря тому что у агрегата есть ссылка на
содержащий его более крупный агрегат, он может пересылать ему восходящие
запросы по предоставлению услуг по необходимым ему интерфейсам. Поскольку при
смене агрегата может произойти смена предоставляемых интерфейсов, то агрегат,
у которого был вызван метод SetAggregate должен перевызвать этот метод
для своих компонентов (разумеется, с аргументом NewAggregate = SELF).
Если какие-либо интерфейсы были кэшированы, то их надо обновить.

//------------------------------------------------------------------------------

  PROCEDURE Delete;

Уничтожение всех агрегированных компонентов. Поскольку для интерфейсов работает
счетчик ссылок, интерфейсный объект нельзя уничтожить до тех пор пока на него
есть ссылки. Агрегат имеет ссылки на свои компоненты, а компоненты имеют
ссылку на свой агрегат, то есть ссылки являются циклическими. Механизм подсчета
ссылок непригоден в случае наличия циклических ссылок объектов друг на друга.
Циклически ссылающиеся друг на друга объекты, с точки зрения механизма подсчета
ссылок, не уничтожимы. Метод Delete предназначен для того чтобы разорвать
этот замкнутый круг. Внутри этого метода агрегат должен обнулить свою ссылку
на более крупный агрегат, а также вызвать этот метод у всех своих компонентов
и обнулить ссылки на свои компоненты. Таким образом, циклические ссылки будут
разорваны, а объекты уничтожены.

*)
//------------------------------------------------------------------------------
Re[4]: Паттерны. Тестовые задачки.
От: Victor Repetsky Украина  
Дата: 24.09.04 08:59
Оценка:
Здравствуйте, LaptevVV, Вы писали:

LVV>А что делать после регистрации?


Зарегистрироватся в группе scea_j2ee, зайти в раздел files, скачать файл.

Недавно в этой группе шло горячее обсуждение вопроса какой паттерн
применен если использовать Connection Pool.
То есть на самом деле применены фабрика и синглтон,
но экзамен требует одного ответа. Какой паттерн важнее — мнения разошлись

Всего хорошего.
Виктор.
SCJP, SCEA
Re: Паттерны. Тестовые задачки.
От: vorl  
Дата: 28.09.04 12:43
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>К своему стыду только недавно узнал про Паттерны проектирования. Сейчас читаю всем известную книгу Эриха Гамма, с соавторами про паттерны. Там в качестве практического примера приводится графический редактор Lexi. По мере прочтения хочется самому закреплять на практике прочитанный материал, применяя паттерны на примере не такого относительно большого примера как Lexi, а чего-то в кодировании поменьше объемом, но со всеми сруктурными особенностями. Может быть что-то связанном с вводом/выводом. Не хочется самому придумывать, навереняка уже есть какие-то уже продуманные задачки.

А>Спасибо.

Прочитав эту книгу я написал библиотеку с помощью которой смог генерить отчеты в различных форматах.
Идея такова. Документ состоит из заголовка и трилера, между ними тело отчета. Тело может состоять из заголовка, траилера и данных. Данные, заголовок и траилер состоят из строк с данными. Строки состоят из полей. Поля имеют свой тип, задаваемый при создании строки. Поля имеют функцию их отображения в текстовом виде. Создаем фабрику классов для строк, где реализуем правила создания строк и предоставления их.
При заполнении строк данными вбираем нужную строку и работаем с ней.
При создании файла даем комаду документу сохраниться, тот готовит свое представление в текстовом виде передавая команду своим элементам выдать результат в текстовом виде.
В общем наибольшее время ушло на создание прототипа. Остальные варианты пошли горазда быстрее.
... << RSDN@Home 1.1.3 stable >>
Re: Паттерны. Тестовые задачки.
От: kwas Россия  
Дата: 29.09.04 07:57
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Не хочется самому придумывать, навереняка уже есть какие-то уже продуманные задачки.


Здесь. Только английский, и только Java. Задачки — простенькие. Solution Guide, как я понимаю, еще не написан, а если бы и был написан, то продавался бы за денежку.
If a shark stops swimming, it will die. Don't stop swimming, Mr. Mulder.
Every epic equalizer is iso (c)
Re[2]: Паттерны. Тестовые задачки.
От: d.Igor  
Дата: 29.09.04 10:36
Оценка:
Здравствуйте, LaptevVV, Вы писали:


LVV>Нету пока нигде ни фига. Мы тут с пацанами начинаем придумывать сборник задач по ООП, где задачи на паттерны будут. А пока — только самому изощряться.


Daj pochitat', wse chto uzhe est'??
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.