2015-10-24 2 views
2

У меня есть ситуация, когда мне нужно ограничить доступ к классу. для дальнейшей разработки у меня есть два класса, скажем A и B, которые зависят от класса C, но A не нужно использовать полный интерфейс C, то же самое относится к B. Что я сделал, сделайте C реализовать два разных интерфейса, один интерфейс A может получить доступ, другой для B. Что я здесь делаю, правильно? или я должен просто документировать это? или есть ли лучший подход?ограничение доступа к интерфейсу класса в java

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

+0

Он делает то, что вы хотите, чтобы он сделал? Проходят ли ваши тесты? Тогда это правильно. Обратите внимание, что это никогда не помешает кому-либо вызвать метод, который не находится в интерфейсе, если он действительно хочет. Это будет мешать hiM: er делать это по ошибке. –

+0

Это была моя проблема, она работает, (по крайней мере, на данный момент), но разве у меня есть интерфейс для класса, который я не хочу, чтобы третья сторона использовала доступную в такой ситуации? –

+0

делить контракт C на несколько интерфейсов и выставлять только соответствующий интерфейс в других частях кода. Я не вижу никаких проблем в этом подходе. –

ответ

1

В вашем дизайне нет ничего плохого. Но причиной вашего дизайна должен быть четкий дизайн, а не безопасность. Учитывая, что A и B имеют доступ к классу C (например, из-за C является публичным) они могут получить доступ ко всему объекту в целом: они могут просто привести объект, которую они получают, чтобы C и обращаться к нему:

public interface IA { 
    void f(); 
} 
public interface IB { 
    void g(); 
} 
public class C implements IA, IB { 
    public void f() { ... } 
    public void g() { ... }   
} 
public class A { 
    public void doSomething(IA anIA) { 
     C aC = (C) anIA; 
     aC.g(); // legal! 
    } 
} 

Это не проблема, потому что вы программист A, B и C. Вы доверяете себе, поэтому вам нужен четкий дизайн, но вам не нужна безопасность.

Даже если C не является общедоступным и A и B не могут получить доступ к классу напрямую, они все еще могут использовать отражение.

Так что если вы не можете доверять A и B, потому что они запрограммированы внешней стороной (например, они являются плагинами), вы не можете использовать эту конструкцию. Вам необходимо отправить объекты, которые действительно реализуют интерфейс, к которому вы хотите подключиться.

public class C { 
    public void f() { ... } 
    public void g() { ... } 

    public IA getAsIO() { 
     return new IA() { 
      public void f() { 
       C.this.f(); 
      } 
     }; 
    } 

    public IB getAsIB() { 
     // similar 
    } 
} 
public class A { 
    public void doSomething(IA anIA) { 
     C aC = (C) anIA; // illegal 
     aC.g(); 
    } 
} 
+0

Это действительно отвечает на мой вопрос выше. и я также понимаю, что я искал неправильные места, чтобы решить свою проблему после того, как я прочитал ваш ответ и комментарии JB Nizets. , в то время как это то, что от темы этого вопроса, что если я поворачиваю таблицы вокруг, то есть вместо методов вызова 'A' ​​в' C', определите функции в 'A', которые' C' может вызывать делать то, что он хочет, чтобы плагин –

Смежные вопросы