Чи вкладені класи недостатньо оцінені?


9

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

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

Ось два приклади, які я щойно використав для них: https://gist.github.com/3975581 - перший допоміг мені зберегти тісно звільнені ієрархічні речі разом, другий дозволив надати працівникам доступ до захищених членів ...


Я просто хочу сказати спасибі за відповіді / думки - я не впевнений, як вибрати відповідь, тому я залишу її, поки я обдумую поради, які я отримав і перегляну ...
Аарон Анодід

Відповіді:


6

Я б не назвав це "рідко використовуваним механізмом проектування" - принаймні, не універсальним: хоча є магазини, де деякі учасники можуть нахмуритися, використовуючи вкладені класи, це зовсім не малозрозуміла особливість.

Хоча існування класів із видимістю збірки та введення лямбдаз значно зменшило потребу вкладених класів * , вони залишаються дійсним вибором дизайну. Хоча є деяке перекриття внутрішніх класів всередині простору імен, вкладена класова функція унікальна тим, що дозволяє повністю заховати клас в іншому класі.


* Використання подібної функції на Java набагато вище, оскільки інших альтернатив, наявних у C #, немає на Java.


Тож чи добре заховати клас повністю в іншому класі відповідно до суті дизайну OOP?
Maxood

1
@Maxood Клас добре приховати, якщо ви можете його приховати. Користувач вашого API повинен якомога менше знати про те, як реалізується ваш API.
dasblinkenlight

3

Подумайте на хвилину, що ви пишете клас всередині іншого класу, який ніколи не буде використовуватися ніде у вашій програмі. Тому що якби ви його використовували в іншому місці, ви зробили б це звичайним публічним класом, як і всі інші.

Тож річ, яка повинна зробити OOP чудовою (повторне використання), тут відсутня. Крім того, що ви могли досягти з вкладеним класом, якого ви не могли досягти звичайними методами та приватними членами в батьківському класі?

Про корисну схему програмного забезпечення, що використовує вкладені класи, дивіться тут .


10
Я ніколи не купував речі про багаторазове використання, принаймні, не так, як зазвичай це робиться. (1) Виклик до існуючих код / ​​класів (про які ви, як видається, розмовляєте, і які, як правило, я бачу як визначення повторного використання), абсолютно не має нічого спільного з OOP, це просто основна модульність. (2) Поліморфізм підтипу, що є визначальною характеристикою OOP, дозволяє повторно використовувати клієнтський код , роблячи конкретну реалізацію нерелевантною , тобто працює точно так само, доступний чи ні конкретний клас. IOW це повторне використання я купую, але воно також працює з вкладеними класами.

1
Я б сказав, що також існує ізоляція простору імен, що надається батьківським класом - тому, якби ви хотіли, і класи A, і B могли мати вкладений клас "Params" та доступ до непублічних членів класу, що містить. Чи не обидві вони причини внутрішніх класів, які використовуються поза класом?
Аарон Анодід

@AaronAnodide Це має бути відповіддю про хороший спосіб використання вкладених класів. Саме так / чому я їх використовую, це допомагає впорядкувати код.
Ізката

2

am I going down an inherintly bad path

Я думаю, що у вашому другому прикладі (підкласи робітників) ви точно є. Ви зіставили кожен підклас до конкретного стану в суперкласі. Отже, щоразу, коли ви хочете додати стан до суперкласу, вам потрібно буде змінити три місця (додати стан до суперкласу, додати новий підклас та змінити конструктор похідного класу, щоб додати підклас до списку ).

Використання вкладених класів для доступу до приватних членів видається дійсним (я ніколи особисто цього не робив), але ваш конкретний випадок тут не працює.

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

Якщо, звичайно, вам не знадобилося здійснити обеззброєну руку. Тоді створення руки, виконуючи наступне, заплутане, оскільки немає тіла / тулуба / сторони. (Також помітьте заплутану оболонку).

arm newArm = new Body.torso.side.arm("");

1

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


1

На мій досвід, вкладені заняття

  • Повернувся, щоб переслідувати мене
  • Були використані, коли я хотів вирізати кути
  • Зробив тестування кошмару
  • Негативно вплинув на розділення проблем та загальний дизайн

Короткий огляд вашого класу, і я відразу думаю, що:

  • Боляче дивитися на це, бо клас величезний
  • Я не можу випробувати «пальці», не дуже сильно створивши все тіло
  • Я не можу мати кілька реалізацій торсу. Здається, це не очевидно в контексті "людського тіла", але в іншому сценарії це стане очевидним.

Чому б не розділити свій клас на кілька класів і не дати їм окремих просторів імен. Напр

WindowsGame1.PhysicalModel.UpperBody
WindowsGame1.PhysicalModel.LowerBody
WindowsGame1.PhysicalModel.UpperBody.Arms
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.