#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 (т.е. фильтрации). Для лучшего понимания почитайте про паттерн декоратор
Комментариев нет:
Отправить комментарий