Начини за сигнализиране, че API връща немодифицируема/неизменна колекция

Освен документирането (очевидно то също трябва да бъде документирано), използването на специален тип връщане (пазя се да се ограничавам до ImutableX) или потребителят да разбере по време на изпълнение, има ли някакъв друг начин да се каже на потребителите за API, че колекцията, която получават от споменатия API, е непроменяема/неизменна?

Има ли някакви конвенции за именуване или анотации на маркери, които универсално сигнализират за едно и също нещо?

Редактиране: Unmodifiable и immutable не означават едно и също нещо, но за целите на този въпрос те са достатъчно сходни. Въпросът основно се свежда до уведомяване на потребителя, че върнатият обект не спазва напълно своя договор (т.е. някои общи операции ще хвърлят изключение по време на изпълнение).


person Celos    schedule 03.06.2015    source източник
comment
Unmodifiable и immutable може да означава различни неща в Java; Collections.unmodifiableList например връща обект List, който не може да се променя, но не е неизменен - ​​не можете да извикате add или remove или set върху него, но съдържанието му може да се промени по друг начин.   -  person user253751    schedule 03.06.2015
comment
@immibis, наясно съм, но благодаря, че го посочи. Промених въпроса с кратко обяснение.   -  person Celos    schedule 03.06.2015


Отговори (4)


Не е обща конвенция за именуване, но може да ви е интересно да използвате тази @Immutable анотация: http://aspects.jcabi.com/annotation-immutable.html Освен целта на документирането, този механизъм също така ще проверява дали вашият обект е наистина неизменен (по време на неговото създаване) и ще хвърля изключение по време на изпълнение, ако не е.

person flogy    schedule 03.06.2015
comment
между другото, Immutable присъства в много възприетия артефакт на google findbugs maven. - person Victor Sorokin; 03.06.2015

Добро и многословно решение би било да направите свой собствен клас обвивка UnmodifiableCollection и да го върнете:

public UnmodifiableCollection giveMeSomeUnmodifableCollection() {
    return new UnmodifiableCollection(new LinkedList());
}

Името на връщания тип би било достатъчно, за да се направи многословно изявление относно непроменимостта на колекцията.

person Krzysztof Cichocki    schedule 03.06.2015

  1. Документирайте го наистина
  2. Осигурете API за проверка дали дадения обект е неизменна колекция
  3. Върнете колекция в обвивка, която ще съдържа информация дали колекцията вътре в нея е променлива или не - любимото ми решение
  4. Ако е възможно, не използвайте колекция с неизменяеми и неизменяеми колекции, а изберете една от тях. Резултатите винаги могат да бъдат неизменни, тъй като те са резултати - защо да ги променяте. Ако има такава необходимост, въпрос на един ред е да копирате колекция в нова, променлива и да я модифицирате (напр. за верижна обработка)
person Antoniossss    schedule 03.06.2015
comment
За вашата трета точка, предполагам, че предимството на някои обвивки с getX и isMutable методи пред връщането на ImmutableX е, че getX може да върне собствен интерфейс за колекция. Може ли по-подробно? - person Celos; 03.06.2015
comment
Определено, така че няма нужда да преоткривате колелото и да предоставяте колекции със специално предназначение. Друго предимство е гъвкавостта. Ако в бъдеще попитате в SO как да уведомите потребителите на API за други метаданни на колекциите си, ще знаете какво да направите :) Има разлика между неизменни и непроменими - обвивката ще изчисти, може да изчисти това. - person Antoniossss; 03.06.2015
comment
Аз съм на оградата относно третия вариант. От една страна, той изпълнява това, което е поискано, от друга добавя леко сложен слой абстракция и принуждава програмиста да се справи с това, което по същество е грешка в бизнес логиката (т.е. ако е променливо, тогава добавете елемент, иначе .. какво? нова, изрично променлива/променлива колекция би била по-добра и в двата случая). - person Celos; 03.06.2015
comment
Това е моето 4-то решение - да обединя резултатите в един и същи тип колекции. Най-просто, но дали е възможно във вашия случай - решавате вие - person Antoniossss; 03.06.2015

Писането на @Immutable анотация за върнатия тип на метод е най-добрият подход. Той има множество предимства:

  • анотацията документира значението за потребителите
  • инструмент може да провери дали клиентският код спазва анотацията (т.е. този клиентски код няма грешки)
  • инструмент може да провери дали кодът на библиотеката спазва анотацията (тоест този код на библиотеката няма грешки)

Нещо повече, проверката може да се извърши по време на компилиране, преди да изпълните кода си.

Ако искате проверка по време на компилиране, можете да използвате Проверка за неизменност на IGJ. Той прави разлика между @Immutable< /a> препратки, чиято абстрактна стойност никога не се променя, и @ReadOnly препратки, върху които не могат да се извършват странични ефекти.

person mernst    schedule 03.06.2015