Оберон-технология: особенности и перспективы |
Тематика обсуждения: Оберон-технология. Особенности, перспективы, практическое применение.
Всего в теме 6256 сообщений
Добавить свое сообщение
Отслеживать это обсуждение Обсуждение из раздела Школа ОБЕРОНА
№ 2736 15-02-2007 18:49 | |
Ответ на »сообщение 2735« (Сергей Перовский)
___________________________
Но она позволяет НЕ делать. А конструктор нет.
Ошибаетесь.
Если не экспортировать за пределы модуля класс, а только интерфейс, то создать класс будет невозможно.
Придется для этого пользоваться специально написанной и доступной снаружи функцией - фабрикой.
Так что добиться того же что и конструктор (в том числе и запрета лазейки) можно.
Но все это надо делать ручками.
ТО есть каждый раз создавать тот самый механизм от которого отказались :))
AVC: Т.е. она одновременно проще и гибче конструктора.
Ошибаетесь. Если бы это было так то эту вот общую задачу корректной инициализации обьектов можно было бы как нибудь выделить в виде библиотечной функции.
Но поскольку этого сделать нельзя, то приходится довольствоваться design pattern - то есть рассказами "бывалых" как это надо ПРАВИЛЬНО делать в каждом конкретном случае. А это и есть самое прямое указание на ущербность, ограниченность подхода.
О том что такое такой вот набор design patterns "грамотного проектирования" в ОО языках, разговор на ветке ФП уже был.
№ 2735 15-02-2007 18:24 | |
Ответ на »сообщение 2734« (AVC)
___________________________
>>>Фабричная процедура позволяет делать ровно то же самое, что и конструктор
Мы не про то. Конечно позволяет.
Но она позволяет НЕ делать. А конструктор нет.
>>>класс = тип + модуль
Это я не понимаю. Термин модуль используется в значениях единицы текста, единицы трансляции, единицы загрузки. Ни под один из этих смыслов класс не попадает. Специальный тип данных, не более.
№ 2734 15-02-2007 17:56 | |
Ответ на »сообщение 2732« (Сергей Перовский)
___________________________
В нормальном ООП ее и нет. Мимо конструктора не проскочишь.
Фабричная процедура позволяет делать ровно то же самое, что и конструктор: гарантировать выполнение инвариантов при создании объекта.
При этом, в отличие от конструктора, она остается обыкновенной подпрограммой, способной к тому же выполнять обязанности "виртуального конструктора" (на что конструктор не способен).
Т.е. она одновременно проще и гибче конструктора.
(Об этом, кстати, написано и в документации ББ.)
ИМХО, основная причина усложненности конструкторов коренится в концепции класса. В соответствии с традиционным взглядом на ООП, класс = тип + модуль. Вот эта "модульность класса" и проступает в сложности конструктора.
№ 2733 15-02-2007 16:58 | |
Ответ на »сообщение 2729« (Илья Ермаков)
___________________________
Ах вот вы о чем. Надо было сразу пример приводить :))
То есть вы предлагаете всем научиться ЗАМЕНЯТЬ отсутствие конструктора в обероне "грамотным проектированием".
Правильное предложение. Когда механизма нет - его приходится создавать самому. Когда нет конструкторов, их приходится эмулировать фарбриками. Эмулировать ручками и всем говорить насколько это НЕОБХОДИМО делать. Насколько это является ГРАМТОНЫМ и единственно правильным с точки зрения проектирования ОО систем.
Точно также можно например эмулировать сборку мусора.
Обязать всех писать обьекты так, что каждый обьект имеет свойтсво Parent.
И когда какой нибудь обьект явно уничтожается (Free) то он обязан также пройтись по всему списку обьектов у которых Parent это он, и уничтожить также и их.
Грамотное решение...в условиях отсутствия сборщика мусора.
Обьявить этот прием "грамотным проектированием" и после чего можно сразу переходить к вашей коронной фразе
Грамотное проектирование решает все проблемы.
№ 2732 15-02-2007 16:26 | |
Ответ на »сообщение 2729« (Илья Ермаков)
___________________________
>>>В нормально "сделанном" модуле просто не должно быть иной возможности
В нормальном ООП ее и нет. Мимо конструктора не проскочишь.
Эмулируя ООП при помощи расширяемых записей мы перекладываем это ограничение с компилятора на "культуру программиста".
Тут я с JOS солидарен.
Описатель класса с его методами в ООП и есть фабрика класса. Абсолютно объязательная к созданию и употреблению. Пользователей Оберона придется убедить в ее необходимости, а в Дельфи другого пути просто нет.
Разве что эмулировать объекты при помощи записей.
№ 2731 15-02-2007 16:16 | |
Ответ на »сообщение 2730« (Илья Ермаков)
___________________________
А вообще - описанная концепция абстрактного типа данных стара как мир, народ либо не читает классику, либо не видит ничего дальше мейнстрима типа Явы/Сей, где ООП, типизация и модульность превращены в безграмотный неудобоваримый суррогат...
№ 2730 15-02-2007 16:14 | |
Ответ на »сообщение 2729« (Илья Ермаков)
___________________________
Пардон, надо читать:
PROCEDURE NewAdder* (left, right: INTEGER): Adder;
VAR a: StdAdder;
BEGIN
NEW(a);
a.left := left; a.right := right;
RETURN a
END Adder;
Время позднее, мозги слипаются :-)
По поводу инсталлируемых фабрик читайте "Некоторые идеи архитектуры Оберон-систем" на OberonCore.
№ 2729 15-02-2007 16:12 | |
Ответ на »сообщение 2726« (Jack Of Shadows)
___________________________
Ответ на »сообщение 2724« (Илья Ермаков)
___________________________
1) Семантика Adder такова, что Left и Right устанавливаются один раз на всю его жизнь. Тогда это делает обязательная фабричная процедура.
О точ и речь. Какая обязательная ? Кто программиста обяжет ?
Конструктор класса ? Так нет его в обероне.
Интерфейс ? Так не прописана в интерфейсах "обязанность" вызывать те или иные процедуры.
Кто помешает программисту взять да и вызвать GetSum не устанавливая Left и Right ?
Кто обяжет? В нормально "сделанном" модуле просто не должно быть иной возможности создать экземпляр такого типа, нежели через фабрику - о чем я тут уже столько толкую... Экспортируется наружу только абстрактный базовый интерфейс, который не может быть инстанционирован... Конкретный тип скрыт внутри модуля. Создать его экземпляр можно только фабрикой, которая выполнит всю требуемую инициализацию и отдаст его как указатель на абстрактный интерфейс.
MODULE Adders;
TYPE
Adder* = POINTER TO ABSTRACT RECORD END;
StdAdder = POINTER TO RECORD (Adder)
left, right: INTEGER
END;
PROCEDURE (a: Adder) Sum* (): INTEGER, NEW, ABSTRACT;
PROCEDURE (a: StdAdder) Sum (): INTEGER;
BEGIN
RETURN a.left + a.right
END Sum;
PROCEDURE NewAdder* (): Adder;
VAR a: StdAdder;
BEGIN
NEW(a);
RETURN a
END Adder;
END Adders.
На самом деле в большинстве случаев идут еще дальше и используют не статическую процедуру-фабрику, а динамически инсталлируемый объект-фабрику, тогда реализацию можно прозрачно для всех клиентов подменять прямо во время выполнения.
Это аргумент функциональщика в пику обьектам. Вы правы, обьекты на черта не нужны.
В данном случае - не нужны. В других - нужны. В ФП полиморфизм обеспечивается своими методами, в ИП - своими. В ФП понятие интерфейсов вводится своими методами, в ИП - своими. ФП объектно-ориентировано и без явного наличия ООП - я прекрасно это понимаю.
№ 2728 15-02-2007 15:42 | |
Ответ на »сообщение 2724« (Илья Ермаков)
___________________________
Грамотное проектирование решает все проблемы.
О, знаменитая обероновская отмазка от всего и вся! - "Грамотное проектирование".
Везет вам обероновцам. Так ведь можно любые споры заканчивать :))
№ 2727 15-02-2007 15:40 | |
Ответ на »сообщение 2726« (Jack Of Shadows)
___________________________
Очепятка:
Но при этом эта процедура - НЕ конструктор класса.
Добавить свое сообщение
Отслеживать это обсуждение
Дополнительная навигация: |
|