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...
Пока на собственное сообщение не было ответов, его можно удалить.