У F # есть малоиспользуемая функция под названием «файлы подписи». У вас может быть большой файл реализации, полный public типы/методы/модули/функции, но тогда вы можете скрыть и выборочно разоблачить эту функциональность для продолжения программы через файл подписи. То есть файл подписи действует как вид экрана/фильтра, который позволяет создавать сущности «общедоступные для этого файла», но «частные для остальной части программы».
Я чувствую, что это симпатичная функция убийцы на платформе .Net, потому что единственным другим/предыдущим инструментом, который у вас есть для такого рода инкапсуляции, является сборка. Если у вас есть небольшой компонент с несколькими родственными типами, которые хотят видеть внутренние детали друг друга, но не хотите, чтобы эти типы имели все эти биты в всем, что вы можете сделать?Ну, вы можете сделать две вещи:
- Вы можете поместить этот компонент в отдельной сборке, и сделать членов, что эти типы акций быть «внутренним», и сделать узкую часть, которую вы хотите все остальные, чтобы увидеть быть " public ", или
- Вы просто отмечаете внутреннее содержимое« внутреннее », но вы оставляете эти типы в своей гигантской сборке и просто надеетесь, что весь другой код в сборке не хочет называть тех членов, которые были помечены как« внутренние », потому что один другой тип, необходимый для его просмотра.
По моему опыту, в крупных проектах программного обеспечения каждый всегда имеет # 2, потому что # 1 является не стартером по разным причинам (люди не хотят 50 небольших сборок, им нужны 1 или 2 или 3 больших сборок, по другим, возможно, хорошим причинам, не связанным с точкой инкапсуляции, которую я поднимаю (в стороне: все упоминают ILMerge, но никто ее не использует)).
Итак, вы выбрали вариант №2. Затем через год вы, наконец, решите реорганизовать этот компонент, и вы обнаружите, что в прошлом году 17 других мест теперь вызывают этот «внутренний» метод, который был действительно предназначен только для этого другого типа, который вызывал его, трудно учесть этот бит, потому что теперь все зависит от этих деталей реализации. Облом.
Дело в том, что нет хорошего способа создать область/границу инкапсуляции с умеренным размером внутри .Net. Часто «внутреннее» слишком велико, а «личное» слишком мало.
... до F #. С файлами подписи F # вы можете создать область инкапсуляции «этого файла исходного кода», пометив кучу вещей как общедоступных в файле реализации, так что все остальные коды в файле могут видеть и участвовать в ней, но затем использовать файл подписи, чтобы скрыть все детали, ожидают узкий публичный интерфейс, который компонент предоставляет для остального мира. Это радует. Определите три сильно связанных типа в одном файле, пусть они видят подробности реализации друг друга, но только разоблачают действительно публичные вещи для всех остальных. Выиграть!
Подпись файлы, возможно, не функция идеально для границ инкапсулирования внутри сборки, но они являются только такой особенностью, которую я знаю, и поэтому я цепляюсь за них, как спасательный плот в океане.
TL;
Сложность - это враг. Границы инкапсуляции - это оружие против этого врага. «private» - отличное оружие, но иногда слишком малое, чтобы быть применимым, а «внутреннее» часто слишком слабо, потому что столько кода (целая сборка и все InternalsVisibleTo) могут видеть внутренние вещи. F # предлагает масштаб больше, чем «частный для типа», но меньше, чем «вся сборка», и это очень полезно.
Я очень думаю, поэтому каждая функция как-то скрыта;) – wishi 2009-11-03 09:29:48