Можете считать отсылкой к этому текст о том, что инструменты бывают разные и для разных целей нужно применять свои. Если уж более подробно описывать минусы ООП, то нужно описывать минусы и плюсы и других подходов, и все это делать на хороших примерах, чтобы было хорошо понятно всем. А это большая, интересная тема, но для отдельной статьи.
Вы же сами видите, что в варианте ФП связи явные, а в ООП — неявные. Вот и проблем в ООП больше.
Если переопределяется метод базового класса, то должно быть очевидно, что такой метод может где-то использоваться и полагаться на то, что это не так совершенно неправильно. Т.е. если в случае с ФП нужно поискать — используется ли функция где-нибудь или нет, то в случае с переопределенными методами даже искать ничего не надо — нужно просто считать, что они точно где-то используются. Получится та же проблема, что и в случае изменения поведения функции, которая используется другими функциями.
Если это не брать в расчет и бездумно что-то менять, то не стоит удивляться, что что-то ломается. По-Вашему получается, что если болгаркой отпилить палец, то виновата болгарка.
За примеры, конечно, спасибо, но к чему они? Я изначально сказал то, что проблема изменения поведения кода, который кем-то используется, существует не только в ООП и является общей проблемой. Да, в ООП есть ситуации, когда эта проблема может быть более острой, но это никак не противоречит моим словам. Я же не пытаюсь доказать Вам, что ООП это единственно правильный подход, в котором нет проблем. Как я уже упоминал выше — серебряной пули нет, и везде есть свои плюсы и минусы.
В случае функционального подхода можно представить иерархию функций:
let func1 f =
let func2 f =
let funcX f = f + 1
funcX f;
func2 f;
printfn "%i" (func1 1)
И предположить, что функция funcX сделана другим автором, который потом берет и меняет ее поведение на:
let funcX f = f - 1
В этом случае у нас тоже может все поломаться и без всякого ООП.
К сожалению, написать статью так, чтобы каждый нашел для себя что-то новое и интересное, затрагивая большой круг тем, да еще и в компактном виде, наверное, нереально.
Жаль, что это статья не смогла Вам угодить. Надеюсь, в какой-нибудь другой раз все будет иначе.
Я не понимаю, как Ваш комментарий связан с проблемой изменения существующего поведения, на основе которого реализовано другое поведение.
Если Вы используете чужую процедуру, исходного кода которой у Вас нет и полагаетесь на ее поведение, что произойдет если ее поведение поменяется? У Вас ничего не поломается все равно?
Тоже самое можно сказать и про процедурный подход — если поменять логику работы процедуры, которая используется в других процедурах, то они так же могут поломаться.
Тут просто существует общая проблема изменения поведения кода, который уже где-то используется.
Я тоже стал думать в эту сторону. Автор начинает с того, что предлагает задуматься над причиной принятия наших решений, а потом без всяких раздумий выбирает ООП как концепцию.
Понятно, что с таким разбором статья получилась бы совсем большой. Но стоило хотя бы отметить существование выбора.
Действительно, мысли раскрыть эту тему были — но, прикинув объем, я решил эту тему не затрагивать. Так можно было бы углубляться до бесконечности. Поэтому за основу была взята наиболее популярная, на мой взгляд, концепция.
В то же время, существует (и поддерживается многими) мнение, что ООП-моделирование в классическом понимании красиво в теории, но создает огромное количество проблем на практике. А также существуют другие подходы, такие как функциональное программирование, пытающиеся преодолеть эти ограничения.
Мне кажется, что ООП и ФП не противостоят друг другу, они о разных вещах. Можно одинаково успешно пользоваться и тем и другим.
Я думаю, это могло бы быть хорошей темой для отдельной статьи.
Миф, цитируемый разводилами-теоретиками недалеким менеджерам. До сих пор не доказана эффективность разработки с ООП перед процедурным подходом. Кроме того, имеется множество авторитетных мнений за то, что ООП является скорей антипаттерном и в реальной жизни лишь усложняет проектирование и разработку, заставляя концентрироваться на абстрактных вещах, не имеющих отношения к решаемой задаче.
Серебряной пули вообще не существует. Для каждой задачи лучше всего подходит какой-то свой набор инструментов.
— Миллионы приложений используют реляционную модель и живут счастливо без всякого наследования в своей предметной области. Приложение в 99% случаев работает с конкретной сущностью, нежели абстрактным надклассом.
Я и не говорил, что они будут жить грустно или не будут работать. Я говорил, что у всего есть своя стоимость. И в зависимости от задач, стоимость применения ООП или реляционного подхода будет отличаться.
— Инкапсуляция становится бесполезной, когда изменения состояния затрагивает сразу много объектов, и когда зависимости одни от других нетривиальны и не вписываются в иерархическую схему. Пример: бильярдный стол с шарами и физикой. Каждый шар хранит и изменяет состояние.
Если Вы считаете, что она здесь не нужна, то стоит применить тот подход, который на Ваш взгляд будет наилучшим. Я обеими руками за то, чтобы подходы и инструменты применялись разумно, а не бездумно.
— Переопределяя очередной метод в большой иерархии, программист не может быть уверен, что не нарушит деятельность объекта на каком-то уровне
На мой взгляд, ООП в данном случае вообще ни при чем. Так же можно сказать и про то, что программист может поменять процедуру и не быть уверенным в том, что все будет работать хорошо. Тут проблема явно в другом.
Автор, вы слишком много аспектов попытались описать в одной статье. ООП, декомпозиция предметной области, проектирование, шаблоны проектирования бизнес приложений каждая из этих тем может потянуть минимум на небольшую книгу.
Описание всех этих аспектов, пускай и в компактном виде, но в одном месте — было одной из целей данной статьи.
И было бы здорово перенять положительный опыт и рисовать классы и методы в UML.
У вас похожий подход, «XACML простой», а затем, предположительно, многостраничное пояснение «простых моментов» :)
Такое многостраничное объяснение я сделал для того, чтобы читатель смог правильно понять как все устроено. Понять основные принципы, которые на мой взгляд действительно просты.
Например, PolicySet может содержать вложеный PolicySet, который в свою очередь является «контейнером» для других PolicySet'ов и т.д., соответственно финальная иерархия будет достаточно сложной для понимания (на каждом уровне свой combining algorithm и т.д.)
Да, они могут вкладываться друг в друга сколько угодно. Но это сложность не XACML, это сложность бизнес-правила, которое представляет собой такую громоздкую иерархию условий. XACML в данном случае лишь показывает свою гибкость, раз позволяет описывать бизнес-правила любой сложности.
Все еще легко? Тогда насколько хорошо вы сможете объяснить факт существования следующей таблицы? :)
Тут просто показано то, как различные алгоритмы комбинации комбинируют четыре возможных результата вычислений. Мне кажется, что тут нет ничего сложного.
Мы ведь говорим о системе, которая может быть life-critical. Соответственно, один из вопросов: сможет ли Администратор быть на все 100% уверен в своем наборе политик проведя несколько «точечных» тестов с несколькими контекстами?
Я считаю, что может. Тестирование это лишь один из вариантов проверки. К этой задаче можно подойти по разному автоматически анализируя политики и возможные атрибуты.
Основное отличие в том, что Oracle заранее не знает, какие значения у лидирующего столбца в индексе, чтобы спускаться по дереву к каждому левому значению, и поэтому не знает где очередное начинается и где заканчивается, поэтому ему нужно отлавливать, когда значение лидирующего в branch-блоках изменяется и брать его уже для прохода по leaf-блокам, а остальные leaf-блоки skip'ает.
В принципе можете прочитать тут и статью и комментарии: richardfoote.wordpress.com/2008/03/10/index-skip-scan-does-index-column-order-matter-any-more-warning-sign/
Спасибо за пояснение и ссылку, очень познавательно. Я попробовал графически выразить свое понимание принципа работы ISS. Если я ошибся поправьте меня пожалуйста:
— представим что есть составной индекс (CHAR, NUM) и идет поиск строк с условием NUM = 2.
Соответственно при IRS мы будем заходить сразу с верхними и нижними границами по каждому из 10 значений полученных из xt_nums. А Index skip scan, при сработавшем Join elimination, вычитывает весь индекс IX_BIG_TAB, а не спускается по дереву как IRS.
Я предполагал, что INDEX SCIP SCAN (ISS) логически разобьет индекс IX_BIG_TAB на 10 небольших индексов и уже последовательно пройдется по ним, используя access(«T».«DT»>=SYSDATE@!-.01 AND «T».«DT»<=SYSDATE@!). Т.е. сделает подобие IRS 10 раз, и, логически получится тоже самое что и в шагах 3-5 из запроса без join elimination. Но, судя по вашим словам, ISS отработает на подобии INDEX FULL SCAN раз ему придется вычитывать весь индекс IX_BIG_TAB?
Буду очень признателен если Вы поподробнее поясните это.
Вообще-то этот пример я как раз делал на 11.2. У вас, наверное какая-нибудь низкая версия типа 11.2.0.1 — 11.2.0.2 — это заметно по 0 в стоимости INDEX UNIQUE SCAN, насколько помню это в каком-то промежуточном патче было исправлено.
Я пробовал на Oracle 11.2.0.4.0. Параметр optimizer_index_cost_adj = 100 (значение по умолчанию).
Попробовал выполнить запрос используя Ваш хинт, и получил такой же план как и в Oracle 12.1, но его стоимость оказалась выше чем у других планов для Oracle 11.2:
то видно, что действительно, cost второго запроса ниже, не смотря на то, что сам запрос более сложный. Но, получается, что шаги 3-5 во втором случае тоже самое, что и шаг 3 в первом случае и, помимо этого, во втором случае присутствует еще один цикл, в то время как в первом случае происходит batched table access. Почему же cost так сильно отличается и во втором случае он в несколько раз меньше?
Кстати, в Oracle 11.2 запросы получаются немного другие и их cost одинаков:
Вообще, советую прочитать Cost-Based Oracle fundamentals Джонатана Льюиса. Ее просто необходимо прочесть наряду с его же «Oracle Core», если хотите заниматься оптимизацией производительности.
Установил Oracle 10.2, проверил еще раз — трансформация работает с обоими вариантами синтаксиса. Поправил текст в статье, спасибо.
Все-таки, даже судя по документации, у синтаксиса ANSI-соединений больше возможностей, чем у традиционного синтаксиса. На мой взгляд, было бы странно в таком случае приводить запрос к традиционному синтаксису. Тем более, Вы сами отметили, что это происходит не во всех случаях. Но если это действительно так — не могли бы Вы рассказать, в какой момент выполнения запроса происходит это преобразование? И еще больше я был бы признателен за какую-либо ссылку на документацию по этому вопросу.
Еще раз хочу подчеркнуть, что одних ролей вам оказалось недостаточно и вам пришлось «зашивать» в код те проверки, которые нельзя сделать в RBAC. Если во всей системе у вас будет всего лишь несколько таких проверок и они никогда не будут меняться, то тогда вам действительно будет дешевле использовать RBAC.
Но, если бизнес-требования будут более сложными и будут требовать проверки других атрибутов, такие проверки вам тоже придется «зашивать» в код. Что если вам нужно дать разрешение менять сущность, но некоторым пользователям должны быть доступны для изменения не все атрибуты, а лишь некоторая их часть? И что если вам нужно учитывать не только пользователя, но и время, ip-адрес, или еще какие-либо атрибуты субъекта и объекта, сравнивать их между собой или с динамически вычисляемым значением? Все это тоже придется «зашивать» в код, и у вас появятся все те проблемы, что я пытался показать в статье. А если эти правила еще и постоянно меняются то для их изменения потребуется привлечь программиста, протестировать изменения, выпустить новую версию приложения, обновить ее у заказчика — все это будет долго и дорого.
В случае ABAC инфраструктура просто получает все текущие атрибуты и проверяет их, используя заданные администратором в «текстовом» виде правила, менять которые дешево.
Грубо говоря, где-то на инфраструктурном уровне это может выглядеть, как: accessEngine.Check(action, subject, object, environment).
Об этом более углубленно я постараюсь рассказать в следующей статье, в которой буду разбирать существующий стандарт — XACML.
На вопрос «зачем» — я как раз и пытался дать ответ в этой обзорной статье, и, как мне кажется, это не плохо получилось.
Если вы считаете, что у вас все проще и вам это не нужно, то ABAC для вас будет действительно избыточен. Я не собираюсь вам ничего продавать, это делают другие, если вы изучите ссылки, приведенные в конце статьи, вы увидите интересные, востребованные на рынке примеры.
Я лишь хочу познакомить вас и других читателей с тем, что еще существует, чтобы у вас был выбор при принятии решения.
То что вы описываете — уже не классический RBAC. В RBAC разрешения вешаются только на роли, субъект в определении разрешений не участвует. Тем более, вы предлагаете «хардкодить» роли в виде классов. В ABAC мы просто описываем какими значениями должны обладать те или иные атрибуты для выполнения действия. А их значения вычисляются в момент проверки прав доступа инфраструктурой. Никакого «хардкода».
Можете считать отсылкой к этому текст о том, что инструменты бывают разные и для разных целей нужно применять свои. Если уж более подробно описывать минусы ООП, то нужно описывать минусы и плюсы и других подходов, и все это делать на хороших примерах, чтобы было хорошо понятно всем. А это большая, интересная тема, но для отдельной статьи.
Если переопределяется метод базового класса, то должно быть очевидно, что такой метод может где-то использоваться и полагаться на то, что это не так совершенно неправильно. Т.е. если в случае с ФП нужно поискать — используется ли функция где-нибудь или нет, то в случае с переопределенными методами даже искать ничего не надо — нужно просто считать, что они точно где-то используются. Получится та же проблема, что и в случае изменения поведения функции, которая используется другими функциями.
Если это не брать в расчет и бездумно что-то менять, то не стоит удивляться, что что-то ломается. По-Вашему получается, что если болгаркой отпилить палец, то виновата болгарка.
В случае функционального подхода можно представить иерархию функций:
И предположить, что функция funcX сделана другим автором, который потом берет и меняет ее поведение на:
В этом случае у нас тоже может все поломаться и без всякого ООП.
Жаль, что это статья не смогла Вам угодить. Надеюсь, в какой-нибудь другой раз все будет иначе.
Если Вы используете чужую процедуру, исходного кода которой у Вас нет и полагаетесь на ее поведение, что произойдет если ее поведение поменяется? У Вас ничего не поломается все равно?
Тут просто существует общая проблема изменения поведения кода, который уже где-то используется.
Действительно, мысли раскрыть эту тему были — но, прикинув объем, я решил эту тему не затрагивать. Так можно было бы углубляться до бесконечности. Поэтому за основу была взята наиболее популярная, на мой взгляд, концепция.
Мне кажется, что ООП и ФП не противостоят друг другу, они о разных вещах. Можно одинаково успешно пользоваться и тем и другим.
Я думаю, это могло бы быть хорошей темой для отдельной статьи.
Серебряной пули вообще не существует. Для каждой задачи лучше всего подходит какой-то свой набор инструментов.
Я и не говорил, что они будут жить грустно или не будут работать. Я говорил, что у всего есть своя стоимость. И в зависимости от задач, стоимость применения ООП или реляционного подхода будет отличаться.
Если Вы считаете, что она здесь не нужна, то стоит применить тот подход, который на Ваш взгляд будет наилучшим. Я обеими руками за то, чтобы подходы и инструменты применялись разумно, а не бездумно.
На мой взгляд, ООП в данном случае вообще ни при чем. Так же можно сказать и про то, что программист может поменять процедуру и не быть уверенным в том, что все будет работать хорошо. Тут проблема явно в другом.
Да, верно — имелось ввиду именно это. Хотел поправить и пропустил. Благодарю.
Описание всех этих аспектов, пускай и в компактном виде, но в одном месте — было одной из целей данной статьи.
Спасибо за замечание, учту на будущее.
Такое многостраничное объяснение я сделал для того, чтобы читатель смог правильно понять как все устроено. Понять основные принципы, которые на мой взгляд действительно просты.
Да, они могут вкладываться друг в друга сколько угодно. Но это сложность не XACML, это сложность бизнес-правила, которое представляет собой такую громоздкую иерархию условий. XACML в данном случае лишь показывает свою гибкость, раз позволяет описывать бизнес-правила любой сложности.
Тут просто показано то, как различные алгоритмы комбинации комбинируют четыре возможных результата вычислений. Мне кажется, что тут нет ничего сложного.
Я считаю, что может. Тестирование это лишь один из вариантов проверки. К этой задаче можно подойти по разному автоматически анализируя политики и возможные атрибуты.
Спасибо за пояснение и ссылку, очень познавательно. Я попробовал графически выразить свое понимание принципа работы ISS. Если я ошибся поправьте меня пожалуйста:
— представим что есть составной индекс (CHAR, NUM) и идет поиск строк с условием NUM = 2.
Я предполагал, что INDEX SCIP SCAN (ISS) логически разобьет индекс IX_BIG_TAB на 10 небольших индексов и уже последовательно пройдется по ним, используя access(«T».«DT»>=SYSDATE@!-.01 AND «T».«DT»<=SYSDATE@!). Т.е. сделает подобие IRS 10 раз, и, логически получится тоже самое что и в шагах 3-5 из запроса без join elimination. Но, судя по вашим словам, ISS отработает на подобии INDEX FULL SCAN раз ему придется вычитывать весь индекс IX_BIG_TAB?
Буду очень признателен если Вы поподробнее поясните это.
Я пробовал на Oracle 11.2.0.4.0. Параметр optimizer_index_cost_adj = 100 (значение по умолчанию).
Попробовал выполнить запрос используя Ваш хинт, и получил такой же план как и в Oracle 12.1, но его стоимость оказалась выше чем у других планов для Oracle 11.2:
Видимо различия в каких-то еще параметрах.
Проверил все планы запросов для Oracle 11.2 получив их через dbms_xplan.display_cursor и все совпало.
Если посмотреть на планы запросов в Oracle 12.1:
1) c join eliminate
2) без join eliminate
то видно, что действительно, cost второго запроса ниже, не смотря на то, что сам запрос более сложный. Но, получается, что шаги 3-5 во втором случае тоже самое, что и шаг 3 в первом случае и, помимо этого, во втором случае присутствует еще один цикл, в то время как в первом случае происходит batched table access. Почему же cost так сильно отличается и во втором случае он в несколько раз меньше?
Кстати, в Oracle 11.2 запросы получаются немного другие и их cost одинаков:
1) с join elimination
2) без join elimination
Эти книжки как раз на очереди.
Все-таки, даже судя по документации, у синтаксиса ANSI-соединений больше возможностей, чем у традиционного синтаксиса. На мой взгляд, было бы странно в таком случае приводить запрос к традиционному синтаксису. Тем более, Вы сами отметили, что это происходит не во всех случаях. Но если это действительно так — не могли бы Вы рассказать, в какой момент выполнения запроса происходит это преобразование? И еще больше я был бы признателен за какую-либо ссылку на документацию по этому вопросу.
Но, если бизнес-требования будут более сложными и будут требовать проверки других атрибутов, такие проверки вам тоже придется «зашивать» в код. Что если вам нужно дать разрешение менять сущность, но некоторым пользователям должны быть доступны для изменения не все атрибуты, а лишь некоторая их часть? И что если вам нужно учитывать не только пользователя, но и время, ip-адрес, или еще какие-либо атрибуты субъекта и объекта, сравнивать их между собой или с динамически вычисляемым значением? Все это тоже придется «зашивать» в код, и у вас появятся все те проблемы, что я пытался показать в статье. А если эти правила еще и постоянно меняются то для их изменения потребуется привлечь программиста, протестировать изменения, выпустить новую версию приложения, обновить ее у заказчика — все это будет долго и дорого.
В случае ABAC инфраструктура просто получает все текущие атрибуты и проверяет их, используя заданные администратором в «текстовом» виде правила, менять которые дешево.
Грубо говоря, где-то на инфраструктурном уровне это может выглядеть, как: accessEngine.Check(action, subject, object, environment).
Об этом более углубленно я постараюсь рассказать в следующей статье, в которой буду разбирать существующий стандарт — XACML.
Если вы считаете, что у вас все проще и вам это не нужно, то ABAC для вас будет действительно избыточен. Я не собираюсь вам ничего продавать, это делают другие, если вы изучите ссылки, приведенные в конце статьи, вы увидите интересные, востребованные на рынке примеры.
Я лишь хочу познакомить вас и других читателей с тем, что еще существует, чтобы у вас был выбор при принятии решения.