[Java] Факторизация программы с разнотипными колбэками от "железа"
исходный класс A преобразуется в прокси, перенаправляющий все вызовы в реальные реализации интерфейсов
class A:D_1
{
public A
{
d1 = new A_D_1;
}
D_1 d1;
public T D_1_Method1(..)
{
return d1.D_1_Method1(..);
}
public T D_1_Method2(..)
{
return d1.D_1_Method2(..);
}
...
}
реализацию интерфейса выносим в отдельный класс
class A_D1:D_1
{
public T D_1_Method1(..)
{
//здесь делаем что-то реальное
}
}
зы
есть утилиты, которые автоматизируют создание такого прокси и поддержание его в актуальном состоянии
Похожая идея возникала и у меня: заменить реализацию интерфейса D на поле d класса A, которое является объектом класса D`, реализующего интерфейс D.
Правда, до Вашего ответа, я не знал, что это в некотором смысле стандартный способ решения проблем проектирования, описанных мной выше. Если я правильно понял, ища в инете по ключевому слову "прокси", то предложенное Вами решение — это шаблон проектирования Proxy (Заместитель).
Если я правильно понял, ища в инете по ключевому слову "прокси", то предложенное Вами решение — это шаблон проектирования Proxy (Заместитель).да, это он и есть
Обычно можно в качесте разных коллбэков передавать разные объекты/классы.
В этом случае не надо никаких прокси. Руками (или рефакторингом) разбиваешь своего монстра на несколько классов, и все использования класса-монстра заменяешь на использование соотв маленького класса.
ЗЫ А прокси в джаве можно сделать на основе рефлекшена - тогда не надо будет каждый раз кодогенерить делегирующий монстрокласс - он сам будет разбираться в рантайме какой метод какому делегату проксирвать. Но это, конечно, пефоманс хит.
АПИ той библиотеки, которая принимает на вход ваш большой класс - там точно необходимо, чтобы был _один_ объект, реализующий _все_ интерфейсы?.Кстати, да, это не необходимо
Обычно можно в качесте разных коллбэков передавать разные объекты/классы.
В этом случае не надо никаких прокси. Руками (или рефакторингом) разбиваешь своего монстра на несколько классов, и все использования класса-монстра заменяешь на использование соотв маленького класса
Возможно, это очень хорошая идея, но я еще до конца не продумал детали. Действительно, можно мыслить в терминах нескольких "объектов-потоков": главный объект — это основной поток, разнотипные устройства (и их колбэки) — это его дочерние объекты-потоки; + имеются разнообразные попарные направленные связи между объектами, по которым одни объекты изменяют внутренние состояния других. Рисуем ориентированный граф взаимодействий и указываем методы взаимодействия ...
Например, акселерометр (1) запускает автофокус (2 автофокус переходит в состояние "ЗАПУЩЕН"; автофокус, оказавшийся в состоянии "ПОЙМАН (НАЙДЕН)", запускает фотографирование (3); фотографирование в состоянии "СДЕЛАНО" запускает "распознаватель" (4 на которого воздействовал объект-поток "сенсор освещенности" (5) и объект-поток "быстрый распознаватель" (6 на которого воздействовала камера (7 на которую в свою очередь воздействовал гироскоп (8) и т.д. и т.п.
Возможно, это очень хорошая идея, но я еще до конца не продумал детали. Действительно, можно мыслить в терминах нескольких "объектов-потоков"На мой взгляд только так и надо. Иначе в чем смысл разбиения по колбэкам, если состояние/логика для всего все равно живет в одном классе? Только не понял, зачем ты сюда потоки приплел, но подозреваю, что это какие-то другие потоки, нежели чем привычный Thread.
Если близок паттерн MVC, то в твоем случае контроллеры - это как бы коллбэки, модель - это состояние, а вью - это библиотека, которая дергает твои коллбэки. И помни об этом.
Если все равно тяжеловато, но хочется сделать красиво и есть время - попробуй заботать TDD - немножко рушит мозг, но со временем хорошо учит писать красивый код.
попробуй заботать TDD - немножко рушит мозг, но со временем хорошо учит писать красивый код.Кстати +1. Как раз тот случай, когда неделя обучения экономит месяц отладки, имхо.
Оставить комментарий
nikola1956
Подскажите, пожалуйста, как лучше факторизовать класс, который реализует несколько интерфейсов, представляющих собой колбэки от разных типов внешних устройств (камеры, акселерометра, графического потока, автофокусировки и т.п.) ?Более точно, есть класс A, который реализует интерфейсы от "железа" D_1, D_2, .. D_k. Каждый из интерфейсов привносит в класс A несколько методов, которые нужно реализовать. Соответственно класс A достигает ужасающих размеров, причем использует дополнительные группы переменных, констант и вспомогательных методов (функций которые относятся к работе в точности с одним из интерфейсов (одна группа переменных, констант и функций — для камеры, другая — для гироскопа или акселерометра и т.п.).
Естественно возникает желание разделить реализации разных интерфейсов по разным файлам и классам (как бы "проекциям" интерфейсов на класс A). Но как это проще всего сделать ? Ведь в Java нет возможности расширения классов как в Ruby или, например, типажей (trait) как в Scala.