#c_sharp #net
Вот смотрю я на некоторые классы стандартных библиотек и думаю, а почему их не сделали вложенными и публичными, чтобы подчеркнуть их "ареал". Например, есть DataTable и DataRow. DataRow нигде, вроде, не используется вне контекста DataTable и более того, отсутствует конструктор => создание возможно только через фабричный метод. Или DataColumn... Так почему бы не подчеркнуть принадлежность вынеся классы во внутрь DataTable? И вообще, вроде, не особо я часто встречал(по моему никогда), что бы использовали это возможность. Почему так?
Ответы
Ответ 1
Ну почему же, используется, но только для тех типов, которые не особо фигурируют напрямую в коде. Например, List.Enumerator, который используется только неявно кодом, генерируемым компилятором для foreach. Для обычных типов их использовать действительно не рекомендуется, на это даже есть специальное предупреждение анализаторов CA1034. Причина банальна - это неудобно; при каждом использовании такого типа снаружи нужно приписывать имя содержащего типа, сократить используя using нельзя. Ну и с точки зрения архитектуры: вложенность это не просто область видимости, она позволяет вложенному классу работать с private-членами содержащего. Если это не нужно по логике взаимодействия этих классов, лучше не связываться с таким нарушением инкапсуляции. Ответ 2
Класс в классе увеличивает размер файла. Если в файле более трёхсот строк, с ним уже не очень удобно работать. Если ваш класс становится слишком большим, это подсказывает, что, возможно, нарушен принцип единственной ответственности (single responsibility). Поэтому классы в классах используют только тогда, когда вы передаёте важную информацию для программиста, который будет поддерживать и изменять ваш код. Если класс Bar находится в Foo, значит, он должен знать, как устроен Foo. Пример: реализуем паттерн Memento: Клиент является "посыльным" за Memento, но только исходный объект может сохранять и извлекать информацию из Memento (Memento является "непрозрачным" для клиентов и других объектов). Из описания паттерна мы понимаем, что класс Originator и класс Memento должны знать друг о друге гораздо больше, чем остальные классы. Именно для подчёркивания этого факта нужно разместить один внутри другого. Я бы размещал Memento внутри Originator и вынес бы в него сохранение и восстановление состояния, чтобы оставить в Originator только его основную ответственность. Поскольку в подавляющем большинстве случаев мы всё-таки хотим скрыть детали реализации, мы не используем этот приём слишком часто.
Комментариев нет:
Отправить комментарий