Страницы

Поиск по вопросам

пятница, 31 января 2020 г.

Зачем нужен класс FilterInputStream?

#java #архитектура


Просмотрев документацию и исходный код класса FilterInputStream, а также код его
наследников, возник вопрос: зачем вообще нужен этот класс? 

Т.к. этот класс не является источником данных, не выполняет никакой полезной работы,
то вероятно единственная цель его существования - решение каких-то архитектурных проблем. 

Как я сейчас понимаю - система ввода/вывода java.io использует паттерн декоратор.
Если классам наследникам FilterInputStream необходимо делегировать часть поведения
потоку ввода, ссылку на который они принимают у себя в конструкторе, они не обращаются
к методам FilterInputStream, а вызывают эти методы сразу по этой ссылке. Единственная
вещь в FilterInputStream, которая используется всеми его наследниками, это ссылочное
поле protected volatile InputStream in. Но ведь это всего лишь одно единственное поле
и совершенно не сложно объявить его в самих наследниках FilterInputStream.

Пожалуйста, скажите прав я или нет, и если нет — то в чем я ошибаюсь или что я не учел.
    


Ответы

Ответ 1



Единственная вещь в FilterInputStream, которая используется всеми его наследниками, это ссылочное поле protected volatile InputStream in. По порядку, все что делает FilterInputStream: содержит поле in, которое наследники могут использовать; объявляет конструктор, который принимает InputStream — каждому наследнику придется объявить хотя бы один конструктор и вызвать конструктор FilterInputStream; создает реализации по-умолчанию для всех методов InputStream, делегируя их вложенному потоку — девять методов, которые наследники могут не переопределять. Т.е. если бы не было FilterInputStream каждому из его наследников пришлось бы: объявить поле для вложенного потока; принимать в конструкторе поток и инициализировать поле; создать шаблонные реализации для всех методов InputStream вида: public int read() { return in.read(); } За счет наличия шаблонных реализаций наследник может переопределить только те методы, поведение которых специфично для наследника. Например, CheckedInputStream переопределяет три метода FilterInputStream, а наследует шесть. В документации указано 11 наследников FilterInputStream (это только в стандартной библиотеке). Дублировать поле и инициализацию уже было бы плохо. Вставлять же в каждый из классов одинаковые делегирующие методы недопустимо.

Ответ 2



FilterInputStream - это декоратор для InputStream. Декораторов на InputStream существует целое множество: к примеру, BufferedInputStream и ZipOutputStream. Он реализует все те же методы, что и InputStream, который лежит в нём, но позволяет к ним добавить доп. функционал. Конкретно его используют для какой-либо модификации данных из InputStream (т.е. фильтрации). Для лучшего понимания почитайте про паттерн декоратор

Комментариев нет:

Отправить комментарий