Почему мы должны предпочтительно использовать первоклассные коллекции?

15

Согласно правилу № 4 « Object Calisthenics» Джеффа Бэй (RTF) в «Антологии ThoughtWorks», рекомендуется « Использовать первоклассные коллекции ».

Правило 4: Коллекции первого класса

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

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

и нам это нужно, чтобы мы были уверены в том, какой тип данных входит в коллекцию и что выходит.

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

Если я упускаю важное значение, пожалуйста, уточните.

Амог Талпалликар
источник
1
Amogh Talpallikar Я изменил правило 8 на правило 4, так как правило 8 на самом деле «Нет классов с более чем двумя переменными экземпляра».
Яннис
Кажется, в оглавлении сказано правило 8 , а затем назовем его правилом 4 в теле.
бесполезно
1
Лучшая ссылка cs.helsinki.fi/u/luontola/tdd-2009/ext/ObjectCalisthenics.pdf ?
Эд Джеймс
6
Это только я, или это правило неосуществимо, как написано? Я имею в виду, у вас есть класс с коллекцией, так что вы берете все остальное. Теперь ваш класс - это коллекция. Так что, если у вас есть другой класс, с этим классом, в нем есть коллекция, и ... вспенить, промыть, повторить.
mjfgates
@mjfgates: хмм ... Отличный момент! о чем по-настоящему подумать!
Амог Талпалликар

Ответы:

12

Безопасность типов - очень незначительная причина для использования первоклассных коллекций. По вашей ссылке:

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

Идея здесь в том, что если вы обнаружите, что ищете, фильтруете, проверяете или что-то еще, кроме семантики добавления / удаления / итерации в коллекции, код просит вас поместить его в свой собственный класс. Если вам нужно обновить только одно значение (после поиска), это, вероятно, относится к классу коллекции.

Обоснование этого довольно простое, коллекции имеют тенденцию передаваться. Вскоре у 4 разных классов появился собственный SearchByID()метод. Или вы получаете возвращаемые значения, как Map<Integer, String>с контекстом того, что хранится на этой карте. Первоклассная коллекция - это простое решение, которое стоит одного исходного файла. На практике, как только они будут созданы (для них также очень легко написать модульные тесты), любое изменение, касающееся коллекции, легко обрабатывается, например, когда SearchByIDтребуется взять GUID вместо int.

Стив Джексон
источник
8

... использовать отдельный класс для обёртывания коллекции и методы для добавления, удаления и изменения данных этой коллекции

Это не только гарантирует тип объектов, хранящихся в коллекциях, но и любые инварианты коллекций.

Деревья (красно-черные, AVL и т. Д.) Чувствительны к упорядочению, и их поведение зависит от перебалансировки, когда это необходимо. Производительность хеш-таблицы также будет зависеть от соответствующего повторного хеширования. Вы хотите не забывать проверять коэффициент загрузки каждый раз, когда вставляете в хэш-карту?

FWIW, текст довольно ясно об этом (и я отредактирую все это в вашем вопросе, так что никто не должен загружать этот RTF):

Каждая коллекция упакована в свой собственный класс, так что теперь поведение, связанное с коллекцией, имеет свой дом

Не имеет ничего общего с типами (или, следовательно, с универсальными), все связано с поведением коллекции с ее данными.

Бесполезный
источник
1

Простой ответ - «Нет», если вы используете язык, который поддерживает Generics. Потому что нет необходимости проверять тип, так как сама языковая функция довольно неплохо справляется с этим (из моего общего опыта Java).

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

java_mouse
источник
Я также думаю в аналогичных линиях. но должно быть что-то, примеры, которые я видел для этого, были на Java и C #, и оба поддерживают универсальные коллекции.
Амог Талпалликар
@AmoghTalpallikar: Моя цель была сделать это проще. Если мне не нужно переопределять какое-либо конкретное поведение структуры данных, я не буду настраивать.
java_mouse