Язык программирования с гранулированным методом и доступом к собственности

StackOverflow https://stackoverflow.com/questions/3461578

Вопрос

Представьте себе что-то вроде этого:

import class B.*;


interface A supports A.testSum
{
   int sum( int a , int b ) access from B.calculator;

   testSum() { Assert(sum(1,1)==2); }

........


class B ...
{
  void calculator() {  A.sum(3,5); //ok }
  void someOtherMethod() { A.sum(0,3); //compile error }

Идея «поддержки» является вторичной, но актуальна, поскольку тест применяется к интерфейсу в этом случае (поэтому язык будет различать между тестом интерфейса, который все реализации должны пройти и тест на реализацию, что специфично для привалов внедрения.

Но важная идея, которую я хочу передать здесь семантику управления доступом; Обратите внимание, что A.Sum с «доступом от» ключевого слова может быть вызван только из метода B.Calculator. Все остальное обнаружено как ошибка времени компиляции. Идея здесь состоит в том, чтобы обеспечить применение архитектурных ограничений более гранулированным способом. Если вы не добавили «доступ от» или просто добавить «доступ с *», это означало бы поведение по умолчанию для того, чтобы позволить методу можно назвать из любого места. Какие архитектурные ограничения? Ну, та, которые находятся вручную при выполнении слоистой конструкции: слой (самый низкий уровень) используется из слоя B (промежуточный уровень), который в свою очередь, используемый из слоя C (высокий уровень). Но слой B не доступен от слоя A, и слой C не представляется ни на каком, либо B, но это общественности, иначе (это может быть то, что будет иметь прямой доступ)

Вопрос: Знаете ли вы любой язык (включая промежуточные языки источника к источникам), которые поддерживают вышеуказанную семантику? дополнительные очки для обсуждения, если этот вид семантики будет контрпродуктивным, опасно или просто поощрять плохой дизайн

Обновлять: Есть еще одно действительно важное использование случая для такого рода ограничения:

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

Таким образом, например, можно определить, что обработчик событий имеет только определенный набор видимых классов, он может взаимодействовать (или наоборот, определенный набор объектов, которые он не может прикоснуться)

Это было полезно?

Решение

Java поддерживает что-то в значительной степени то же самое.

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

Вы также можете сделать свои собственные привилегии и предоставить им определенные части кода. Например, чтобы открыть файл, код, который хочет получить доступ к файловым потребностям FilePermission для этого файла. Вы можете сделать любые разрешения, которые вы хотите, чтобы он мог сделать разрешение под названием SumPermission который Calculator Проверяет до суммирования и суммируя только только к любым людям, которые вы хотите. Защитные домены промежутся от классов, а не отдельных методов в классах, потому что целый класс обычно получается из одного источника. Модель на самом деле идет глубже, что вы предложили. Каждый класс на стеке (включая историю созданий потоков), ведущих к проверке безопасности, должен иметь разрешение, поэтому, если какой-то ненадежный код вызывает ваш код, который имеет SumPermission, он не пройдет проверку безопасности. Конечно, это только по умолчанию, всякий раз, когда вы делаете все, что нуждается в разрешениях, вы можете использовать doPrivileged Блок, чтобы сообщить о предстоящей проверке, чтобы проверить только ваши разрешения вместо ваших, так и ваших абонентов.

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

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

Это совершенно возможно и возможно для реализации надежного поведения между взаимно ненадежным кодом в Java, но, вероятно, сделает вашу работу намного проще, и работает на JVM, поэтому вы все равно сможете использовать библиотеки Java и библиотеки с любых других языков, которые используют JVM.

Другие советы

Это звучит как особый случай модель объекта-возможности. Отказ Возможно, есть языки, которые реализуют это каким-то образом.

Аналогичным образом, быстрый Google вокруг для «Безопасности уровня метода» привел меня к нескольким вещам, которые, кажется, приготовлено сообщество предприятия Java. Я думаю, что специализируя этот подход к простому методу, является своего рода бессмысленным. Если у вас не очень хорошая причина для этого, я думаю, что это, вероятно, плохая идея. Если вы действительно заинтересованы в том, чтобы сделать это по какой-то причине, то на самом деле модель должна быть, чтобы получить приемник, чтобы проверить, что источник вызова находится в некоторых разрешенных наборах.

В любом случае, это в основном ломая большинство моделей программирования довольно плохо. Вам было бы намного лучше укреплять предварительные условия и инварианты классов, чтобы убедиться, что любой вызов метода (из любой точки!) Является значимым или хорошо поведенческим. Если вы используете его для обеспечения заказа метода, который может быть достигнут с использованием проверки инвариантных (статически или во время выполнения) или теоретических моделей, таких как Интерфейсные автоматы.

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

module T
    def check
        raise unless self.is_a?(Ca)
        raise unless %r{in `good_func'} =~ caller.first #`
        true
    end
end

class Ca
    include T
    def good_func
        check
    end
    def bad_func
        check
    end
end

class Cb
    include T
    def good_func
        check
    end
    def bad_func
        check
    end
end

a = Ca.new
b = Cb.new

a.good_func
=> true
a.bad_func
=> (RuntimeError)

b.good_func
=> (RuntimeError)
b.bad_func
=> (RuntimeError)

При использовании модуля в виде смеси, self соответствует классу, которое includeS модуль. caller Возвращает текущую CALLSTACK и caller.first Получает в себя первую запись на CaultStack (то есть функции, которая называла этот).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top