Ни у кого не возникало мыслей, что System.IO в наших с вами дот нетах проектировали специально, чтобы максимально запутать бедных программистов? Вот я, например, постоянно путаюсь между этими TextReader-ами, StreamReader-ами, StringReader-ами, классами FileStream и System.IO.File и т.п.. Поэтому я решил сделать небольшую шпаргалку для себя, но она может быть полезна и кому-то еще.
Итак, вот она:
Чтобы было проще разбираться в множестве этих классов, я выделил несколько категорий типов, которые решают разные задачи:
- Непосредственно стримы с данными (FileStream, MemoryStream etc): позволяют работать с файлами, сокетами, памятью как с потоком данных бинарных данных
- Декораторы (BufferedStream, GZipStream etc): добавляют поведение стримам, типа буферизации или сжатия.
- Адаптеры (текстовые – TextReader/Writer и бинарные – BinaryReader/Writer): служат для упрощения чтения специфических данных из стримов, таких как чтение текстовых данных или выкусывание примитивных данных из бинарного потока.
- Фасадный класс с набором фабричных методов System.IO.File (на рисунке не показан)
Классы StreamDecorator и DataStream не существуют, их я выделил чтобы проще было показывать "общность" классов.
Класс File является таким себе фасадом и содержит набор вспомогательных методов для чтения/записи и манипулирования файлами, но в данном случае наиболее важными являются следующие фабричные методы:
Встроенная поддержка тестируемости
Обратите внимание, что на диаграмме выше кроме классов, работающих со стримами есть еще пара классов (StringReader и StringWriter), которые работают со строками в памяти.
Благодаря этому, вы можете обеспечить тестируемость любых классов, работающих со стримами. Если у вас есть класс, читающий что-либо из файла, то вместо открытия файла напрямую, ваш класс может принимать Stream, а еще лучше, TextReader, который легко можно будет "замокать" передав вместо него StringReader с нужным содержимым.
Этому подходу следуют многие классы .NET Framework, как XmlReader/XmlWriter, XElement/XDocument и многие другие. По сути, TextReader – является такой себе стратегией, передача которой через конструктор или метод обеспечит как разделение ответственности между классами, так и требуемую тестируемость.
Отличная шпаргалка! Большое спасибо!
ОтветитьУдалить@Andrey: рад помочь!
ОтветитьУдалитьУдобно и наглядно. спасибо.
ОтветитьУдалить> System.IO в наших с вами дот нетах проектировали специально, чтобы максимально запутать бедных программистов
ОтветитьУдалитьЭто точно!
> > System.IO в наших с вами дот нетах проектировали специально, чтобы максимально запутать бедных программистов
ОтветитьУдалить> Это точно!
Вы еще на Windows Store Application посмотрите и подумайте над любым нетривиальным сценарием (особенно весело с портированием кода с андроидов/обычных форм).
Да уж, с этими стримами всегда путаешься. Кстати, даже не задумывался чем является оказывается класс File — фабрикой )) Больше всего доставило написание адаптеров на стрим, мне кажется разработчики слегка переборщили, лучше бы обошлись интерфейсами. Думаю, они бы так и сделали, если бы выпала возможность перепроектировать весь .NET заново.
ОтветитьУдалить@Алексей: Кстати, класс File является скорее фасадом с набором фабричных методов;)
ОтветитьУдалить