Кілька класів в одному файлі .cs - добре чи погано? [зачинено]


30

Чи доцільно створювати декілька класів у файлі .cs або кожен файл .cs має індивідуальний клас?

Наприклад:

public class Items
{
    public class Animal
    {
    }

    public class Person
    {
    }

    public class Object
    {
    }
}

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

Відповіді:


30

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

  • ви розробляєте кластерний кластер (частіше зустрічається в Objective-c), тому може бути розумним використовувати підхід часткового класу
  • вам потрібна перерахунок, який використовується лише з відкритим API батьківського класу. У цьому випадку я вважаю за краще, щоб публічний перелік оголошувався всередині батьківського класу, а не забруднював мій простір імен. Енум, будучи «внутрішнім перерахунком», ефективно призводить до надання йому чітко визначеної сфери.

Якщо ви сформулюєте це питання дещо інакше і запитаєте про "Чи повинен я помістити кожен простір імен - клас рівня у свій файл", то моя відповідь буде "так".

При розробці класів ми дотримуємось єдиного принципу відповідальності. Читання коду стає набагато простіше, якщо його форма слідує його семантиці, отже, розбиття файлів за класом доцільне.

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

Наступним важливим аспектом є управління джерелами та об'єднання. Тримаючи класи окремо, ви уникаєте великих клопотів, коли вносяться зміни до одного файлу, оскільки окремі класи потрібно змінити.


1
Я погоджуюся, але тоді внутрішні класи дуже рідкісні в моєму досвіді. Якщо бути справедливим, насправді не так багато, що дійсно може виправдати внутрішні класи, єдиний я знаю про IEnumerable класів, де ви насправді не стосуєтесь до фактичного класу, доки ви можете його перерахувати. У всіх інших випадках кожен клас повинен отримати власний файл. Якщо з інших причин через проблеми з джерелом контролю.
Хомде

2
Додам, що внутрішні класи повинні бути рідкісним винятком і майже ніколи не повинні бути публічними.
Джош

Так, я вчить мене за те, що я так швидко не переймаюсь, внутрішні класи - це добре, проте питання про те, чи варто використовувати внутрішні класи - це інше питання :)
krystan honor

11

Щоб бути жорстоко чесним, будь ласка, не додайте до файлу більше одного кореневого класу. На моїй останній роботі були файли не лише з декількома класами, але з декількома просторами імен, і це поширювалося на кілька тисяч рядків коду. Дуже складно спробувати слідувати.

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

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

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


3
О боже - це звучить жахливо.

Чому ти запитуєш? Хтось порушив вас, і ви хочете запитати, чому?

Зачекайте ... ви згадували невеликий анекдот про мою останню роботу? Якщо так, я неправильно зрозумів і прошу вибачення за таке.
Джессі К. Слікер

Погодьтеся повністю. Я працюю над проектом, де більшість файлів мають принаймні 4 класи на файл. А деякі мають до 22 класів + 1 інтерфейс на файл.
L_7337

7

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

Наприклад, я вважаю, що при використанні Fluent NHibernate легше, якщо я зберігаю EntityіEntityMap в одному файлі, незважаючи на те, що мої інструменти можуть сказати про це.

У більшості випадків це просто ускладнює пошук занять. Використовуйте економно та обережно.


1
Спеціально для Fluent NHibernate я вважав корисним зберігати їх не лише в одному файлі, але і в тому ж класі. Усі мої сутності мають вкладений клас під назвою Map.
Джеймс Бенінгер

7

Простіше кажучи, це не так добре, як це зробити, і я скажу вам чому, трохи пізніше, коли ваше рішення стане великим, ви забудете, де такі класи, як ім'я файлу більше не буде представляти вміст, яке ім'я файлу AnimalPersonObject.cs це просто неможливо.

Впевнені, що ви зможете обійти це, скориставшись такими інструментами, як resharper, щоб перейти до типів, але 1 клас на файл (включаючи інтерфейси) справді є основою будь-якого стандарту коду, який я коли-небудь бачив, не лише в .net, а в Java та c ++ і безліч інших мов, тих, які не мають часто проблем з обслуговуванням, і ви знайдете молодших розробників, яким важко зрозуміти код.

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


3

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


-3

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

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