Как создать два интерфейса к классу Java одно только для чтения, одно чтение-запись?

Я пишу игровой механизм в Java для двух карточных игр плеера, для которых мои студенты собираются записать плеерам AI.

Плееры AI будут сменяться, играя в карты на их 'поле' часть 'таблицы' перед ними. Они могут напасть картой от их поля на карту в поле другого игрока. Карты могут быть поверхностью или победить.

Класс GameEngine позволяет плееру AI принимать его оборот путем вызова GamePlayer. TakeTurn (инженер GameEngine) метод. Игрок может попросить у игрового механизма поля игрока защиты, таким образом, плеер может принять решения на основе количества карт там и которые поверхность. Скажем, этим методом является GameEngine. GetDefendingField ()

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

У меня есть классы для Карты, Поле (ArrayList Карт), GamePlayer и GameEngine. Там какой-либо путь состоит в том, чтобы создать интерфейс для Поля так, чтобы GameEngine мог возвратить поле игрока защиты без способности плеера нападения изменить его? и без способности плеера нападения переделать поле игрока защиты во что-то, что может быть изменено.

У меня может быть GameEngine. GetDefendingField () возвращают интерфейс только для чтения в Поле, которое не может быть переделано к Полю?

tia,

Sh-

6
задан shindigo 2 March 2010 в 16:44
поделиться

6 ответов

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

Для такого интерфейса:

interface Info {
    String getInfoA();
    void setInfoA(String infoA);
    String getInfoB();
    void setInfoB(String infoB);
}

Вы можете создать обертку readonly, которая игнорирует сеттеры или выбрасывает исключения, например:

class ReadonlyInfo implements Info {
    final Info instance;
    ReadonlyInfo(Info info) { 
         if (null == info) { throw new InvalidArgumentException(); } 
         instance = info; 
    }
    String getInfoA() { return instance.getInfoA(); }
    void setInfoA(String infoA) { /** silent ignore */ }
    String getInfoB() { return instance.getInfoB(); }
    void setInfoB(String infoA) { throw new IllegalStateException(); }
}

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

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

11
ответ дан 8 December 2019 в 13:45
поделиться

Здесь вы говорите об основном модели-представлении-контроллере, где ваша модель - это карта и поле, контроллер - это GamePlayer и GameEngine, а представление пока еще не определено. Ваше поле - это ваша модель, и вы хотите создать 2 разных интерфейса, которые будут обращаться к модели поля, один только для чтения и один для чтения-записи. Ваша реализация чтения-записи, скорее всего, просто вернет объект Field. Ваша реализация только для чтения будет проходить через элементы в Поле и возвращать только те, к которым у них есть доступ, делая глубокую копию каждой возвращенной Карты в Поле.

2
ответ дан 8 December 2019 в 13:45
поделиться

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

1
ответ дан 8 December 2019 в 13:45
поделиться

Мне нравится идея использования безопасности типов и полиморфизма для управления такого рода контроль доступа во время компиляции, особенно при обучении.

Хороший способ приблизиться к этому - иметь два полевых интерфейса. Возможно, Field и MutableField, где последнее расширяет первое и добавляет методы изменения. Ваш FieldImpl, конечно, может реализовать и то, и другое.

Проблема, конечно же, в том, что вы хотите вернуть различные объявленные типы (Field или MutableField) из вашего игрового движка в зависимости от того, чье поле вы используете. Если у вас одна модель, вы можете использовать что-то вроде getMyField () и getOtherPlayerField (), поскольку из описания видно, что при вызове getField () человек точно знает, какое именно поле ему нужно.

2
ответ дан 8 December 2019 в 13:45
поделиться

Вы можете создать интерфейс только для чтения, который имеет только геттеры. Расширение этого интерфейса будет интерфейсом чтения-записи, который добавляет сеттеры.

1
ответ дан 8 December 2019 в 13:45
поделиться

Вы не можете определить интерфейс Java, который обеспечивает доступ только для чтения к полям / члены, поскольку это деталь реализации, определенная в классе. (Действительно, то, как вы храните данные внутри, является деталью реализации)

Я бы предложил создать две реализации вашего интерфейса Field, одну с доступом только для чтения, а другую с доступом для чтения / редактирования. Вы можете сделать так, чтобы каждый класс реализовал интерфейс Field, возможно, с классом AbstractField в качестве родительского класса каждого, чтобы охватить общие функции.

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

0
ответ дан 8 December 2019 в 13:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: