2010-02-02 2 views
18

У меня есть метод List<Foo> getFoos(), который получает данные с удаленного сервера и возвращает его.Допустимо ли возвращать unmodifiableList или я должен возвращать массив?

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

Первый подход состоял в том, чтобы вернуть массив и подменить метод подписи Foo[] getFoos(). Но он более распространен в java и более удобен для пользователя для работы с коллекциями, поэтому я сменил подпись на List<Foo> getFoos(). Этот метод всегда возвращает

Collections.unmodifiableList (originalList)

Таким образом, когда пользователь попытается изменить список, он получит RuntimeException.

Есть ли какие-либо рекомендации по дизайну api в подобных случаях?

ответ

23

Collections.unmodifiableList вполне приемлем и должен быть быстрее (нет необходимости создавать массив).

Редактировать - Что касается дизайна API, вы должны просто сделать свой JavaDoc понятным! Люди, которые используют метод, не читая его док, заслуживают удивления: p

+0

Я больше забочусь о том, будут ли это путать пользователей и заставить их думать, что они могут изменить список, и все данные синхронизации будут выполняться автоматически (синхронизация с сервером я имею в виду). – Roman

+1

Конечно, после первого RuntimeException все запутанные пользователи, безусловно, поймут, что они не могут сделать это так просто :) – Roman

+0

@Roman В вашей документации вам просто нужно, чтобы возвращался немодифицируемый список. – Poindexter

0

Если вы хотите создать специализированное специализированное свойство из существующего объекта или List в этом случае, почему бы не попытаться расширить или скрыть его и заставить соответствующие аксессуры бросать исключение?

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

+1

Я не думаю, что расширение List - лучший подход, чем просто использование unmodifiableList. Это больше работает, и очень вероятно, что ваша собственная реализация не так хороша, как та, которая создана разработчиками Java. –

+0

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

2

Я бы также сказал, что это вполне приемлемо и намного лучше, чем возвращение массива (что предложение some должно рассматриваться как устаревший тип вообще). Если вы хотите более подробно рассказать об этом в API, вы можете подумать о возврате ImmutableList от Google Collections.

+0

Да, коллекции Immutable * идеально подходят для такого рода вещей. – ColinD

+1

Я не уверен, что это можно назвать хорошей практикой для использования классов из сторонних библиотек в API (даже если это написано Google). – Roman

+0

Если эта библиотека не сделала публичного обещания о вечной обратной совместимости, сродни JDK, вы были бы правы. Однако в случае Google Collections вы в безопасности. –

1

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

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

0

Если у вас есть полная свобода, и, похоже, это так, то вам не нужно выбирать между массивом или списком, а скорее возвращать итератор. Это также поможет, если вам нужна уникальность, поэтому вместо возврата Set - все равно возвратите итератор.

+2

Вы действительно думаете, что получение итератора более удобно для пользователя, чем получение списка или набора или массива? (подсказка: что, если ему нужно повторить дважды? что, если ему нужно получить размер? Что делать, если ему нужно работать со всей коллекцией, а не с конкретными элементами, то есть делать операции типа xxxAll() ...) – Roman

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