По каким причинам большинство .net классов являются запечатанными (например: Int32, Double, String и т. п.)?
Есть ли в каких книгах/статьях объяснение данного архитектурного решения от создателей платформы?
Ответ
Все классы, которые не поддерживают наследование от них, должны быть sealed. Чтобы класс поддерживал наследование от него, необходимо обдуманное архитектурное решение: нужно рассмотреть реальные сценарии, когда это требуется; продумать, какие члена будут перегружаться; как остальные части системы будут работать с унаследованными классами и так далее.
Если все классы сначала делать незапечатанными, а потом думать, то велика вероятность, что от этого будет больше вреда, чем пользы: никакие реальные возможности добавлены не будут, программисты полезут в потроха класса и нагромоздят хаков. И все эти хаки придётся поддерживать, потому что обратная совместимость — это святое. Это значит, что реализация может быть закрыта для улучшений в будущих версиях.
Если какой-то класс закрыт, это значит, что архитектор не нашёл нормальных сценариев наследования, которые оправдывали бы незапечатенность класса.
Классы типа String и StringBuilder закрыты, потому что это открывает возможности для изменения реализации классов, производительность которых критична для системы. Например, раньше билдер работал по принципу List
Что касается Int32 и Double, то это вообще-то структуры, они вообще не поддерживают наследование.
Логика разработчиков .NET описана в книге Framework Design Guidelines. Некоторые части книги доступны на MSDN
На этот вопрос отвечал Эрик Липперт в статье Why Are So Many Of The Framework Classes Sealed? Он называет один ключевой принцип: "Хороший код делает ровно то, для чего он создан, ни больше ни меньше", а затем раскрывает его:
Философский. Наследование основано на отношении is-a. Если нельзя придумать такой класс, то наследование запрещено.
Практический. Создавать классы, которые можно расширять, сложно.
Совместимость. Закрытый класс можно сделать открытым, но не наоборот.
Безопасность. Если с помощью наследования можно переопределить логику базового класса, можно исковеркать логику и подвергнуть систему угрозе.
Более развёрнутая аргументация по ссылке выше.
В целом, классы во фреймворке "по умолчанию" закрыты примерно по той же причине, почему методы в C# по умолчанию невиртуальны. Можно вспомнить Java с виртуальными по умолчанию методами и учиться на ошибках.
Комментариев нет:
Отправить комментарий