Re[53]: ...продолжение
От: Cyberax Марс  
Дата: 28.05.07 10:19
Оценка:
Sinclair wrote:
> AVK>Точно путаешь. Grid layout (термин из Swing, WPF) это то, что в вебе
> реализуется как раз таки при помощи таблиц и называется табличной версткой.
> Может быть, может быть. Хотя, насколько я помню SWING, его grid layout
> значительно жестче, чем даже table layout в вебе, т.к. компоненты не
> могут пересекать границы клеток.
В SWING есть GridBagLayout, в котором это возможно (как и еще куча
всего, он даже мощнее вебовского).
Posted via RSDN NNTP Server 2.1 beta
Sapienti sat!
Re[53]: ...продолжение
От: Delight  
Дата: 29.05.07 04:06
Оценка: :)
Здравствуйте, Sinclair, Вы писали:

S>Может быть, может быть. Хотя, насколько я помню SWING, его grid layout значительно жестче, чем даже table layout в вебе, т.к. компоненты не могут пересекать границы клеток.

Могут. Span поддерживается.

Когда-то сам делал простенькую сериализацию-десериализацию в XML (.NET 1.1) и пришёл к выводу, что для управления layoutом вполне хватает splitted panel c абсолютными и процентными пропорциями деления. Практически та же HTML-table, только вид в профиль. И, само собой, контролы надо через reflection настраивать.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[54]: ...продолжение
От: aka50 Россия  
Дата: 29.05.07 11:16
Оценка:
Здравствуйте, Delight, Вы писали:

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


S>>Может быть, может быть. Хотя, насколько я помню SWING, его grid layout значительно жестче, чем даже table layout в вебе, т.к. компоненты не могут пересекать границы клеток.

D>Могут. Span поддерживается.
D>Когда-то сам делал простенькую сериализацию-десериализацию в XML (.NET 1.1) и пришёл к выводу, что для управления layoutом вполне хватает splitted panel c абсолютными и процентными пропорциями деления. Практически та же HTML-table, только вид в профиль. И, само собой, контролы надо через reflection настраивать.

Все становиться несокько менее весело, когда хочется использовать liquid css design: http://www.mardiros.net/liquid-css-layouts.html
пример подобной техники: http://www.glish.com/css/1.asp
Re[55]: ...продолжение
От: Delight  
Дата: 29.05.07 11:56
Оценка:
Здравствуйте, aka50, Вы писали:

A>Все становиться несокько менее весело, когда хочется использовать liquid css design: http://www.mardiros.net/liquid-css-layouts.html

A>пример подобной техники: http://www.glish.com/css/1.asp

А тут в чём проблема? ИМХО CSS как раз легко подменить и никакой новой сущности не надо. Другое дело — десктоповые бинарники...
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[40]: ...продолжение
От: Кирилл Лебедев Россия http://askofen.blogspot.com/
Дата: 01.06.07 13:59
Оценка:
Здравствуйте, WolfHound,

Ок, давайте продолжим.

WH>Ну давай. Раскажи что же они сказали.

Если перевести их высказывания на нормальный технический язык, то основных недовольства два:

  1. "Мешанина" из интерфейсов, в числе которых есть и совершенно пустые.
  2. Злоупотребление object'ами в качестве аргументов функции.
        public interface IAttachedProperty : IPropertyBase, IAttachedElement
        {
            object GetValue(object owner, object instance);
            void SetValue(object owner, object instance, object value);
                      // ...
        }

К этому я бы добавил еще две претензии:

  1. Дублирование методов в интерфейсах IProperty и IAttachedProperty, и в интерфейсах IEvent и IAttachedEvent.
        public interface IAttachedProperty : IPropertyBase, IAttachedElement
        {
            object GetValue(object owner, object instance);
            void SetValue(object owner, object instance, object value);
            void AddValueChanged(object owner, object instance, EventHandler handler);
            void RemoveValueChanged(object owner, object instance, EventHandler handler);
            bool CanResetValue(object owner, object instance);
            void ResetValue(object owner, object instance);
            bool ShouldSerializeValue(object owner, object instance);
        }
        public interface IProperty : IPropertyBase, IElement
        {
            object GetValue(object instance);
            void SetValue(object instance, object value);
            void AddValueChanged(object instance, EventHandler handler);
            void RemoveValueChanged(object instance, EventHandler handler);
            bool CanResetValue(object instance);
            void ResetValue(object instance);
            bool ShouldSerializeValue(object instance);
        }

    Методы абсолютно похожи за исключением того, что в IAttachedProperty добавляется еще один аргумент. Из его названия непонятно, но, полагаю, что это контейнер (форма или что-то другое).
  2. Интерфейс IProperty практически полностью повторяет класс PropertyDescriptor, интерфейс IEvent — класс EventDescriptor. Непонятно, зачем потребовалось такое дублирование интерфейсов.

КЛ>>Я спрашивал конкретные примеры. Конкретный пример включает название контрола, примеры свойств (перечислить) и примеры событий.

WH>Зачем это? Я не понимаю.
Затем, чтобы был понятен предмет разговора. Например, в .NET'е термины "атрибут", "свойство" имеют свои специфичные значения. А при программировании на других языках или с использованием иной технологии у этих терминов может быть иное значение. Например, в OOD характеристики объекта (или члены-данные класса) принято называть атрибутами, когда как в .NET это скорее свойства, а атрибуты задают механизм работы с этими свойствами различных инструментов, например, дизайнера форм.

WH>Дались тебе конкретные контролы. Всеравно завтра прибежит заказчик и скажет хочу супер крутой контрол. Я его вчера в одной проге подсмотрел.

WH>И все. Твоя до придела ужатая система начнет трещать по швам ибо нужно будет перелопатить все(сериализаторы, дизайнеры, возможно другие контролы). А моя даже не заметит появление нового контрола. Ну дописали еще одну сборку с контролом и все.
Допустим, контролы будут изменяться. Пусть свойства этих контролов тоже будут совершенно непохожие и не сводимые друг к другу. Но свойства "контролов на форме" (элементов в контейнере) будут практически одинаковыми (или совсем одинаковыми). Это объясняется тем, что форма работает с разными контролами одинаковым образом, и эти дополнительные свойства контролов (Вы их называете добавленными) создаются в ответ на нужды формы. Грубо говоря, форме надо поместить контрол в определенную область, вот он и размещается по заданному X и Y.

Аналогичная ситуация складывается в .NET'е с атрибутами. Не смотря на то, что контрол может иметь любые свойства, эти свойства имеют определенный набор атрибутов, которые позволяют управлять их отображением в PropertyGrid. Т.е. свойства разные, а атрибуты — одинаковые. Здесь я имею в виду одинаковость типов и/или названий атрибутов, а не их значений.

То же самое произойдет и с контролами на форме.

WH>Модель метаданных от самх контролов не зависит никак.

WH>Болие того модель метаданных такова что может работать с чем угодно, а не только контролами.
WH>Это называется повторное использование кода.
И в чем состоит назначение этой модели? Вы просто продублировали и так уже существующие классы PropertyDescriptor и EventDescriptor, при этом, наплодив дубликатов (IProperty и IAttachedProperty, IEvent и IAttachedEvent). И реализовали установку и получение свойства при помощи рефлексии. Классов много, а функциональность — одна. Стоит ли игра свеч?

WH>Так это и были проблемы. Системы фундаментально различные. Но их нужно подвести под общий знаменатель для того чтобы прикладникам (люди рисующие формочки сотнями) не приходилось делать одну и туже работу 2 раза. Болие того тонкости отношений win с web их тоже заботить не должны.

С этим никто и не спорит. Но Вы привели общую цель. А для того, чтобы ее можно было достичь, нужно конкретизировать задачи, которые и возникают из-за различий между win и web forms. Каждую задачу желательно сопроводить поясняющим примером.

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

WH>А зачем мне это надо если в мою модель укладываются все контролы? Всключая контролы для принципиально другого UI и вобще то что контролами UI не является.

WH>Так зачем мне частности если у меня общий случай хорошо работает?
О какой модели идет речь? Вы просто написали читалку и сохранялку свойств с использованием отражения. Извините, но даже в статьях на RSDN.ru и gotdotnet.ru описываются способы, как это можно сделать гораздо проще. Без того, чтобы плодить кучу интерфейсов.

Непонятно, в чем "фишка" Вашего решения?

WH>Не получится. Дело в том что лейауты имеют разную логику. И им нужны разные данные и разный код.

WH>Например томуже сплайн-лейауту нужна информация о базовых точках и логика интерполяции.
WH>Ни одному другому лейауту ни то ни другое не нужно.
Не получится, ну и ладно. В конце-концов, у меня возможность обобщения лэйаутов указывается в качестве дополнительной.
Но, мне кажется, если постараться, то такое обобщение создать можно. Надо просто разобраться в разных видах лэйаутов.

WH>Реализация данной модели метаданных для всех контролов уместилась в 8 классов.

С этим более-менее все понятно. Спасибо за поясняющий код.

WH>Дык всеже в чем притензия к совершенно тривиальному коду?

В нарушении LSP.

WH>Я хочу узнать сколько языков ты знаешь. Ибо от этого очень сильно зависит то как человек проектирует.

WH>Человек знающий только один язык хорошим архитектором быть не может.
WH>Причем нужно изучать совсем разные языки. Те не ограничиваться C/C++/pascal (C# и жаба пожалуй отдельно от C++ и ко ибо там совсем другой стиль разработки), а еще не забыть про всякие хаскели, форты и прочее.
Конечно же, для архитектора будет плюсом знание нескольких языков программирования. Но и стремление к коллекционированию языков программирования в своем "багаже" тоже ни к чему хорошему не приведет. Т.к. языки относятся к реализации, а архитектор больше работает с моделями предметной области, потоками данных и управления.

КЛ>>Позвольте переспросить: Для того, чтобы добавить тултипы ко всем контролам формы, Вы заводите специальный контрол, который осуществляет такое добавление?

WH>Да. Причем этот контрол не знает в лицо ни один другой контрол. И все работает. Забавно правда?
WH>Кстати не помню как в WinForms 1 но в WinForms 2 сделано также.
А каким образом он добавляет это свойство?

WH>А у тебя со "спокойно реализуете" будут большие проблемы.

С чего Вы это взяли? С того, что приведенные таблицы не содержат нужное Вам свойство? Так чего Вы хотели от чернового решения? Оно лишь дано для иллюстрации подхода. А вот в Вашем случае, формы, созданные по той же "тултипной" технологии, станут просто несопровождаемыми из-за хаотичной зависимости между контролами. Сопровождающий программист просто запарится определять, какие свойства добавляет какой компонент. Конечно, в том случае, когда таких компонентов не 2 — 3, а 10 — 20.
С уважением,
Кирилл Лебедев
Software Design blog — http://askofen.blogspot.ru/
Re[28]: О сопровождении
От: Кирилл Лебедев Россия http://askofen.blogspot.com/
Дата: 01.06.07 14:30
Оценка:
Здравствуйте, AndrewVK, Вы писали:

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

Именно такой запутанный код и порождается продемонстрированным подходом к наследованию. Особенно, если при этом наследование производится путем вынесения общих атрибутов (здесь я пишу об атрибутах объектов в понимании OOD, а не в понимании .NET) в базовые классы или интерфейсы.

AVK>С этой точки зрения прямой зависимости между количеством классов и интерфейсов и сложностью (читай стоимостью) рефакторинга нет. Однако кое какая корреляция имеется, и она отнюдь не в пользу кода, в котором в один класс или интерфейс упихано максимальное количество аспектов.

Я писал не о количество классов/интерфейсов вообще, а о количестве классов/интерфейсов, приходящихся на одну сущность.

AVK>P.S. Кстати, а как с точки зрения твоей теории выглядит АОП? Как совсем неверный подход?

Не скажу, что много читал про АОП. Но из того, что видел, считаю: идея, как мне кажется, в правильном направлении, но реализация — нехорошая.
С уважением,
Кирилл Лебедев
Software Design blog — http://askofen.blogspot.ru/
Re[41]: ...продолжение
От: WolfHound  
Дата: 01.06.07 17:34
Оценка:
Здравствуйте, Кирилл Лебедев, Вы писали:

КЛ>"Мешанина" из интерфейсов, в числе которых есть и совершенно пустые.

Не техническая оценка.
1)Нет там никакой мешанины. Все абсолютно логично разделено на аспекты.
2)Ну и что что есть пустой интерфейс? Он необходим для однообразия иерархии. Без него получилось бы ущербно.

КЛ>Злоупотребление object'ами в качестве аргументов функции.

Нет злоупотребления ибо типизировать в данном случае не возможно.
Тем не мение сами контролы строго типизированные. Те в интерфейсах контролов нет ни одного object'а кроме случаев где оно реально надо.
А вот сами дескрипторы свойств и сботытий типизировать нельзя ибо в этом случае будет невозможно работать с ними обобщенно.

КЛ>Методы абсолютно похожи за исключением того, что в IAttachedProperty добавляется еще один аргумент. Из его названия непонятно, но, полагаю, что это контейнер (форма или что-то другое).

Именно.

КЛ>Интерфейс IProperty практически полностью повторяет класс PropertyDescriptor, интерфейс IEvent — класс EventDescriptor. Непонятно, зачем потребовалось такое дублирование интерфейсов.

За тем что в модели PropertyDescriptor/EventDescriptor нет присоеденненых свойств и событий.

КЛ>Допустим, контролы будут изменяться. Пусть свойства этих контролов тоже будут совершенно непохожие и не сводимые друг к другу. Но свойства "контролов на форме" (элементов в контейнере) будут практически одинаковыми (или совсем одинаковыми). Это объясняется тем, что форма работает с разными контролами одинаковым образом, и эти дополнительные свойства контролов (Вы их называете добавленными) создаются в ответ на нужды формы. Грубо говоря, форме надо поместить контрол в определенную область, вот он и размещается по заданному X и Y.

Нет заданных X и Y. Ну нет. Положение определяют лейауты. Причем лейауты могут быть вложенными.

КЛ>И в чем состоит назначение этой модели? Вы просто продублировали и так уже существующие классы PropertyDescriptor и EventDescriptor, при этом, наплодив дубликатов (IProperty и IAttachedProperty, IEvent и IAttachedEvent). И реализовали установку и получение свойства при помощи рефлексии. Классов много, а функциональность — одна. Стоит ли игра свеч?

Еще раз. Нет дублирования. Ну нету. Это разные сущьности и обрабатывать их нужно по разному.
Что касается PropertyDescriptor и EventDescriptor то я их использую для того чтобы не писать самому PropertyGrid. Но коллекции из этих дескрипторов я формирую сам на основе своей модели производя связывание первого аргумента методов присоедененных совойств и присоедененных событий. Связывание происходит на лету при редактировании. Иначе просто нельзя получить актуальный список присоедененных свойств и событий.

КЛ>С этим никто и не спорит. Но Вы привели общую цель. А для того, чтобы ее можно было достичь, нужно конкретизировать задачи, которые и возникают из-за различий между win и web forms. Каждую задачу желательно сопроводить поясняющим примером.

Ради флейма я большую статью, а то и небольшую книгу не осилю.

КЛ>Кстати, способность к конкретизации (при описании задач и решений) — одно из необходимых качеств архитектора, а, конечно, не количество знаемых языков программирования. Ибо архитектор и проектировщик занимаются постановкой и решением (концептуальных) задач, а не кодированием алгоритмов.

Этим занимаются бла-бла-бла архитекторы. Правильные архитекторы обязанны писать код иначе они отрываются от реальности и начинают пороть всякую чушь.

КЛ>О какой модели идет речь? Вы просто написали читалку и сохранялку свойств с использованием отражения. Извините, но даже в статьях на RSDN.ru и gotdotnet.ru описываются способы, как это можно сделать гораздо проще. Без того, чтобы плодить кучу интерфейсов.

А там описываются присоедененные свойства? Нет? Ай какая неприятность...

КЛ>Не получится, ну и ладно. В конце-концов, у меня возможность обобщения лэйаутов указывается в качестве дополнительной.

А у меня одна из основных задач это возможность добавить любой лейаут и любой контрол не модифицируя остальной код. Ибо модификация это очень дорого.
Те будет написан только новый лейаут или компонент. Все остальное затронуто не будет.

КЛ>Но, мне кажется, если постараться, то такое обобщение создать можно. Надо просто разобраться в разных видах лэйаутов.

Их бесконечное колличество. И они зависят исключительно от фантации заказчиков.

WH>>Дык всеже в чем притензия к совершенно тривиальному коду?

КЛ>В нарушении LSP.
Далось тебе это LSP. Конкретные проблемы назвать можешь?

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

Еще раз. архитекторы, кодеры итп это все базворды.
Есть программисты и те кто под них косят.
Так вот архитекторы которые не думают о том как то что они придумали отобразить в коде относятся ко второй группе ибо рожают уродцев которых в коде не воплотить.
Также нужно понимать что разные языки приводят к разным архитектурним решениям.
Даже C# и C++ не смотря на то что очень похожи приводят к совершенно различным решениям. Те то что я буду делать на С++ я не стану делать на C# и на оборот.
Про всякие лиспы и прочие ерланги я вобще молчу. Там совершенно иная идеология.
Так вот люди которые владеют разными идеологиями могут действовать на гораздо большем пространстве решений.
Причем это помогает работать даже на языках которые напрямую не поддерживают некоторое решение ибо иногда дешевле написать интерпритатор (возможно усеченный) чем ломиться напрямую.

КЛ>С чего Вы это взяли? С того, что приведенные таблицы не содержат нужное Вам свойство? Так чего Вы хотели от чернового решения? Оно лишь дано для иллюстрации подхода.

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

КЛ>А вот в Вашем случае, формы, созданные по той же "тултипной" технологии, станут просто несопровождаемыми из-за хаотичной зависимости между контролами. Сопровождающий программист просто запарится определять, какие свойства добавляет какой компонент. Конечно, в том случае, когда таких компонентов не 2 — 3, а 10 — 20.

Он вобщето пользуется редактором. А редактор железный. Ему хоть 2, хоть 22, хоть 22222.
... << RSDN@Home 1.2.0 alpha rev. 673>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[29]: О сопровождении
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 01.06.07 20:00
Оценка: 20 (2) +1
Здравствуйте, Кирилл Лебедев, Вы писали:

КЛ>Именно такой запутанный код и порождается продемонстрированным подходом к наследованию. Особенно, если при этом наследование производится путем вынесения общих атрибутов (здесь я пишу об атрибутах объектов в понимании OOD, а не в понимании .NET) в базовые классы или интерфейсы.


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

КЛ>Я писал не о количество классов/интерфейсов вообще, а о количестве классов/интерфейсов, приходящихся на одну сущность.


Сущность понятие растяжимое. Собственно, их количество зависит от проведенной декомпозиции. Это во-первых. А во-вторых частенько в программу вносятся синтетические сущности, нацеленные как раз на упорядочивание кода и облегчение поддержки. Ты там вроде GoF поминал. Посмотри — сколько паттернов как раз и порождают такие сущности. Визитор к примеру. Ты же не будешь спорить с тем, что код с визитором на десятках типов узлов будет легче поддерживать, нежели рукопашную диспетчеризацию свитчем? Или будешь?

AVK>>P.S. Кстати, а как с точки зрения твоей теории выглядит АОП? Как совсем неверный подход?

КЛ>Не скажу, что много читал про АОП.

Плохо. Я серьезно. Это не значит что АОП рулез неимоверный, но если уж решил заниматься дизайном приложений, один из способов изоляции аспектов приложения (читай снидения связности) хотя бы в общих чертах представлять надо.

КЛ> Но из того, что видел, считаю: идея, как мне кажется, в правильном направлении, но реализация — нехорошая.


Я не про реализацию, а про идею как раз. Если она для тебя хорошая, то как тогда быть с тем фактом что вынесение аспектов в изолируемые элементы увеличивает "количество классов/интерфейсов, приходящихся на одну сущность"? Причем заметно так увеличивает.
... << RSDN@Home 1.2.0 alpha rev. 675 on Windows Vista 6.0.6000.0>>
AVK Blog
Re[41]: ...продолжение
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.06.07 22:09
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Андрюш, дело в том что твой собеседник вобще не понимает что такое КОП. Соотв. и решение, направленное на поддержку этого самого КОП он воспринять просто не в состоянии. И получается разговор слепого с глухим.


Одним словом Блаб в области КОП. Единственно разумное решение дать ссылки на хороший материал по КОП.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[31]: ...продолжение
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.06.07 22:09
Оценка:
Здравствуйте, aka50, Вы писали:

Это... ты бы взял за основу преведенную статью и написал бы для нашего сайта по-русски обо всем об этом. А?
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[30]: О сопровождении
От: Кирилл Лебедев Россия http://askofen.blogspot.com/
Дата: 03.06.07 12:07
Оценка: -2
Здравствуйте, AndrewVK, Вы писали:

AVK>Видишь ли, при проектировании любых систем, при любом способе декомпозиции, есть очень небольшое количество правил, которых следует при этом придерживаться в обязательном порядке. Одно из таких правил гласит, что надо максимально возможно снижать связность (coupling в англоязычной литературе) решений. Хитрость в том, как это сделать. Однозначного ответа на этот вопрос нет, но кое что за истекшее время удалось наработать.


Не смотря на то, что английский термин (coupling) упомянут Вами верно, в переводах используется другое слово — "зацепление". А вот как раз "связность" считается очень полезной. Приведу цитату:

"Двумя важными понятиями при разработке программ являются зацепление (coupling) и связность (cohesion). Связность — это мера того, насколько отдельная компонента образует логически законченную, осмысленную единицу. Высокая связность достигается объединением в одной компоненте соотносящихся (в том или ином смысле) друг с другом функций. <...>

С другой стороны, зацепление возникает, если одна программная компонента должна иметь доступ к данным (состоянию) другой компоненты. Следует избегать таких ситуаций".

Тимоти Бадд. Объектно-ориентированное программирование в действии / Пер. с англ. — СПб.: Питер, 1997. — с. 61 — 62.


Поэтому код должен быть связан (это хорошо!), но не зацеплен.

AVK>Теперь вернемся к ООП. В самой его (ООП) базе есть специальное решение, которое как раз и предназначено для уменьшения связности. Называется оно инкапсуляция. <... skip ...> Очевидно, что чем беднее и формальнее контракт, тем ниже связность. Соответственно, если мы стремимся к минимизации связности, то нужно стремится и к минимизации каждого конкретного контракта (не нарушая при этом целостности кода!).


На счет инкапсуляции никто не спорит, а вот точка зрения о том, что бедный контракт — это хорошо, на мой взгляд, является неверной. Далее при ответе я все-таки буду пользоваться терминами "зацепление" и "связанность", предполагая, что, когда Вы пишите "связанность", Вы все-таки, на самом деле, имеете в виду "зацепление" (см. выше).

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

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

Приведу пример. Для того, чтобы создать форму (в программе, а не в редакторе форм) с контролами на ней, нужно выполнить последовательность действий:

  1. Создать форму и контролы.
  2. Правильно структурировать дочерние контролы (т.е. прикрепить дочерние элементы к родительским).
  3. Правильно расположить контролы на форме и внутри других контролов.
  4. Отобразить форму и контролы.
  5. Обрабатывать команды от контролов.
  6. И т.д. (список далеко не полон).

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

Т.е. мало того, что Вам придется дублировать одни и те же алгоритмы в разных контролах (в кнопке, в списке, в радиокнопке и т.д.), так еще и изменять все эти контролы, как только понадобится поменять какой-нибудь алгоритм (скажем, layout). Даже если предположить, что если Вы layout все-таки вынесите в отдельный модуль, но будете хранить свойства, связанные с layout'ом в каждом компоненте (у WolfHound'а они называются добавленными свойствами), Вам придется изменять все контролы, как только поменяется формат данных, необходимых для layout'а.

Именно поэтому я и предложил в решении ряд моделей:

  1. Структурная модель.
  2. Визуальная модель.
  3. Топологическая модель.
  4. Динамическая модель.

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

AVK>Но есть еще и наследование, которое здесь обсуждается. Тут есть одна большая засада — дело в том, что в случае наследования в классических языках под одной крышей смешали две сущности — наследование контрактов и наследование реализаций. Второе имеет весьма опосредованное отношение к обсуждаемому вопросу. Остается наследование контрактов. Его можно использовать двояко — во-первых как некий констрейнт, заставляющий соблюдать базовые контракты при декларации соответствия наследуемому. Во-вторых как средство обеспечения полиморфизма.


Наследование — это инструмент реализации. Даже классики OOA рекомендуют его применять на последних стадиях анализа (например, тот же Дж. Рамбо). А, учитывая, что все применение наследования сводится к вынесению общих атрибутов в базовые классы, то во время анализа и на первых стадиях проектирования можно вообще успешно обойтись и без него. Например, в ряде языков программирования наследования нет вообще. Но это не мешает проектировать и писать на них хорошие программы. Т.е. я ни в коей мере не против наследования. Но просто нужно четко понимать, что наследование — это реализация.

В свете сказанного термин "наследование интерфейса" приобретает вообще какое-то мистическое значение. Интерфейс либо есть, либо его нет. Интерфейс все-таки выявляется на этапах анализа и проектирования. А вот механизм наследования выбирается на этапе реализации, т.к. повторяю, что не все языки программирования поддерживают наследование. Так что наследование интерфейса — это вообще попытка скрестить этапы проектирования и реализации.

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

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


Попробую пояснить. Во-первых, главное в моем решении — это выделение разных моделей, каждая из которых отвечает строго за определенную функциональность. Т.е. таблицы там — не главное. Они даны просто для иллюстрации внутренних данных моделей. Вот и все.

Во-вторых, я не вижу ничего страшного в том, чтобы делать расширенную модель данных, но в рамках одного функционального модуля. Это стандартный аналитический прием. Например, та же таблица Менделеева была построена по такому принципу, т.к. на момент ее построения были известны далеко не все элементы, которые в ней есть сейчас. И ничего! Действует уже более 100 лет.

Что касается Вашего беспокойства о раздувании контрактов, то у меня никакого раздувания не будет. Потому что контракты определяются не атрибутами, а тем, как используется модуль. Соответственно, и атрибуты подбираются для модуля (класса) в том и только том случае, если они нужны для реализации заданной функциональности. А как там они организованы во внутренних данных модуля — дело десятое. Наоборот, люди, которые используют наследования для разнесения атрибутов по разным классам, выносят атрибуты в контракты. А атрибуты имеют тенденцию изменяться чаще. Соответственно, при таком подходе и контракты реорганизуются чаще. Я уж не говорю вообще о том, что вместо одного контракта плодится несколько других, и вместо того, чтобы для решения одной задачи обратиться к одному интерфейсу, пользователь (тоже программист) вынужден будет обращаться к нескольким интерфейсам. Опять-таки возрастает зацепление, т.к. вместо связи 1 к одному возникает связть 1 к N, где N — количество интерфейсов.

AVK>Сущность понятие растяжимое. Собственно, их количество зависит от проведенной декомпозиции.

Можно сказать и по-другому. Группа однотипных задач должна решаться одним функциональным модулем (ну, или несколькими модулями с одинаковым интерфейсом). Т.е. интерфейс должен быть 1 на одну группу.
С уважением,
Кирилл Лебедев
Software Design blog — http://askofen.blogspot.ru/
Re[31]: О сопровождении
От: WolfHound  
Дата: 03.06.07 12:45
Оценка:
Здравствуйте, Кирилл Лебедев, Вы писали:

КЛ>Т.е. мало того, что Вам придется дублировать одни и те же алгоритмы в разных контролах (в кнопке, в списке, в радиокнопке и т.д.), так еще и изменять все эти контролы, как только понадобится поменять какой-нибудь алгоритм (скажем, layout). Даже если предположить, что если Вы layout все-таки вынесите в отдельный модуль, но будете хранить свойства, связанные с layout'ом в каждом компоненте (у WolfHound'а они называются добавленными свойствами), Вам придется изменять все контролы, как только поменяется формат данных, необходимых для layout'а.

Тут есть только один человек который предлагает засунуть все свойства и все алгоритмы во все контролы да еще и использовать одни и теже свойства для разных целей в зависимомти от фазы луны. И это не я.

hint: Присоедененные свойства они на то и присоедененные что добавляются к компоненту внешними для этого компонента средствами, а не хардкодятся в сам компонент.
... << RSDN@Home 1.2.0 alpha rev. 673>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[32]: О сопровождении
От: minorlogic Украина  
Дата: 03.06.07 13:17
Оценка: 3 (1)
Мне кажется вы выбрали плохой пример для разбра. Очевидно что у Киррила нет опыта в решении подобных задач и вы сним находитесь в разном положении. Удачнее было бы выбрать нейтральную тему и не такую объемную , чтонить попроще. А пока вглядит диалог со стороны малоконструктивно.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Ищу работу, 3D, SLAM, computer graphics/vision.
Re[33]: О сопровождении
От: WolfHound  
Дата: 03.06.07 13:37
Оценка: +1
Здравствуйте, minorlogic, Вы писали:

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

Тут все гораздо запущенней. Кирилл как ему кажется изобрел методику получения хороших решений для любых задач. Данная методика также извесна как серебренная пуля. Вот пусть и отвечает за свою серебренную пулю... Пока у него это очень плохо получается.
... << RSDN@Home 1.2.0 alpha rev. 673>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[32]: О сопровождении
От: Кирилл Лебедев Россия http://askofen.blogspot.com/
Дата: 03.06.07 14:48
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Тут есть только один человек который предлагает засунуть все свойства и все алгоритмы во все контролы

Мягко говоря, это не соответствует истине.

WH>да еще и использовать одни и теже свойства для разных целей в зависимомти от фазы луны. И это не я.

Про layout'ы я Вам уже объяснял. Жаль, что Вы не поняли. Но ничего более добавить не могу.

WH>hint: Присоедененные свойства они на то и присоедененные что добавляются к компоненту внешними для этого компонента средствами, а не хардкодятся в сам компонент.

Просто непонятно, что Вы с этими свойствами делаете. Присоединяете ли Вы их лишь виртуально — только для того, чтобы они отображались в property grid вместе с другими свойствами контрола? Или Вы их каким-то образом динамически добавляете к другим свойствам контрола и, фактически, генерируете новый код? Или эти добавленные свойства сохраняются в XML вместе с другими свойствами контрола(т.е. "добавленные свойства" добавляются только для сохранения или только для сохранения и отображения в property grid).
С уважением,
Кирилл Лебедев
Software Design blog — http://askofen.blogspot.ru/
Re[34]: О сопровождении
От: Кирилл Лебедев Россия http://askofen.blogspot.com/
Дата: 03.06.07 14:55
Оценка: +1 -1
Здравствуйте, WolfHound, Вы писали:

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

Я такого не говорил. Но ряд задач проектирования методика решает хорошо.

WH>Вот пусть и отвечает за свою серебренную пулю... Пока у него это очень плохо получается.

Я как бы и не отказываюсь разбирать задачу. Просто решение задачи — это процесс обоюдный. Я не должен уклоняться от решения, но и Вы должны отвечать на вопросы. А пока что большую часть информации я почерпнул из статей на gotdotnet.ru и rsdn.ru, а не из Ваших ответов. Конечно, Вы отвечаете на вопросы. Но полнота ответов оставляет желать лучшего.
С уважением,
Кирилл Лебедев
Software Design blog — http://askofen.blogspot.ru/
Re[31]: О сопровождении
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 03.06.07 16:37
Оценка:
Здравствуйте, Кирилл Лебедев, Вы писали:

КЛ>Не смотря на то, что английский термин (coupling) упомянут Вами верно, в переводах используется другое слово — "зацепление".


Не знаю в чьих переводах там упоминается зацепление, но в русскоязычном коммьюнити принят термин связность. Термин зацепление я от вас в первый раз слышу.

КЛ>На счет инкапсуляции никто не спорит, а вот точка зрения о том, что бедный контракт — это хорошо, на мой взгляд, является неверной.


Взгляд будет подкреплен аргументами?

КЛ> Далее при ответе я все-таки буду пользоваться терминами "зацепление" и "связанность", предполагая, что, когда Вы пишите "связанность", Вы все-таки, на самом деле, имеете в виду "зацепление" (см. выше).


Не связанность, а связность.

КЛ>Итак, согласно приведенной цитате, высокая связанность достигается группировкой в одной компоненте связанных друг с другом функций. Здесь я, конечно же, имею в виду не столько функции в смысле языка программирования, сколько бизнес-функции или задачи, ради которых и создавалась компонента. Т.е. полезно в одной компоненте группировать похожие функции, решающие однотипные задачи.


Это слишком примитивный взгляд на проблему. На практике, как всегда, все намного сложнее. Дело в том, что близость той или иной функции к другой вещь большей частью субъективная. Опять же, ровнять под одну гребенку разные ситуации нельзя. Вот к примеру метод Sort вробе бы как, на первый взгляд, неразрывно связан с коллекцией. Но, если мы сделаем его методом коллекции, нам придется реализовывать его в каждой коллекции по новой. Поэтому в данном случае более правильным было бы вынести метод Sort наружу. Тем самым мы уменьшаем сложность контракта IList, и упрощаем его реализацию. Теперь нам не надо реализовывать метод Sort в любой коллекции.
Совсем уж хорошо эта задача решается на C# 3.0, благодаря наличию в нем extension methods.
На эту тему есть статья Мейерса.
http://www.softcraft.ru/coding/sm/sm01.shtml

Я начну со следующего утверждения: Если вы пишете функцию, которая может быть выполнена или как метод класса, или быть внешней по отношению к классу, Вы должны предпочесть ее реализацию без использования метода. Такое решение увеличивает инкапсуляцию класса. Когда Вы думаете об использовании инкапсуляции, Вы должны думать том, чтобы не использовать методы.


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


В общеупотребимых терминах это называется грамотная ОО декомпозиция. Только я то совсем о другом говорил.

КЛ>Приведу пример. Для того, чтобы создать форму (в программе, а не в редакторе форм


(*)

КЛ>) с контролами на ней, нужно выполнить последовательность действий:


КЛ>

    КЛ>
  1. Создать форму и контролы.
    КЛ>
  2. Правильно структурировать дочерние контролы (т.е. прикрепить дочерние элементы к родительским).
    КЛ>
  3. Правильно расположить контролы на форме и внутри других контролов.
    КЛ>
  4. Отобразить форму и контролы.
    КЛ>
  5. Обрабатывать команды от контролов.
    КЛ>
  6. И т.д. (список далеко не полон).
    КЛ>

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

КЛ>Такой код обладает низкой связанностью и высоким зацеплением.

Ты это к чему?

КЛ>если Вы layout все-таки вынесите в отдельный модуль, но будете хранить свойства, связанные с layout'ом в каждом компоненте (у WolfHound'а они называются добавленными свойствами)


У WH добавленые свойства храняться в владельце этих свойств, а не в тех, к кому они присоединены. В (*) ты заявил, что речь не идет о дизайнере форм. А теперь сослался на пример WH, который как раз разработан прежде всего для поддержки дизайнера. И присоединенность свойств фигурирует там в дизайнере (и при сериализации). В рантайме никаких присоединенных свойств нет, все работает через штатные типизированные интерфейсы. Т.е. в примере с лейаутами в дизайнере мы будем иметь:
    class:Form
        prop:Id = _form
        prop:Layout = Absolute
        class:Button
            prop:Text = O La La
            prop:Location@_form = 10; 10
            prop:Size@_form = 60; 15

А то же самое в коде будет таким:
Form _form = new Form();
_form.Id = "_form";
_form.Layout = new AbsoluteLayout();
Button b = new Button();
b.Text = "O La La";
_form.SetLocation(b, new Point(10, 10));
_form.SetSize(b, new Size(60, 15));

Идея ясна?

КЛ>, Вам придется изменять все контролы, как только поменяется формат данных, необходимых для layout'а.


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

AVK>>Но есть еще и наследование, которое здесь обсуждается. Тут есть одна большая засада — дело в том, что в случае наследования в классических языках под одной крышей смешали две сущности — наследование контрактов и наследование реализаций. Второе имеет весьма опосредованное отношение к обсуждаемому вопросу. Остается наследование контрактов. Его можно использовать двояко — во-первых как некий констрейнт, заставляющий соблюдать базовые контракты при декларации соответствия наследуемому. Во-вторых как средство обеспечения полиморфизма.


КЛ>Наследование — это инструмент реализации.


Ты внимательно прочел, что я написал?

КЛ>А, учитывая, что все применение наследования сводится к вынесению общих атрибутов в базовые классы


А как же полиморфизм?

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


Без наследования реализаций или без наследования контрактов?

КЛ>Если же подойти с чисто практической точки зрения, то "наследование интерфейса" позволяет навесить одной компоненте несколько разных функциональностей.


Нет. Ты опять забыл про полиморфизм.

КЛ>Попробую пояснить. Во-первых, главное в моем решении — это выделение разных моделей, каждая из которых отвечает строго за определенную функциональность. Т.е. таблицы там — не главное. Они даны просто для иллюстрации внутренних данных моделей. Вот и все.


КЛ>Во-вторых, я не вижу ничего страшного в том, чтобы делать расширенную модель данных, но в рамках одного функционального модуля. Это стандартный аналитический прием. Например, та же таблица Менделеева была построена по такому принципу, т.к. на момент ее построения были известны далеко не все элементы, которые в ней есть сейчас. И ничего! Действует уже более 100 лет.


Мда. Вот я тебе честно скажу — я архитектора, который изъясняется подобным образом, сразу бы уволил. Куча текста ни о чем.

КЛ>Что касается Вашего беспокойства о раздувании контрактов, то у меня никакого раздувания не будет.


Оно у тебя в твоем примере уже есть. Ты влепил в базовый контрол свойства, специфичные для конкретного лейаута. Завтра появится еще один, со своими свойствами, послезавтра еще один. И понеслась. В ходе эволюции интерфейс базового контрола раздуется. И что самое плохое — отрефакторить такой код будет весьма сложно, потому что на базовые контракты завязано, как правило, очень много кода (реализации).

КЛ> Потому что контракты определяются не атрибутами, а тем, как используется модуль.


Бред какой то. Контракты определяются требованиями. Атрибуты и методы это составляющие части ОО-контракта.

КЛ>Наоборот, люди, которые используют наследования для разнесения атрибутов по разным классам, выносят атрибуты в контракты.


У тебя опять мешанина между наследованием реализаций и контрактов. Если атрибуты не находятся в публичных контрактах, то вынесение их в базовый класс и наследование этой реализации никоим образом не влияет на публичный контракт. Если же атрибуты изначально находятся в контрактах, то они в контрактах и остаются после выделения базового контракта.
... << RSDN@Home 1.2.0 alpha rev. 675 on Windows Vista 6.0.6000.0>>
AVK Blog
Re[32]: О сопровождении
От: Кирилл Лебедев Россия http://askofen.blogspot.com/
Дата: 03.06.07 18:33
Оценка:
КЛ>>Приведу пример. Для того, чтобы создать форму (в программе, а не в редакторе форм

AVK>(*) <skip>


AVK>У WH добавленые свойства храняться в владельце этих свойств, а не в тех, к кому они присоединены. В (*) ты заявил, что речь не идет о дизайнере форм. А теперь сослался на пример WH, который как раз разработан прежде всего для поддержки дизайнера. И присоединенность свойств фигурирует там в дизайнере (и при сериализации). В рантайме никаких присоединенных свойств нет, все работает через штатные типизированные интерфейсы. Т.е. в примере с лейаутами в дизайнере мы будем иметь:


Тут Вы не поняли. В (*) я говорил о последовательности операций, которые совершаются при появлении формы. А поскольку термин "создание формы" может использоваться, когда хотят показать процесс создания формы в дизайнере, и когда хотят показать процесс создания формы (окна, диалога) в программе, то я конкретизировал.

Что касается WH, то мне лично было непонятно, для чего нужно добавлять дополнительные свойства. Теперь понял, что для дизайнера. Изначально (из первого описания задачи) я представлял, что интерфейсы отвечают за сохранение форм и контролов на них с добавленными свойствами в файлах разных форматах (например, в XML, и этот XML где-то дальше используется). Если бы мне задачу описали по-другому, например так:

Имеется PropertyGrid, который работает со свойствами редактируемого объекта. Необходимо сделать так, чтобы PropertyGrid работал и со свойствами, которые свойствами объекта не являются.

Тогда бы все стало ясно.

На остальное отвечу позже.
С уважением,
Кирилл Лебедев
Software Design blog — http://askofen.blogspot.ru/
Re[33]: О сопровождении
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 03.06.07 19:18
Оценка:
Здравствуйте, Кирилл Лебедев, Вы писали:

КЛ>Теперь понял, что для дизайнера.


И для сериализации в человекочитаемом виде.

КЛ> Изначально (из первого описания задачи) я представлял, что интерфейсы отвечают за сохранение форм и контролов на них с добавленными свойствами в файлах разных форматах


И это тоже.

КЛ>[i]Имеется PropertyGrid


PropertyGrid тут совсе не причем. То, что ты не можешь абстрагироваться от конкретных контролов при описании задачи не есть гуд.
... << RSDN@Home 1.2.0 alpha rev. 675 on Windows Vista 6.0.6000.0>>
AVK Blog
Re[34]: О сопровождении
От: WolfHound  
Дата: 03.06.07 19:58
Оценка:
Здравствуйте, AndrewVK, Вы писали:

КЛ>>Теперь понял, что для дизайнера.

AVK>И для сериализации в человекочитаемом виде.
Это частности. Главное это вынесение из контрактов контролов то чего там быть не должно.
А сериализация с пропертигридом это уже детали реализации и их можно прицепить практически к любой модели.
... << RSDN@Home 1.2.0 alpha rev. 673>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.