Rambler's Top100
"Knowledge itself is power"
F.Bacon
Поиск | Карта сайта | Помощь | О проекте | ТТХ  
 Базарная площадь
  
О разделе

Основная страница

Группы обсуждений


Тематический каталог обсуждений

Архив

 
 К н и г и
 
Книжная полка
 
 
Библиотека
 
  
  
 


Поиск
 
Поиск по КС
Поиск в статьях
Яndex© + Google©
Поиск книг

 
  
Тематический каталог
Все манускрипты

 
  
Карта VCL
ОШИБКИ
Сообщения системы

 
Форумы
 
Круглый стол
Новые вопросы

 
  
Базарная площадь
Городская площадь

 
   
С Л С

 
Летопись
 
Королевские Хроники
Рыцарский Зал
Глас народа!

 
  
ТТХ
Конкурсы
Королевская клюква

 
Разделы
 
Hello, World!
Лицей

Квинтана

 
  
Сокровищница
Подземелье Магов
Подводные камни
Свитки

 
  
Школа ОБЕРОНА

 
  
Арсенальная башня
Фолианты
Полигон

 
  
Книга Песка
Дальние земли

 
  
АРХИВЫ

 
 

Сейчас на сайте присутствуют:
 
  
 
Во Флориде и в Королевстве сейчас  01:46[Войти] | [Зарегистрироваться]
Обсуждение темы:
Оберон-технология: особенности и перспективы


Тематика обсуждения: Оберон-технология. Особенности, перспективы, практическое применение. 

Количество сообщений на странице

Порядок сортировки сообщений
Новое сообщение вверху списка (сетевая хронология)
Первое сообщение вверху списка (обычная хронология)

Перейти на конкретную страницу по номеру


Всего в теме 6256 сообщений

Добавить свое сообщение

Отслеживать это обсуждение

Обсуждение из раздела
Школа ОБЕРОНА

<<<... | 3576—3567 | 3566—3557 | 3556—3547 | ...>>>
Всего сообщений в теме: 6256; страниц: 626; текущая страница: 270


№ 3566   26-03-2007 18:27 Ответить на это сообщение Ответить на это сообщение с цитированием
Ответ на »сообщение 3565« (AVC)
___________________________
Можно и базывый класс конечно.
А вообще механизм навешивания аспектов чрезвычайно гибок.
Можно например по wildcard то есть по шаблонам имени класа или поля/метода
например
pontcut sql_*.* AspectLogDaabaseActivity

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

За счет чего? Рефлексии?
А нельзя ли тогда за ее счет и обойти этот аспект?


В смысле ? Самому себе подножку поставить ?
Эт вряд ли :)) Разве что вы каким то образом умубритесь переделать правила reflections в системе.
То есть случайно поломать или забыть чо то сделать не получится, даже если очень постараться.

Ну а если специально, и у злоумышленника ТАКОЙ доступ к системе, то там уже неважно аспекты у вас или еще что :))



№ 3565   26-03-2007 18:16 Ответить на это сообщение Ответить на это сообщение с цитированием
Ответ на »сообщение 3562« (Jack Of Shadows)
___________________________

>>>Ну звездочку там не обязательно ставить. Можно имя конкретного класса. Можно даже список конкретных классов и их полей.

А можно указать полный список всех потомков? :)
Или достаточно указать базовый класс, а потомки "подключатся" автоматически?

>>>Аспекты например вы можете навесить на классы чьих исходников у вас нет.

За счет чего? Рефлексии?
А нельзя ли тогда за ее счет и обойти этот аспект?
 AVC


№ 3564   26-03-2007 18:07 Ответить на это сообщение Ответить на это сообщение с цитированием
Ответ на »сообщение 3563« (Илья Ермаков)
___________________________
Прошу прощения, время позднее :-)
Конечно, тип EmpWrapper - он не "просто так", а содержит обернутый Employee:
EmpWrapper = POINTER TO RECORD (Employees.Employee)
  emp: Employees.Employee
END,
а EmpDirectory содержит предыдущий (базовый с ее точки зрения) каталог:
EmpDirectory = POINTER TO RECORD (Employees.Directory)
  baseDir: Employees.Directory
END
- и в нужные моменты они делегируют свои вызовы базовым версиям...


№ 3563   26-03-2007 18:00 Ответить на это сообщение Ответить на это сообщение с цитированием
Ответ на »сообщение 3560« (Jack Of Shadows)
___________________________
Кстати... Пораскинув мозгами, понимаю, что проблемка-то и правда из серии надуманных :-) Сначала в мейнстримовском ООП на нее налетели, а потом плодят "припарки", чтобы ее обходить.

Хотя - терминология "аспект" хорошая, как и сама задача раздельной реализации аспектов поведения.
Итак - суть задачи: у нас есть некоторый класс, реализующий основную логику. Нам нужно иметь возможность "снаружи", не трогая его реализации, добавить к его методам какую-то пред/пост-логику, аспект в поведении, при этом прозрачно для всех клиентов.
Фактически, аспект - это "обертка" на базовый класс. И реализовать его можно было бы как класс-обертку, который выполняет аспекты поведения, а затем делегирует вызов обернутому классу. Но - увы, проблема в том, что при этом в стандартной ОО-парадигме клинетский код потребуется переделывать, чтобы он начал работать с оберткой вместо исходного класса... А если аспектов-оберток много - ёёёлки-палки :-)
Что у нас есть? Напишу на Обероне, но так, как принято сразу "лабать" в мейнстриме:
MODULE Employees;

  TYPE
    Employee* = POINTER TO RECORD ... END;
 
  PROCEDURE (e: Employee) SSN* (): SSN;
  BEGIN
    ...
  END SSN;

END Employees.

Итак, быстренько слабали класс, открыли его реализацию для прямого использования/наследования, пользуемся из всех других модулей системы, радуемся. И вдруг нам приспичило добавить в систему поддержку безопасности. Модуль Protect, к примеру. Казалось бы - чего проще: напишем обертку - класс-наследник Protect.Employee, который добавит к базовому Employee необходимый аспект поведения. Увы, увы - добавить-то добавит, но вот сотни модулей системы заставить учитывать нововведенный аспект будет весьма трудно. Во-первых, все они работают прямо с классом Empoyees.Employee. Во-вторых - даже если перепишем-перенаправим код на новую обертку - а если оберток несколько? А если в системе уже наплодились десятки классов - наследников Employye?

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

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

MODULE Employee;
 
  TYPE
    Employee* = POINTER TO ABSTRACT RECORD END;
    (* абстрактный интерфейс - экспортирован *)
    Directory* = POINTER TO ABSTRACT RECORD END;
    (* абстрактная фабрика-каталог *)

    StdEmployee = POINTER TO RECORD (Employee) ... тут все нутро ... END;
    (* базовая реализация - скрыта внутри модуля, снаружи недоступна *)
    StdDirectory = POINTER TO RECORD (Directory) END;
    (* скрытая фабрика-каталог для реализации по умолчанию *)
 
  VAR
    dir-: Directory;

  PROCEDURE (e: Employee) SSN* (): SSN, NEW, ABSTRACT;
  PROCEDURE (d: Directory) NewEmployee* (): Employee, NEW, ABSTRACT;

  PROCEDURE (e: StdEmployee) SSN* (): SSN;
  BEGIN
    ... RETURN чего-то там...
  END SSN;

  PROCEDURE (d: StdDirectory) NewEmployee (): Employee;
    VAR e: StdEmployee;
  BEGIN
    NEW(e); ...инициализируем e...
    RETURN e
  END NewEmployee;

  PROCEDURE SetDir* (d: Directory);
  BEGIN
    dir := d
  END SetDir;

  PROCEDURE Init;
    VAR d: StdDirectory;
  BEGIN
    NEW(d); dir := d
  END Init;

BEGIN
  Init
END Employees.

Все, немного потрудившись над модулем Employees и проделав дополнительную работу, можем теперь пожинать самые разные плоды.
Клиенты создают новых Employee вызовом Employees.dir.NewEmployees, при этом не знают, какая конкретно реализация Employees и какая реализация dir используется, их дело - знать только абстрактный интерфейс (кстати, к вопросу о старом споре - обойти обязательную инициализацию они тоже не могут. Никак. И без всяких конструкторов).
Поскольку реализация сокрыта, то можем ее очень легко подменять (о чем ранее говорилось) - просто переустановив свой dir вызовом SetDir.

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

MODULE Protect;
 
  IMPORT Employees;
 
  TYPE
    EmpWrapper = POINTER TO RECORD (Employees.Employee) END;
    EmpDirectory = POINTER TO RECORD (Employees.Directory) END;

  PROCEDURE (w: EmpWrapper) SSN (): SSN;
  BEGIN
    ... узнали через метамеханизмы, кто нас вызвал или что еще там...
    RETURN фильтрованный SSN
  END SSN;
 
  PROCEDURE (d: EmpDirectory) NewEmployee (): Employees.Employee;
    VAR e: EmpWrapper;
  BEGIN
    NEW(e); ... RETURN e
  END NewEmployee;

  PROCEDURE InstallProtection;
    VAR ed: EmpDirectory;
  BEGIN
    NEW(ed); Employees.SetDir(ed)
  END InstallProctection;

BEGIN
  InstallProtection
END Protect.

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




№ 3562   26-03-2007 17:46 Ответить на это сообщение Ответить на это сообщение с цитированием
Ответ на »сообщение 3561« (AVC)
___________________________
Происхождение от общего класса как бы обеспечивает выполнение закона тождества во избежание хитрых софизмов. :)


Ну звездочку там не обязательно ставить. Можно имя конкретного класса. Можно даже список конкретных классов и их полей.

В ББ существуют так называемые методы только-для-реализации (implement-only).

Вот и попались. :)) То есть класс данных ДОЛЖЕН знать о том что его будут проверять, и предоставить соответствующие точки проверки пусть и через implement-only.
А это уже leaking abstractions.

В случае с аспектами классы с данными знать ничего не знают ни о каких SecureSSN и вообще ни о каких правилах доступа, даже просто как о точках подцепления к ним (implement-only)

Аспекты например вы можете навесить на классы чьих исходников у вас нет.
А как быть в вашем случае в обероне, если автор классов не удосужился предоставить точки implement-only? а исходников у вас нет ? Приехали.

Короче задача в любом случае решается. Просто в одном случае легко и просто. А в другом с массой оговорок, условий итд итп.



№ 3561   26-03-2007 17:36 Ответить на это сообщение Ответить на это сообщение с цитированием
Ответ на »сообщение 3560« (Jack Of Shadows)
___________________________

Теперь понятно.
Спасибо!

Далее, что удобно, так это то что тот же самый аспект будет вызываться и на другом обьекте у которого тоже есть поле SSN, Например Client.SSN
Хотя ни Client ни Employee не наследуют от общего предка.


То-то некто удивится, если в его случае (например, для того же Client) SSN означает совсем другое! :)

Результат: Проверка доступа в классах данных отсутствует.
Проверка доступа в коде вывода информации отсутствует.
Обойти (случайно забыть) это поверку невозможно.
повтороно использовать эту проверку в других обьектах где требуется та же функцинальность - запросто.


Собственно, аналогично.
Единственная разница -- требуется происхождение от общего базового класса.
Что, IMHO, более правильно.
Или есть какой-то непреодолимый закон природы, что SSN всегда имеет один и тот же смысл?
Происхождение от общего класса как бы обеспечивает выполнение закона тождества во избежание хитрых софизмов. :)

Ну а теперь раз "за сценой" прояснилось, поведайте нам как вы сделаете это при помощи оберона.

(Озадаченно.) Да я как бы уже рассказал...
 AVC


№ 3560   26-03-2007 17:11 Ответить на это сообщение Ответить на это сообщение с цитированием
Ответ на »сообщение 3559« (AVC)
___________________________
Что означает "за сценой" в предложении
За сценой означает описано в аспекте.
У вас есть класс Employee с множеством полей, одно из которых SSN.

Делаете аспект SecureSSN в котором описываете логику доступа и возвращаемые данные.

acpect SecureSSN
  bla bla
  ...
end

Навешиваете его на поле SSN:

pointcut before *.SSN SecureSSN

То есть перехватывать перед обращением к ЛЮБОМУ (*) обьекту с полем SSN

Все. После этого везде где в коде будет встречаться thisEmployee.SSN аспект будет перехватывать обращение и заменять данные согласно правилам доступа.

Далее, что удобно, так это то что тот же самый аспект будет вызываться и на другом обьекте у которого тоже есть поле SSN, Например Client.SSN
Хотя ни Client ни Employee не наследуют от общего предка.

Результат: Проверка доступа в классах данных отсутствует.
Проверка доступа в коде вывода информации отсутствует.
Обойти (случайно забыть) это поверку невозможно.
повтороно использовать эту проверку в других обьектах где требуется та же функцинальность - запросто.

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

Ну а теперь раз "за сценой" прояснилось, поведайте нам как вы сделаете это при помощи оберона.


№ 3559   26-03-2007 17:01 Ответить на это сообщение Ответить на это сообщение с цитированием
Ответ на »сообщение 3557« (Jack Of Shadows)
___________________________

ПРИМЕР в студию!
Что вы предлагаете ? Пометить поле SSN как implement only ? И ? Чего вы этим добьетесь ?
Того что программист создаст метод класса, в котором будет проверять доступ пользователя к данным ?
Чем это отличается от способа номер 1, который я уже приводил, то есть забить код проверки доступа прямо в класс, хранящий данные?


Jack, я тоже не понял Ваших объяснений, зачем кипятиться? :)
Что означает "за сценой" в предложении
Просто при каждом обращении к полю SSN, за сценой вызывается функция проверки доступа, которая перехватывает чтение поля, и заменяет данные в соответствии с правами доступа.?
Пока это остается "под ковром" рано, IMHO, говорить о красоте и модульности.
Давайте будет потихоньку разбираться.

В ББ существуют так называемые методы только-для-реализации (implement-only).
Их можно вызывать только из того модуля, в котором они были определены (там где этот метод был объявлен впервые с пометкой NEW), а (пере)определять -- в потомках типа, уже где угодно (если метод допускает переопределение).
Совершенно необязательно, чтобы проверка SSN находилась в типе, содержащем указанный метод-для-реализации. Этим данный пример отличается от Вашего первого случая.
Проверка может происходить при вызове, а сам тип данных с информацией об этом знать не будет.
Какой-нибудь конкретный пример кода Вам лучше привел бы Илья Ермаков, прочитавший большое число модулей ББ, т.к. идея, кажется, вполне ясна, а сам я (в силу специфики своей деятельности ) почти всегда склоняюсь к более низкоуровневым средствам, нежели используемые в ББ.

В принципе, должно быть примерно так. Тип, содержащий данные о SSN, имеет метод GetSSN-, помеченный как implement-only (т.е. дефисом вместо звездочки).
Вызывать же его можно из какой-нибудь функции в модуле, где GetSSN объявлен впервые.
В этой функции, в зависимости от настройки системы, можно проверять и права доступа, и еще что-нибудь.
 AVC


№ 3558   26-03-2007 16:58 Ответить на это сообщение Ответить на это сообщение с цитированием
Ответ на »сообщение 3552« (Jack Of Shadows)
___________________________
Одно из возможных решений - просто разбить единый класс "данные" на три отдельных, применив парадигму Носитель-Курьер-Проектор (Carrier-Rider-Mapper), которая часто прмиеняется в ББ.
Данные сами по себе. Работать с ними можно только через курьер, который знает, как с ними работать. На верхнем уровне курьер оборачивается в требуемый проектор.

Хотя в некотором смысле аспекты могут быть удобны. Только для этого совершенно не нужно расширять язык, достаточно использовать метапрограммирование...
Концепцию, перекликающуюся с аспектами, но немного иной направленности, я делал в Active BlackBox - механизм автоагрегации деталей (см. http://oberoncore.ru/index.php?option=com_content&task=blogcategory&id=14&Itemid=10).


№ 3557   26-03-2007 16:27 Ответить на это сообщение Ответить на это сообщение с цитированием
Ответ на »сообщение 3556« (AVC)
___________________________
пример в студию.
Какая буква из этой фразы вам не понятна ?
ПРИМЕР в студию!
Что вы предлагаете ? Пометить поле SSN как implement only ? И ? Чего вы этим добьетесь ?
Того что программист создаст метод класса, в котором будет проверять доступ пользователя к данным ?
Чем это отличается от способа номер 1, который я уже приводил, то есть забить код проверки доступа прямо в класс, хранящий данные ?
Не мытьем так катаньем ? :))


<<<... | 3576—3567 | 3566—3557 | 3556—3547 | ...>>>
Всего сообщений в теме: 6256; страниц: 626; текущая страница: 270


Добавить свое сообщение

Отслеживать это обсуждение

Дополнительная навигация:
Количество сообщений на странице

Порядок сортировки сообщений
Новое сообщение вверху списка (сетевая хронология)
Первое сообщение вверху списка (обычная хронология)

Перейти на конкретную страницу по номеру
  
Время на сайте: GMT минус 5 часов

Если вы заметили орфографическую ошибку на этой странице, просто выделите ошибку мышью и нажмите Ctrl+Enter.
Функция может не работать в некоторых версиях броузеров.

Web hosting for this web site provided by DotNetPark (ASP.NET, SharePoint, MS SQL hosting)  
Software for IIS, Hyper-V, MS SQL. Tools for Windows server administrators. Server migration utilities  

 
© При использовании любых материалов «Королевства Delphi» необходимо указывать источник информации. Перепечатка авторских статей возможна только при согласии всех авторов и администрации сайта.
Все используемые на сайте торговые марки являются собственностью их производителей.

Яндекс цитирования