Аспектно Ориентированное Программирование @ DeForum.ru
DeДверь  
Логин:  
Пароль:  
  Автологин  
   
Разместить рекламу
Письмо админу
Правила | FAQ | *Поиск | Наша команда | Регистрация | Вход
 
 
На страницу 1 2  >  Страница 1 из 2 [ Сообщений: 37 ] 
*   Список форумов / Начинка и техника / Программирование для WWW » ответить » создать топик « | »
Автор Сообщение
AlexShop Муж.
участник
34
Сообщения: 1866
Зарегистрирован: 17.02.04
Заголовок сообщения: Аспектно Ориентированное Программирование
Сообщение Добавлено: 12 Июнь 2008, 07:12:56 
Привет всем,
сегодня совершенно случайно ознакомился с Аспектно Ориентированное Программированием!

Первое впечатление - Вау! :eek: :up:

Уже много сайтов посвященно этой методики, но это страница показалось мне наиболее понятной:
http://wiki.agiledev.ru/doku.php?id=aop:aop_php

Судя по всему, различные реализации АОП для PHP находится в состоянии зародыша. И не ясно какая из них станет лидирующей.

Соглашусь с автором статьи, о том что жаль что "PHP Runkit" находится эксперементальной стадии и "не является чатью core PHP". Иначе можно было бы сделать многое своими руками. Хотя многое можно сделать используя небезызвестную eval() функцию.

--------
Вообщем пару мыслей возникло у меня, как симулировать отдаленное подобие АОП в теперешний PHP не используя Runkit или eval(). Недостаток у моего способа - надо менять код в классах.

Предпологаю вы знакомы с понятием Front Controller (программа через которую проходят все запросы).

Моя идея сделать Front Controller для каждого класса:
1. Каждый запрос к методу будет отлавливаться функцией __call()
2. Что бы осуществить пункт 1. можно сделать все методы private, и дать им имена отличные от API.
3. Функция __call() будет работать как Front Controller.
4. В самом начале и конце __call() будет вызываться класс, например AOP::before() и AOP::after().
5. Нужный класс AOP (а их будет много) будет инклюдится в теле программы.

Таким образом уже имеем хоть какой то динамичный контроль над поведением методов.
Можно динамично прикруть фильтры (вход/выход) для каждого метода и т.п.
Также надо освежить в памяти Strategy паттерн - может пригодится.

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

_________________
Тот, кто задает вопрос, глупец в течение пяти минут, тот, кто его не задает, глупец всю свою жизнь. (Китайская поговорка)
Crazy Муж.
Модератор
107
Сообщения: 14561
Зарегистрирован: 23.12.01
Откуда: Moscow
Сообщение Добавлено: 12 Июнь 2008, 10:28:27 

AlexShop писал(а):
Судя по всему, различные реализации АОП для PHP находится в состоянии зародыша. И не ясно какая из них станет лидирующей.



Никакая. AOP в PHP -- мертворожденная технология. Пока не будет полддержки в языке -- лучше церебральной мастурбацией на заниматься.


Цитата:
Недостаток у моего способа - надо менять код в классах.



...поэтому он тоже мертворожденный. Сразу теряется возможность полноценно использовать чужой код. А "мы напишем все заново с нуля" -- это еще одна форма церебральной мастурбации.

Кратко мое мнение таково: если хочется использовать AOP -- нужно сменить язык. Если хочется писать именно на PHP -- нужно оставить в покое AOP.
diezel2005 Муж.
новый человек
16
Сообщения: 140
Зарегистрирован: 12.08.06
Откуда: Украина
Сообщение Добавлено: 12 Июнь 2008, 13:28:37 

Crazy писал(а):
Никакая. AOP в PHP -- мертворожденная технология. Пока не будет полддержки в языке -- лучше церебральной мастурбацией на заниматься.


+4 к харизме.

AlexShop, ты уже готов к Java, честно. Там лучше и проще. Да, процедурно не очень напрограммируешь. Понятно, что быстро ничего не сделаешь. Но те извраты, которые ты постоянно находишь в PHP, их в Java(JSP, j2me, j2ee) нет. Изучишь УМЛ, узнаешь, что такое TDD, освоишь нормальный(!) ООП и все приколы PHP отойдут на второй план. На них больше никогда не будешь обращать внимания. Вообще...

_________________
Не можешь вынести хамства? Сосчитай до десяти и вынеси хама.
AlexShop Муж.
участник
34
Сообщения: 1866
Зарегистрирован: 17.02.04
Сообщение Добавлено: 14 Июнь 2008, 07:09:44 
diezel2005,
на Яву я поглядываю, но сейчас меня LAMP кормит и его надо изучить на должном уровне. :)

Crazy,
почти согласен,
но не выходит ли что за возможность полноценно использовать чужой код, АОП нарушает инкапсуляцию и мой любимый "Принцип Черного Ящика"?
Т.е. если класс содержит объекты, АОП может менять поведение объектов и таким образом менять поведение класса извне? :spy:
(вопрос ко всем)

_________________
Тот, кто задает вопрос, глупец в течение пяти минут, тот, кто его не задает, глупец всю свою жизнь. (Китайская поговорка)
Crazy Муж.
Модератор
107
Сообщения: 14561
Зарегистрирован: 23.12.01
Откуда: Moscow
Сообщение Добавлено: 14 Июнь 2008, 11:26:08 
AlexShop, hint: AOP работает (в нормальных языках) на уровне публичного интерфейса объекта.
AlexShop Муж.
участник
34
Сообщения: 1866
Зарегистрирован: 17.02.04
Сообщение Добавлено: 15 Июнь 2008, 00:46:04 
Итак друзья, кому интересно я продолжаю...

Где-то я слышал крылатое выражение о том что PHP можно сравнить с Китайским языком. На нем разговаривают огромное кол-во программистов, но все они вэб-девелоперы!

Что нам PHP программистам остается делать?

Сначала надо правильно озвучить проблему.
Неправильно: как внедрить AOP парадигму в PHP?
Правильнее: как решить проблему сквозной функциональности в PHP?

Я поискал в инете: есть ли какие способы решения (паттерны) этой проблемы, кроме AOP? Информации мало, но я нашел интересную работу написаную Markus Völter, которая предлагает различные решения, одним из которых является использование паттернов если язык не поддерживает AOP.

Скачать работу в формате PDF можно тут. Нам интересна страница 12. UML схему можно видеть на стр. 13.

Он предлагает использовать паттерны Proxy, Factory и Interceptor для решения проблемы сквозной функциональности (кстати Interceptor я не нашел в книге Банды Четырех).

На основе его работы, я сделал свой PHP пример с моими комментариями.
Мой пример отличается от его (т. к. я не все понял), но идея думаю будет понятна.

Итак, имеем класс Car (который имплементирует iCar интерфейс). Класс умеет хранить название модели и ездить:
Код:
interface iCar
{
   function setModel($model);
   function drive();
}

class Car
{
   private $_model;

   function setModel($model)
   {
      $this->_model = $model;
   }

   function drive()
   {
      return $this->_model." drives!";
   }
}



Имеется класс CarProxy, который применяет Proxy паттерн к классу Car.
CarProxy имеет в себе Interceptor объект, который вызывается дважды в каждом методе ("до" и "после"):
Код:
class CarProxy
implements iCar
{
   private $_car;
   public  $_interceptor;

   function setModel($model)
   {
      // Вызываем Interceptor "до":
      $this->_interceptor->beforeInvoke($this->_car, "setModel", array($model));
      
      // Стандартный код для Proxy паттерна:      
      if (! $this->_car) $this->createCar();
      $return = $this->_car->setModel($model);

      // Вызываем Interceptor "после":
      $this->_interceptor->afterInvoke($this->_car, "setModel", array($model), $return);

      return $return;
   }

   function drive()
   {   // Здесь все аналогично предыдущему методу
      $this->_interceptor->beforeInvoke($this->_car, "drive", array());
      if (! $this->_car) $this->createCar();
      $return = $this->_car->drive();
      $this->_interceptor->afterInvoke($this->_car, "drive", array(), $return);
      return $return;
   }

   function createCar()
   {
      $this->_car = new Car();
   }
}
Понятно что программа-клиент не знает в каком случае она имеет дело с Car, а в каком с CarProxy. Для нее главное, что бы объект умел ездить (т.е. имел iCar интерфейс).


Класс Interceptor может содержать любой ваш код, который должен выполняться "до" и "после" вызова методов объекта CarProxy:
Код:
class Interceptor
{
   function beforeInvoke($obj, $method, $args)
   {
      // Ваш код
   }

   function afterInvoke($obj, $method, $args, $return)
   {
      // Ваш код
   }
}



Класс CarFactory создает машины. В зависимости от файла конфигурации (например XML) CarFactory будет выпускать: Car или CarProxy.
Также в зависимости от конфигурации в CarProxy будут внедряться различные Interceptor объекты. Я весь этот код не привожу, а просто самый минимум:
Код:
class CarFactory
{
   static function createCar()
   {
      $car = new CarProxy();
      $car->_interceptor = new Interceptor();
      return $car;
   }
}



Ну и наконец программа-клиент, для тестирования:
Код:
$car = CarFactory::createCar();
$car->setModel("BMW");
echo $car->drive();

С этим методом можно и нужно экспериментировать дальше.

---------------------------------
Плюсы данного метода:
• Не надо менять оригинальные классы.
• Если в программе объекты создаются уже при помощи Factory паттерна - не надо менять тело программы. В противном случае, написание Factory для объектов - минимально воздействует на программу.

Работа заключается в том что:
• Мы создаем Proxy для каждого класса, в отдельных файлах.
• Изменяем Factory что бы мог понимать файлы конфигурации и действовать согласно им.

В результате имеем полянку для решения проблемы сквозной функциональности в PHP, при минимальном воздействии на программу.

Если в PHP когда нибуть появится AOP, и программу придется вернуть в перновочальное состояние, все что надо сделать это:
• удалить лишний код в Factory классах (объекты могут и дальше создаваться с помощью них).
• удалить Proxy и кофигурационные файлы.


Кстати, Markus Völter имеет много интересных статей на своем сайте посвященных паттернам:
http://www.voelter.de/publications/patterns.html

Код у меня валидный, можно скопировать все в один файл и тестировать.

_________________
Тот, кто задает вопрос, глупец в течение пяти минут, тот, кто его не задает, глупец всю свою жизнь. (Китайская поговорка)
Crazy Муж.
Модератор
107
Сообщения: 14561
Зарегистрирован: 23.12.01
Откуда: Moscow
Сообщение Добавлено: 15 Июнь 2008, 14:04:31 
AlexShop, начнем с простого: что ты понимаешь под "сквозной функциональностью"? Такого общепринятого русскоязычного термина, насколько я знаю, не существует.

P.S. Паттерна Interceptor нет в GOF по той простой причине, что общепринятого паттерна с таким именем в природе опять таки нет. :)
diezel2005 Муж.
новый человек
16
Сообщения: 140
Зарегистрирован: 12.08.06
Откуда: Украина
Сообщение Добавлено: 15 Июнь 2008, 14:25:50 

Crazy писал(а):
Паттерна Interceptor нет в GOF


Это не паттерн, но по сюжету вся нагрузка ложится именно на этот объект. Код Interceptorа при, скажем, 20 интерфейсах с 5 методам каждый будет поражать своей читабельностью. Но мне интересно, чем все закончится.

_________________
Не можешь вынести хамства? Сосчитай до десяти и вынеси хама.
AlexShop Муж.
участник
34
Сообщения: 1866
Зарегистрирован: 17.02.04
Сообщение Добавлено: 15 Июнь 2008, 21:08:55 
Crazy, diezel2005 рад дисскусии!

Определимся с терминами: что я понимаю под "сквозной" функциональностью?

Три дня назад я не знал что под этим термином скрывается, но интуитивно понимал эту проблему и решал ее своими способами.

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

Самый худший вариант:
Проверка авторизации происходит в самом журнале, допустим в каждом из этих методах: add(), modify(), remove(). Если эту программу захочет использовать кто-то другой, кому не нужна авторизация - нам придется менять программу, удаляя из нее куски кода которые проверяют авторизацию.

Приемлемый вариант:

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

Проблема "сквозной" функциональности:
Дело в том что контроллеров много (иногда один на каждую страницу сайта, если страница имеет свой функционал). Поэтому один и тот же код проверки авторизации, должен находится в разных файлах и методах. Тем самым нарушен один из главных принципов программирования: не дублируй код. Мартин Фаулер в своей замечательной книге "Рефакториг" назвает такой код "с душком" (неприятный запах).
Почему термин назвается: "сквозная" функциональность? Я думаю, потому что наш код авторизации "сквозит" в разных файлах и методах.

Классическое решение "сквозной" функциональности:

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

Как AOP решает это проблему:
AOP решает радикальным способом. Оно заявляет что код авторизации вообще не должен находится в контроллерах. Конроллеры должны заниматься своим делом: правильно использовать нашу программу Журнал (вызывать методы: добавить, изменить, удалить) в зависимости от того какую кнопку пользователь нажал.

Тут я хочу сразу извиниться за возможные неточности, потому что с AOP я теоретически знаком третий день, не имея возможности испытать на себе (Java я не знаю, а к тем наработкам которые существуют для PHP - я пока скептически отношусь).

Итак, где же находится код авторизации?

К программе подключается модуль - Aspect. В общих чертах этот модуль имеет возможность:
1. Прервать исполнение программы со стороны(!).
2. Исполнить ваш любой код.
3. Продолжить (или остановить) дальнейшее исполнение программы.

То что модуль подключается со стороны является сильной (а возможно и слабой) стороной AOP.
(поэтому я и спросил у Crazy не нарушает ли это "принцип черного ящика" и инкапсуляцию).

В нашем случае модуль Aspect:
1. Прерывает программу в контроллерах которые имеют методы, допустим: addArticle(), editArticle() и deleteArticle().
2. Исполняет код авторизации (который хранится в одном месте).
3. В зависимости от того прошла авторизация или нет исполняет методы addArticle(), editArticle(), deleteArticle() или что-то другое.

Вообщем я увлекся и ушел немного с заданой темы (вы все это знаете лучше меня), но может кому-то еще это будет интересно.

В PHP нет такой росскоши как возможность прервать программу со стороны. Надо заранее изменить программу так что бы она разрешала себя прервать. Сейчас наработки AOP для PHP предлагают различные способы динамически изменить программу. Но то как они это делают :fie: (Crazy прав).

Мне нравится способ, который предложил Markus Völter:
- все делается исключительно средствами PHP
- правда статически меняем программу, но воздействие на нее оказываем минимальное.
- все сводится к написанию отдельных модулей.

Вот я изложил мое теперешнее представление: "сквозной" функциональности и AOP в целом.
Дальше я рассмотрю недостатки у предложенного способа (они есть) и как их лучше преодолеть в PHP.

_________________
Тот, кто задает вопрос, глупец в течение пяти минут, тот, кто его не задает, глупец всю свою жизнь. (Китайская поговорка)


Последний раз редактировалось AlexShop 15 Июнь 2008, 21:57:33, всего редактировалось 8 раз(а).
AlexShop Муж.
участник
34
Сообщения: 1866
Зарегистрирован: 17.02.04
Сообщение Добавлено: 15 Июнь 2008, 21:22:42 

diezel2005 писал(а):
Это не паттерн, но по сюжету вся нагрузка ложится именно на этот объект. Код Interceptorа при, скажем, 20 интерфейсах с 5 методам каждый будет поражать своей читабельностью. Но мне интересно, чем все закончится.


diezel2005,
Interceptor'ов будет не один класс - их будет много. Скажем один на каждый интерфейс.
Factory будут динамически выбирать и вставлять нужный Interceptor в ProxyObject.

Как правильно выбрать Interceptor?
Factory будет смотреть файл конфигурации (например XML).

В XML будет заложена вся логика. При создании некоторого объекта Factory выберает одно из двух:
а) берет такой-то Interceptor, вставляет его в ProxyObject и выдает ProxyObject
б) создает и выдает обычный Object

_________________
Тот, кто задает вопрос, глупец в течение пяти минут, тот, кто его не задает, глупец всю свою жизнь. (Китайская поговорка)
Crazy Муж.
Модератор
107
Сообщения: 14561
Зарегистрирован: 23.12.01
Откуда: Moscow
Сообщение Добавлено: 15 Июнь 2008, 22:00:01 

AlexShop писал(а):
Я понимаю "сквозную" функциональность, также как понимает ее автор статьи, ссылку на которую я привел в самом начале этой темы.



Открываем статью:


Цитата:
В английском языке есть очень удачный термин для этого – crosscutting concerns



Вот оригинальным термином -- crosscutting concerns -- я и рекомендую пользоваться. Поскольку загадочное "'сквозная' функциональность" не передает ни одного из смысловых аспектов.

Что же касается crosscutting concerns, то минусы и плюсы здесь ходят парами. Да, мы получаем более чистый код благодаря тому, что каждый аспект задачи описан отдельно и связно. Однако снижается пригодность программы к отладке и развитию: во-первых, потому, что локально внесенное изменение может широко жжахнуть по коду и, во-вторых, потому, что изучение одного участка кода ничего не говорит о том, как это будет работать в полной программе. И самое мрачное: AOP вообще никак не поддержано средствами проектирования. Я примерно раз в год ищу материалы по методологиям/языкам проектирования программ, которые предусматривали бы возможность выразить идеи AOP. Их нет. К примеру, попытка пришить AOP к UML пока ничем хорошим не кончилась (это логично: AOP и OOP ортогональны).

Именно поэтому в отсутствие поддержки со стороны языка и специальной IDE данная концепция нежизнеспособна. Что мы и наблюдаем на практике: даже при наличии полноценной реализации AOP для Java, при наличии хорошей поддержке IDE, реальных коммерческий проектов нет. Даже слухи не ходят.

В PHP это тем более нежизнеспособно, поскольку:

1) AOP имеет смысл при том масштабе проекта, при котором уже нет смысла писать на PHP
2) Уровень реюза кода в PHP в реальных проектах настолько низок, что не позволяет всерьез использовать плюсы AOP
3) PHP предусматривает простые решение для тех задач, для которых зачастую предлагается использовать AOP. Простейщий пример -- авторизация, которая легко реализуется auto_prepend_file.

Так что AOP -- штука интересная. В академическом смысле. Изучать -- стоит. Применять в коммерческих проектах -- нет.
AlexShop Муж.
участник
34
Сообщения: 1866
Зарегистрирован: 17.02.04
Сообщение Добавлено: 16 Июнь 2008, 00:44:19 
Crazy, все верно

В OOP все жиздется на том что:
1. Объект - это черный ящик.
2. Как он работает (имплементацию) - не смотри, не меняй и не знай (если только не делаешь рефакторинг).
3. К классу объекта приложены инструкции (API). Вот по ним и работай.

Если надо изменить (добавить) функционал то:
1. Не меняй код класса - оставь его как есть.
2. Сделай новый класс, который наследовал бы функционал старого и измени что надо.
3. Либо добавь функционал к объекту с помощью паттернов (например Observer).

Почему мы не хотим изменять код классов? Потому что:
1. Программисты потратили достаточно времени, что сделать этот код чистым от ошибок
2. Мы уверенны, что класс работает сегодня - так же как он работал и вчера.
3. Другие участки программы (о которых мы не подозреваем) могут использовать этот класс.

Это называется Open/Closed Principle.

Мне кажется что AOP нарушает этот принцип.
AOP позволяет прерывать работу класса (для которой он был построен) и исполнять чужой код.
Что самое страшное - то что класс об этом не подозревает.

Объект возможно все еще остается "черной коробкой" - но поведение его уже не описывается API.
Его поведение труднее прогнозировать. Еще труднее прогнозировать поведение композитных объектов (которые содержат внутри другие объекты, а те в свою очередь другие).

Напротив: OOP строится из твердого знания своих классов, объектов и их поведения.
Те вещи которые предлагает AOP, не надо хотеть в OOP.
Поэтому OOP и AOP - это разные парадигмы (не даром они имеют разные названия).

------
Но вот что самое интересное.

Так как способ который предложил Markus Völter основан на паттернах, то мы все еще остаемся в OOP.
И никакие принципы OOP здесь не нарушаются.
Так что мы имеем некоторую AOP функциональность, при полном согласии с OOP.

Согласен, что такая функциональность нужна для больших Enterprise проектах, где PHP обычно не фигурирует.
Но поэкспериментировать тоже можно.

------
Уровень PHP кода низок в реальных проектах все мы знаем почему. Потому что:
1. PHP позволяет быстро написать спаггетти код, который увы будет работать.
2. Надо обладать дисциплинированностью что бы писать правильно и характером что бы убедить босса потратить время на это.

_________________
Тот, кто задает вопрос, глупец в течение пяти минут, тот, кто его не задает, глупец всю свою жизнь. (Китайская поговорка)


Последний раз редактировалось AlexShop 16 Июнь 2008, 01:20:08, всего редактировалось 1 раз.
Crazy Муж.
Модератор
107
Сообщения: 14561
Зарегистрирован: 23.12.01
Откуда: Moscow
Сообщение Добавлено: 16 Июнь 2008, 01:20:02 

AlexShop писал(а):
В OOP все жиздется на том что:
1. Объект - это черный ящик.
2. Как он работает (имплементацию) - не смотри, не меняй и не знай (если только не делаешь рефакторинг).
3. К классу объекта приложены инструкции (API). Вот по ним и работай.



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


Цитата:
Если надо изменить (добавить) функционал то:
1. Не меняй код класса - оставь его как есть.
2. Сделай новый класс, который наследовал бы функционал старого и измени что надо.
3. Либо добавь функционал к объекту с помощью паттернов (например Observer).



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

Так что мы меняем код классов. Это объективная реальность. Разберем по пунктам:


Цитата:
Почему мы не хотим изменять код классов? Потому что:
1. Программисты потратили достаточно времени, что сделать этот код чистым от ошибок
2. Мы уверенны, что класс работает сегодня - так же как он работал и вчера.
3. Другие участки программы (о которых мы не подозреваем) могут использовать этот класс.



Важно понимать, что, в отличие от модульного программирования, класс есть связная сущность, а не набор случайно соседствующих методов. Если не рассматривать правку дефектов, то изменения в класс мы вносим только при изменении требований. Т.е. в случае, когда меняется наше видение этой сущности. В этом случае "другие участки" также должны работать с новой сущностью. Соответственно, нет смысла использовать наследование и оставлять старый класс как есть. Единственно, что это даст -- места в программе, где по забывчивости будет применяться старый класс. А пользы акромя вреда -- никакой. Этим мы покрываем п.3.

Если класс нормально работает сегодня и нас это поведение устраивает завтра, то с какого бодуна мы вообще полезли что-то менять в программе? Работает -- не трогай. Рефакторинг -- отдельная история. Так что и п.2. мы покрыли.

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

Итак, если кратко: есть РОВНО ОДИН случай, когда мы используем наследование: когда это диктуется отношениями в логической модели. Никакие текущие потребности в сохранении старого API и попытки повышения устойчивости кода не оправдывают применения наследования.


Цитата:
Это называется Open/Closed Principle.



Этот принцип применяется в случае, когда мы хотим сделать новую систему на базе старой. Он не применяется в жизненном цикле разработке самой системы. Более того, зачастую приходится импортировать ИСХОДНИКИ чужой системы в свою систему управления версиями и вносить изменения в ее потроха. Прежде всего -- в случаях, когда нас не устраивает декомпозиция или уровни изоляции. Когда OOP придумывали -- никому не пришло в голову, что там, где в базовом классе есть цельный метод FooBar, в потомке потребуются отдельно Foo и Bar. Так что других решений -- кроме сунуть руки в код -- может просто не быть.


Цитата:
Мне кажется что AOP нарушает этот принцип.
AOP позволяет прерывать работу класса (для которой он был построен) и исполнять чужой код.
Что самое страшное - что класс об этом не подозревает.



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


Цитата:
Объект возможно все еще остается "черной коробкой" - но поведение его уже не описывается API.
Его поведение труднее прогнозировать. Еще труднее прогнозировать поведение композитных объектов (которые содержат внутри другие объекты, а те в свою очередь другие).



..и опять таки с наследованием все то же самое.


Цитата:
Напротив: OOP строится из твердого знания своих классов, объектов и их поведения.
Те вещи которые предлагает AOP, не надо хотеть в OOP.
Поэтому OOP и AOP - это разные парадигмы (не даром они имеют разные названия).



За некоторыми нюансами с самими постулатами я согласен. :)


Цитата:
Так как способ который предложил Markus Vцlter основан на паттернах, то мы все еще остаемся в OOP.
И никакие принципы OOP здесь не нарушаются.
Так что мы имеем некоторую AOP функциональность, при полном согласии с OOP.



Логическая ошибка в этой фразе состоит в том, что ты считаешь, что паттерны привязаны к OOP. Это не так. Соответственно, и вывод -- неверен.


Цитата:
Уровень PHP кода низок в реальных проектах все мы знаем почему. Потому что:
1. PHP позволяет быстро написать спаггетти код, который увы будет работать.
2. Надо обладать дисциплинированностью что бы писать правильно и характером что бы убедить босса потратить время на это.



Замени "PHP" на название любого другого языка -- и все утверждения сохранят силу. :)
AlexShop Муж.
участник
34
Сообщения: 1866
Зарегистрирован: 17.02.04
Сообщение Добавлено: 18 Июнь 2008, 05:47:52 

Crazy писал(а):
То, что ты описал, представляет собой не OOP, а просто модульное программирование. Приципиально важный аспект OOP -- наследование.


Да, сказалось отсутствие формального образования по информатике у меня. :rolleyes:



Crazy писал(а):
Здесь следует учитывать, что концепция "наследовать вместо изменения исходника при изменении требований" живет только в некоторых книжках (кривых). В реальной жизни эта методика не применяется.


Люди с древнейших времен желают строить так, что бы держалось как можно дольше.
Программистам повезло: если программу не трогать - она никогда не будет ломаться.
Это может быть неосуществимой мечтой или искушением, но Open/Closed principe (в той или иной форме) будет жить пока программирование существует.

Если мы программируем Корзинку для покупок, то в ней должны быть методы: добавить/удалить товар, очистить корзину. Они должны быть при любой бизнес-логики. Написав и проверив эту функциональность мы больше ее не трогаем. И чем проще модуль и монотонее его работа - тем меньше надобности его менять.

Но везде применять этот принцип - не выгодно, приводит к ненужной сложности (это из моей книжки )))

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

Это как в квантовой физике:
Чем меньше (проще) модуль - тем лучше этот принцип работает и наоборот.

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

_________________
Тот, кто задает вопрос, глупец в течение пяти минут, тот, кто его не задает, глупец всю свою жизнь. (Китайская поговорка)
AlexShop Муж.
участник
34
Сообщения: 1866
Зарегистрирован: 17.02.04
Сообщение Добавлено: 21 Июнь 2008, 18:41:05 
После лирического отступления вернемся к делу..


AlexShop писал(а):
AOP позволяет прерывать работу класса (для которой он был построен) и исполнять чужой код.
Что самое страшное - что класс об этом не подозревает.



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


Согласен, но надо добавить:
• при наследовании, изменения происходят во время компиляции программы (Compile-time)
• в AOP изменения происходят во время выполнения программы (Run-time)



Crazy писал(а):
Логическая ошибка в этой фразе состоит в том, что ты считаешь, что паттерны привязаны к OOP. Это не так. Соответственно, и вывод -- неверен.


Моя логика была не эта:
- если используем паттерны - значит используем OOP
А вот эта:
- если используем OOP и паттерны - значит все еще используем OOP

Поэтому вопрос: "Обладает ли способ предложенный Markus Völter теми же недостатками, что и AOP?" для меня остается открытым.
Возможно недостатки растут из-за того что, изменения вносятся во время Run-time.
При этом не важно что мы используем: паттерны или AOP.

_________________
Тот, кто задает вопрос, глупец в течение пяти минут, тот, кто его не задает, глупец всю свою жизнь. (Китайская поговорка)
Crazy Муж.
Модератор
107
Сообщения: 14561
Зарегистрирован: 23.12.01
Откуда: Moscow
Сообщение Добавлено: 21 Июнь 2008, 20:12:37 

AlexShop писал(а):
• при наследовании, изменения происходят во время компиляции программы (Compile-time)
• в AOP изменения происходят во время выполнения программы (Run-time)



Оба утверждения в общем случае неверны. Ибо:

1) Нет причин реализовывать наследование исключительно во время компиляции (см. JavaSсript и Groovy).
2) Нет причин реализовывать AOP исключительно во время выполнения. См. PostSharp


Цитата:
если используем OOP и паттерны - значит все еще используем OOP



Я тебя понял именно так. Вопрос в другом: я не вижу логической цепочки, которую замещает здесь слово "значит". :) JFYI: некоторые из классических -- GOF -- паттернов взяты напрямую из функционального программирования. Поэтому, кстати, функциональщикам трудно объяснить концепцию паттернов -- многие у них просто живут в виде штатных языковых средств. :)
AlexShop Муж.
участник
34
Сообщения: 1866
Зарегистрирован: 17.02.04
Сообщение Добавлено: 21 Июнь 2008, 22:29:10 
Помоему все сводится к одному:
• какие возможности языка во время Comple-time?
• какие возможности языка во время Run-time?

Чем больше возможностей язык имеет во время Run-time - тем меньше ему надо AOP.
Потому что в конечном счете мы приходим к одному: к динамике.

Хотим ли мы реализацию наследования во время Run-time в OOP? Это уже отдельная тема.:)



Crazy писал(а):
Нет причин реализовывать AOP исключительно во время выполнения.


Кстати многие наработки AOP для PHP так и делают. Например у phpAspect:
"Процесс вплетения аспектов происходит статически непосредственно в исходный код приложения, который копируется в отдельную директорию".

------------------------------------------------------


AlexShop писал(а):
если используем OOP и паттерны - значит все еще используем OOP


Crazy писал(а):
я не вижу логической цепочки, которую замещает здесь слово "значит"



Вот моя полная логическая цепочка:
1. OOP не имеет недостатки, которые имеет AOP
2. OOP программа не имеет недостатки, которые имеет AOP программа
3. OOP программа использует паттерны, что бы реализовать AOP функциональность
4. Пункт 2. сохраняет свою силу.

По крайней мере, хочется на это надеяться.

_________________
Тот, кто задает вопрос, глупец в течение пяти минут, тот, кто его не задает, глупец всю свою жизнь. (Китайская поговорка)
Crazy Муж.
Модератор
107
Сообщения: 14561
Зарегистрирован: 23.12.01
Откуда: Moscow
Сообщение Добавлено: 22 Июнь 2008, 19:20:43 

AlexShop писал(а):
Чем больше возможностей язык имеет во время Run-time - тем меньше ему надо AOP.



Здесь есть путаница между методологией программирования (AOP) и способом выражения этой (или иной) методологии в языке.


Цитата:
Хотим ли мы реализацию наследования во время Run-time в OOP? Это уже отдельная тема.:)



Мы это уже имеем. :)


Цитата:
Вот моя полная логическая цепочка:
1. OOP не имеет недостатки, которые имеет AOP
2. OOP программа не имеет недостатки, которые имеет AOP программа
3. OOP программа использует паттерны, что бы реализовать AOP функциональность
4. Пункт 2. сохраняет свою силу.



В переходе от 3 к 4 отсутствует логика. Hint: замени абстрактные надостатки AOP на их конкретный список и отсутствие логики станет более заметным.
AlexShop Муж.
участник
34
Сообщения: 1866
Зарегистрирован: 17.02.04
Сообщение Добавлено: 14 Июль 2008, 03:05:06 

Crazy писал(а):
Когда OOP придумывали -- никому не пришло в голову, что там, где в базовом классе есть цельный метод FooBar, в потомке потребуются отдельно Foo и Bar.


Оффтопик: кстати, у меня возникла идея как расширить синтаксис языка PHP (и не только) что бы сделать его более понятным. Например:
Код:
Вместо:
str_replace($string1, $string2, $string3)

разрешить писать так:
search_for($string1)replace_to($string2)in($string3)

Код:
Или вместо гипотетической функции:
remove($array, $elements);

разрешить писать функции так:
remove($elements)in($array)

Т.е аргументы не обязательно должны идти в конце функции: functionName(a, b), а где угодно: function(a)Name(b).
Тем самым приближаясь к обычной грамматике английского языка.

Вот только кто возьмется за такое расширение?

_________________
Тот, кто задает вопрос, глупец в течение пяти минут, тот, кто его не задает, глупец всю свою жизнь. (Китайская поговорка)
Crazy Муж.
Модератор
107
Сообщения: 14561
Зарегистрирован: 23.12.01
Откуда: Moscow
Сообщение Добавлено: 14 Июль 2008, 06:31:20 
AlexShop, welcome to Smalltalk syntax :)
zebraMan
новый человек
0
Сообщения: 1
Зарегистрирован: 22.01.09
Заголовок сообщения: Re: Аспектно Ориентированное Программирование
Сообщение Добавлено: 22 Январь 2009, 07:17:27 
Признаюсь честно, я в восторге... Впервые вижу настолько грамотно написанный и изложенный текст программистов! :lol:

До сегодняшнего дня я думал, что я программирую на слабенькую 4-ку, но теперь я понимаю, что еле набираю до 1 :cry:

Поэтому могу вам только пожелать положительных результатов вашей работы над АОР, а я внимательно понаблюдаю ходом мыслей :green:

Еще раз СПАСИБО за дискуссию. Для меня это еще хоть и маленький, но опыт :beer:
jettero
новый человек
0
Сообщения: 230
Зарегистрирован: 14.09.03
Сообщение Добавлено: 12 Февраль 2009, 11:21:30 
Кстати скоро будет готов php фреймворк FLOW3 с поддержкой AOP.
jettero
новый человек
0
Сообщения: 230
Зарегистрирован: 14.09.03
Заголовок сообщения: Re: Аспектно Ориентированное Программирование
Сообщение Добавлено: 21 Февраль 2009, 01:37:58 
Еще насчет AOP – во FLOW3 его уже похоже реализовали, судя по этой табличке http://forge.typo3.org/versions/show/182. У них синтаксис AOP вводится через аннотации, а фреймворк, читая аннотации, реализует концепцию AOP.
Кто хочет покопаться может скачать из trunk текущую версию, я пока не рвусь тестить, жду первого релиза, надеюсь уже скоро :cool:
AlexShop Муж.
участник
34
Сообщения: 1866
Зарегистрирован: 17.02.04
Заголовок сообщения: Re: Аспектно Ориентированное Программирование
Сообщение Добавлено: 16 Май 2009, 09:58:43 
Crazy,
если ты не против, вернемся к Open-Closed Principle.

Этот принцип говорит: классы должны быть закрыты для изменений и открыты для расширения. А как достичь этого -- несказано.
Можно использовать наследование, а можно полиморфизм.

К примеру:
класс для сортировки данных может использовать разные алгоритмы сортировки: по алфавиту, по дате, по числам и т.п.

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

Так как класс не занимается сортировкой, у него всего одно предназначение: он применяет алгоритм сортировки к данным.
Иными словами: класс имеет одну и только одну причину для изменений (The Single Responsibility Principle).

Причин изменять алгоритмы тоже нет:
если изменить алгоритм сортировки по алфавиту, то он перестанет сортировать по алфавиту. Зачем нам это надо? (Рефакторинг -- отдельная история).

Так что при правильном проектировании (к примеру с использованием паттерна Стратегия) Open-Closed Principle может применяться в работе.

_________________
Тот, кто задает вопрос, глупец в течение пяти минут, тот, кто его не задает, глупец всю свою жизнь. (Китайская поговорка)
Crazy Муж.
Модератор
107
Сообщения: 14561
Зарегистрирован: 23.12.01
Откуда: Moscow
Сообщение Добавлено: 16 Май 2009, 10:51:14 
Да, Open-Closed Principle применим в реальной жизни. Надеюсь, это избавляет меня от необходимости подробно разбирать приведенный выше поток сознания и по каждому утверждению отдельно показывать, почему оно неверно в принцие или никак не доказывает применимость этого принципа? :)

Тем более, что мой склероз говорит, что я уже писал о том, что закрытость для изменений не означает отказ от редактирования кода...
AlexShop Муж.
участник
34
Сообщения: 1866
Зарегистрирован: 17.02.04
Заголовок сообщения: Re: Аспектно Ориентированное Программирование
Сообщение Добавлено: 16 Май 2009, 20:09:32 
Crazy,
полиморфизм или паттерн Стратегия наглядно иллюстрируют приминение Open-Closed Principle (OCP).

Решение использовать OCP должно приниматься в каждом индивидуальном случае.
Иными словами: не надо использовать OCP только потому что это возможно.

Я не за отказ от редактирования кода, но за дизайн при котором не хотелось бы редактировать код.

_________________
Тот, кто задает вопрос, глупец в течение пяти минут, тот, кто его не задает, глупец всю свою жизнь. (Китайская поговорка)
Crazy Муж.
Модератор
107
Сообщения: 14561
Зарегистрирован: 23.12.01
Откуда: Moscow
Сообщение Добавлено: 16 Май 2009, 20:16:34 
AlexShop, полиморфизм не имеет отношения к OCP. Ты путаешь полиморфизм и делегирование. Это раз.

Решение о разрешении редактирования кода никак не связано с применением или отсутствием применения OCP. Эти вещи лежат в разных измерениях. OCP придуман вовсе не для того, чтобы избежать редактирования кода. Более того, OCP в принципе не может обеспечить отказ от редактирования кода. Это два.

BTW, непосредственно сейчас я участвую в проекте, в котором дизайн строится на приципе Close-Close. Что не отменяет частого редактирования.
AlexShop Муж.
участник
34
Сообщения: 1866
Зарегистрирован: 17.02.04
Заголовок сообщения: Re: Аспектно Ориентированное Программирование
Сообщение Добавлено: 16 Май 2009, 21:19:41 

Crazy писал(а):
Ты путаешь полиморфизм и делегирование.

Спасибо, я пересмотрю внимательно эти два термина.

Crazy писал(а):
Решение о разрешении редактирования кода никак не связано с применением или отсутствием применения OCP. Более того, OCP в принципе не может обеспечить отказ от редактирования кода.

Согласен.

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

А для чего он придуман?

Crazy писал(а):
BTW, непосредственно сейчас я участвую в проекте, в котором дизайн строится на приципе Close-Close. Что не отменяет частого редактирования.

Гугл молчит о Close-Close Principle. Я понимаю это как стандартные PHP функции: они закрыты для модификации и расширения (тоже можно делать и с классами).
Если Open-Close или Close-Close не отменяют редактирования, то какой смысл вкладывается в термин "Close" ?

_________________
Тот, кто задает вопрос, глупец в течение пяти минут, тот, кто его не задает, глупец всю свою жизнь. (Китайская поговорка)
Crazy Муж.
Модератор
107
Сообщения: 14561
Зарегистрирован: 23.12.01
Откуда: Moscow
Сообщение Добавлено: 16 Май 2009, 21:30:17 

Цитата:
какой смысл вкладывается в термин "Close"



Если кратко: Close-Close фактически не является официальным термином. На практике это означает, что как изменение существующего класса, так и создание потомков является нерекомендованной практикой. Хочешь нового -- сделай в стороне свой класс и в нем можешь делегировать часть функций существующему. Хочешь изменить существующий или от него наследоваться -- требуется письменное согласие владельца кода соответствующего класса.

Такая схема мне не особо нравится, но практика показала ее применимость.


Цитата:
А для чего он придуман



Для того, чтобы упорядочить редактирование кода. Например, классическая Agile-разработка с коллективным владением кода предполагает, что я могу влезть в любой класс и его изменить. OCP говорит, что я должет по возможности не править существующие классы, а создавать новые. Обращаю внимание на "по возможности": если для правки дефекта создают новый класс, а старый оставляют с дефектом, то это либо очень специфическая архитуетура, либо, чаще, особая мозговая болезнь.
AlexShop Муж.
участник
34
Сообщения: 1866
Зарегистрирован: 17.02.04
Заголовок сообщения: Re: Аспектно Ориентированное Программирование
Сообщение Добавлено: 16 Май 2009, 22:11:50 

Crazy писал(а):
На практике это означает, что как изменение существующего класса, так и создание потомков является нерекомендованной практикой.

Добавлю что изменения (не рефакторинг) иногда являются недопустимыми, как:
AlexShop писал(а):
если изменить алгоритм сортировки по алфавиту, то он перестанет сортировать по алфавиту. Зачем нам это надо?




Crazy писал(а):
OCP говорит, что я должен по возможности не править существующие классы, а создавать новые. Обращаю внимание на "по возможности"

Логично. Если выгода от правки кода больше чем от соблюдения OCP, то смело правим код (18 постов выше я был слишком категоричен :)).

_________________
Тот, кто задает вопрос, глупец в течение пяти минут, тот, кто его не задает, глупец всю свою жизнь. (Китайская поговорка)
Crazy Муж.
Модератор
107
Сообщения: 14561
Зарегистрирован: 23.12.01
Откуда: Moscow
Сообщение Добавлено: 16 Май 2009, 23:04:35 

AlexShop писал(а):
если изменить алгоритм сортировки по алфавиту, то он перестанет сортировать по алфавиту. Зачем нам это надо?



Если я сменю quicksort на mergesort, то с какого перепугу он перестанет сортировать по алфавиту?
Crazy Муж.
Модератор
107
Сообщения: 14561
Зарегистрирован: 23.12.01
Откуда: Moscow
Сообщение Добавлено: 16 Май 2009, 23:08:33 

AlexShop писал(а):
Если выгода от правки кода больше чем от соблюдения OCP, то смело правим код (18 постов выше я был слишком категоричен :)).



Проблема в том, что не существует методики, позволяющие определить, чего больше в данном конкретном случае -- вреда или пользы.
AlexShop Муж.
участник
34
Сообщения: 1866
Зарегистрирован: 17.02.04
Заголовок сообщения: Re: Аспектно Ориентированное Программирование
Сообщение Добавлено: 17 Май 2009, 01:46:22 

AlexShop писал(а):
Если я сменю quicksort на mergesort, то с какого перепугу он перестанет сортировать по алфавиту?

Я имел ввиду функцию для сравнения элементов (comparison function) которая используется например в:
http://us3.php.net/manual/en/function.usort.php , а не алгоритм сортировки который работает со всем списком.

_________________
Тот, кто задает вопрос, глупец в течение пяти минут, тот, кто его не задает, глупец всю свою жизнь. (Китайская поговорка)
Crazy Муж.
Модератор
107
Сообщения: 14561
Зарегистрирован: 23.12.01
Откуда: Moscow
Сообщение Добавлено: 17 Май 2009, 02:15:32 
AlexShop, та же фигня. Один и тот же результат зачастую можно получить, используя разные алгоритмы, имеющие, к примеру, различные характеристики по памяти и скорости.

P.S. вообще-то, стоит писать именно то, что имеешь в виду.
AlexShop Муж.
участник
34
Сообщения: 1866
Зарегистрирован: 17.02.04
Заголовок сообщения: Re: Аспектно Ориентированное Программирование
Сообщение Добавлено: 23 Май 2009, 22:22:30 
Crazy,
ради рефакторинга код можно менять всегда и везде. Нас же интересуют изменения в коде которые нужны из-за меняющихся требований к программе.

--------
Я соглашусь с этим кратким определением полиморфизма: polymorphism = delegation + indirection

В моем примере есть делегация:
класс (для сортировки данных) делегирует данные в функцию которая сравнивает пару элементов.

В примере отсутствует indirection:
в программе должны быть управляющие конструкции (if-else, switch-case) которые подставляли бы нужную функцию в класс.

Поэтому в моем примере действительно нет полиморфизма, а есть делегация к callback-функции.


Crazy писал(а):
полиморфизм не имеет отношения к OCP.

OCP не имеет прямого отношения к полиморфизму, потому что OCP ничего не говорит о реализации.
Мы можем использовать: наследование, полиморфизм, Аспектно Ориентированное Программирование, и (мы только что рассмотрели) callback-функции.

Короткая статья на Википедии разделяет реализацию OCP на две категории:
1. Meyer's OCP (где используется наследование);
2. Polymorphic OCP (где используется полиморфизм).

К сожелению в статье не говориться о таких различиях как:
- при первом способе изменения происходят во время компилирования программы;
- при втором способе изменения происходят во время исполнения программы.

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

Также в статье не упоминается:
- Аспектно Ориентированное Программирование (хотя ИМХО оно очень согласуется с OCP).
- динамические языки как JavaScript, где поведение функций можно менять во время выполнения программы.

_________________
Тот, кто задает вопрос, глупец в течение пяти минут, тот, кто его не задает, глупец всю свою жизнь. (Китайская поговорка)
*   Список форумов / Начинка и техника / Программирование для WWW « | » » ответить » создать топик
На страницу 1 2  >  Страница 1 из 2 [ Сообщений: 37 ] 
Показать сообщения за:   Поле сортировки  
Найти:
Перейти:  
Уровень доступа: Вы не можете начинать темы. Вы не можете отвечать на сообщения. Вы не можете редактировать свои сообщения. Вы не можете удалять свои сообщения. Вы не можете добавлять вложения.
cron


ООО ДеФорум
При использовании материалов сайта ссылка на DeForum.ru — обязательна.
Проект Павла Батурина ©2001-2077; // Powered by phpBB © 2013 phpBB Group
Rambler's Top100