Сделайте методы библиотеки не видимыми для внешнего доступа, но видимыми для библиотеки - PullRequest
1 голос
/ 23 ноября 2011

Я разработал библиотеку, и мне нужно, чтобы пользователи этой библиотеки могли получить доступ только к одному классу (с несколькими методами).

С другой стороны, мне нужно, чтобы этот класс имел доступ ко всем методам библиотеки -классы.

Одно из решений - поместить все классы в один пакет и сделать все методы защищенными, но мне не нравится иметь библиотеку с разными классами для разных целей.(например, класс для использования видео и класс для анализа XML) в одном пакете.

Сейчас:

com.aracem.library:
- класс 1
-класс 2
- класс 3
- класс 4
- класс 5

Я хочу что-то вроде этого

com.aracem.library:
- класс 1
com.aracem.library.video
- видео класса 2
com.aracem.library.xml
- класс 3 xml
- класс 4 xml

Как определитьметоды классов 2, 3, 4 (в примере), чтобы позволить классу 1 получить доступ к методам, но не позволить пользователям библиотеки получить доступ к этим методам?

1 Ответ

9 голосов
/ 23 ноября 2011

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

Все классы должны быть защищены пакетами. Чтобы иметь возможность вызывать свои собственные классы из другого пакета, создайте открытые интерфейсы в ваших пакетах и ​​заставьте свои классы реализовывать эти интерфейсы. Экземпляры классов должны создаваться только вашей фабрикой. Положите фабрику за пакет. Сам фабричный класс является публичным.

Теперь у клиентского кода есть только одна возможность доступа к вашим классам: создать их экземпляр с помощью вашей фабрики. Но завод должен проверить права доступа звонящего. Это просто: new Throwable().getStackTrace()[0] возвращает вам элемент трассировки стека вашего абонента. Изучите его пакет и решите, следует ли вам продолжать или бросить Exception, например, SecurityException.

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

...