Добрый день, суть приложения - парсинг афиш кинотеатров. (парсинг одинаковых данных (миниатюра, название кино, расписание) с разных сайтов).
Для каждого кинотеатра есть объект Cinema, в котором вся информация по кинотеатру и пару xpath для парсинга афиши. Проблема в том, что в данный момент нужно обойтись без xpath.
Если я правильно понимаю, нужно для каждого объекта Cinema использовать что-то типа листенера, который будет по своему парсить html страничку. Все Cinema-объекты хочу создавать в синглтоне CinemaManager, который после будет использоваться в активностях. Данные о кинотеатрах статические, поэтому я думаю то, что парсинг забит в код не ошибка.
Не выходит спарсить данные в один xpath, нужно несколько, еще сами данные нередко приходится чистить и форматировать а в одном шаблонном методе универсально это сделать не выходит. Для каждого кинотеатра хочется свой код парсинга.
По поводу листенера, я имел в виду колбэк, для каждого объекта Cinema:
private Callback mCallback;
public interface Callback {
void myFunction();
}
public void setCallback(Callback callback) {
mCallback = callback;
}
Возможно стоит вынести все эти колбеки в отдельный объект?
**** дисклеймер : я ниже очень усложнил дизайн специально, не стоит писать именно так, уберите лишнее. Это не "правильное" решение, а инфа к размышлению. ****
MikkiMouse: ну если дизайнить, то давайте подумаем вместе, самое простое что приходит на ум, делаем абстрактный класс AbstractCinema, внутри него абстрактный метод parse(), каждый наследник будет этот метод переопределять и парсить как душе угодно. Вполне себе удобный способ, но с ним одна проблема, теперь дерево классов Cinema будет зависить от метода parse(). Поясню : например у вас есть два наследника от AbstractCinema у которых метод parse() отличается лишь настройками, значит во избежания дубликатов кода, вам придется делать им еще одного общего предка внутри которого определять метод ну и так далее.
Значит парсинг нужно выносить отдельно сразу. При чем логично предположить что некоторые сайты можно будет спарсить схожими способами, регулярки там, xpath, а для некоторых будет хватать чтения rss-а, или вообще веб-сервис коллы. Поэтому парсинг выносим в отдельный модуль, внутри которого можно будет расширяться как угодно. Во вне он выдаст какой-нибудь фасад, или фабрику, или просто пачку классов.
Далее, у нас есть инструмент парсинга, теперь нужно его мапить на определенные инстансы Cinema_1..N и передавать параметры. По сути нужен класс с мапой(ассоциативным массивом), в котором вы бы могли записывать что то типа:
ParserMapping.put('ImaxCinema', {
parseType : 'XPATH',
params : [
{
name : 'filmsPath',
value : '/* ваш XPATH */'
},
... // еще любые параметры
]
handlerClassName : 'DefaultXPathParser'
});
Выберите из писанины выше идеи подходящие вам и используйте. Надеюсь помог)
Спасибо за ответ. Если представить что на страничке, которую парсим, будет грязный код, такое нередко встречается, спарсить нужные данные через, например, DefaultXPathParser не выйдет. Мне нужна комбинация инструментов для парсинга, и весь этот геморрой лишь для одного кинотеатра ImaxCinema, выходит нужно в модуле парсера делать что-то типа ImaxCinemaParser? Или пытаться использовать шаблонные парсеры, типа MultiXPathParser, RegexXPathParser etc.? Я думаю в параметрах не удастся передать то, как следует правильно спарсить и организовать данные.
Сейчас подумал может все проблемы что я много хочу от парсера (сразу получить нужные отформатированные данные), но если не так то все идет к ветвлению о котором вы написали (AbstractCinema) и которое не очень хотелось бы видеть)