Нужен совет по структурированию интерфейсов - PullRequest
0 голосов
/ 23 декабря 2011

У меня есть структура, подобная следующей

   Interface A
   Interface B extends Interface A
   abstract Class C implements Interface B
   now concrete Class D extends Class C

Теперь я использую Интерфейс B в другом классе и возвращаю конкретный объект класса D.

Интерфейс B содержит геттеры и сеттеры и изменяетметоды.

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

Ответы [ 3 ]

1 голос
/ 23 декабря 2011

Одним из способов достижения этого было бы создание объекта-обертки только для чтения, который реализует интерфейс B, распространяет геттеры на обернутый объект и вызывает исключение (например, IllegalAccessEXception или InvalidStateException) из сеттеров и модификаторов.

0 голосов
/ 23 декабря 2011

Разработка превосходного предложения @rsp:

Создание интерфейса «только для чтения»

   public interface MyInterfaceRO {
      public int getFoo();
      public String getBar();
      // etc...
   }

Создание интерфейса «чтение-запись», соответствующего вашему B

   public interface MyInterfaceRW extends MyInterfaceRO {
      public void setFoo(int foo);
      public void setBar(String bar);
      // ...
   }

IMO, самый простой способ сделать то, что вы хотите (предотвратить изменение), это просто вернуть MyInterfaceRO.Вызывающий объект (если он не выполняет приведение) не будет иметь возможности вызывать setFoo (), фактически в своей IDE он даже не увидит .setFoo () в качестве опции.

Я не понимаюпочему вы действительно хотите вернуть тип B (мой RW выше), но, если вы это сделаете, вы застряли с вызывающей стороной, имеющей возможность видеть и вызывать setFoo ().Вероятно, вам лучше всего следовать прецеденту, установленному в коллекциях java, и генерировать исключение UnsupportedOperationException.Для удобства вы можете предложить метод

public boolean isModifiable ();

, но вы не можете заставить вызывающего его использовать и уважать его.

0 голосов
/ 23 декабря 2011

Похоже, вы имеете в виду шаблон проектирования Proxy: http://en.wikipedia.org/wiki/Proxy_pattern.

В вашем случае вы хотите, чтобы интерфейс B поддерживал получение / настройку определенных полей, но вы хотите, чтобы он предоставлял определенный прокси для настройки и получения этих полей, а не непосредственно редактировал их.

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

public interface Proxiable {

    public static interface Proxy
    {

    }


    public ProxySub getProxy();
}

Таким образом, ваш интерфейс определяет прокси-интерфейс - и любой, кто расширяет ваш интерфейс, должен будет предоставить прокси-провайдера.

Однако, если у вас нет ДЕЙСТВИТЕЛЬНО веской причины для этого, вы можете переоценивать. Интерфейсы достаточно универсальны, так что обычно достаточно оставить детали методов HOW реализованными для подклассов, вместо того, чтобы форсировать эту надстройку на уровне интерфейса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...