Чому ми бажано використовувати колекції першого класу?


15

Як правило, номер 4 об’єктної гімнастики Джеффа Бея (RTF) в «Антології ThoughtWorks», рекомендується « Використовувати колекції першого класу ».

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

Застосування цього правила просте: будь-який клас, який містить колекцію, не повинен містити змінних інших членів. Кожна колекція перетворюється на свій клас, тож тепер поведінка, пов'язана з колекцією, має дім. Ви можете виявити, що фільтри стають частиною цього нового класу. Також ваш новий клас може обробляти такі дії, як об'єднання двох груп разом або застосування правила до кожного елемента групи.

Що я можу зрозуміти з цього, це те, що ми повинні використовувати окремий клас, що завершує колекцію, та методами для додавання та видалення змін даних цієї колекції.

і нам це потрібно, щоб ми були впевнені, який тип даних потрапляє в колекцію і що виходить.

Якщо ми використовуємо загальну колекцію (мовами, де це застосовується), чи потрібно нам дотримуватися цього правила?

Якщо я пропускаю важливе значення, будь ласка, уточніть.


1
Amogh Talpallikar Я змінив правило 8 на правило 4, оскільки правило 8 - це фактично "Немає класів з більш ніж двома змінними примірника".
янніс

Здається, як правило 8 правила в змісті, а потім називає його правилом 4 у тілі.
Марно


6
Це тільки я, чи це правило не реалізоване, як написано? Я маю на увазі, у вас є клас із колекцією в ньому, тож ви виймаєте все інше. Тепер ваш клас - колекція. Тож якщо у вас є інший клас, у якого цей клас, у ньому є колекція, і ... мийте, промивайте, повторіть.
mjfgates

@mjfgates: хм ... Чудова точка! щось по-справжньому подумати!
Амо Талпаллікар

Відповіді:


12

Безпека типу - дуже незначна причина використання першокласних колекцій. З вашого посилання:

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

Ідея тут полягає в тому, що якщо ви виявите, що ви шукаєте, фільтруєте, перевіряєте чи що-небудь крім семантики додавання / видалення / ітерації колекції, код просить вас помістити її у свій клас. Якщо вам потрібно оновити лише одне значення (після пошуку), воно, ймовірно, переходить у клас колекції.

Міркування для цього досить прості, колекції, як правило, передаються навколо. Незабаром у 4 різних класах є свій SearchByID()метод. Або ви отримуєте значення, що повертаються, як Map<Integer, String>у контексті того, що зберігається на цій карті, позбавлене. Колекція першого класу - це просте рішення, яке коштує одного вихідного файлу. На практиці, як тільки вони є на місці (вони також дуже легко написати одиничні тести), будь-які зміни, що стосуються колекції, легко обробляти, як, наприклад, коли SearchByIDпотрібно взяти GUID замість int.


8

... використовувати окремий клас, завершуючи колекцію та методами додавати, видаляти модифіковані дані цієї колекції

Це набагато більше, ніж гарантує тип предметів, що зберігаються в колекціях, однак це також гарантує будь-які інваріанти колекції.

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

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

Кожна колекція перетворюється на свій клас, тож тепер поведінка, пов'язана з колекцією, має дім

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


1

Проста відповідь - «Ні», якщо ви використовуєте мову, яка підтримує Generics. Тому що немає необхідності перевіряти тип, оскільки сама мовна функція справляє досить непогану роботу в цьому (З мого досвіду Java generics).

Але якщо у вас є якісь ситуації, коли ви хочете налаштувати структуру даних, що задається мовою, ви можете створити клас обгортки навколо оригінальної структури даних та розкрити власні API та все ж використовувати базову реалізацію вихідної структури даних.


Я теж розмірковую в подібних рядках. але щось має бути, приклади, які я бачив для цього, були в Java та C # і обидва підтримують загальні колекції.
Амо Талпалікар

@AmoghTalpallikar: Моя думка полягала в тому, щоб зробити це просто. Якщо мені не потрібно перекривати якусь конкретну поведінку структури даних, я не буду налаштовувати.
java_mouse
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.