#java #android
#java #Android
Вопрос:
Иногда мне нужен простой универсальный прослушиватель без определения моего собственного класса. Существует ли предопределенное «что-то произошло, и вот строка или объект или что-то еще» в Java или Android?
Комментарии:
1. В принципе, это все, что я хочу. Существует ли он? общедоступный интерфейс SomethingHappenedListener { public void itHappened(Object объект); }
2. Модель MVC, Observer, Observable должны делать то, что вам нужно
3. Это именно то, что я хочу. Так печально, что ни java, ни Android не имеют встроенной поддержки событий / делегирования, таких как c #, obj-c, swift и т.д.
Ответ №1:
Это было в проекте, над которым я работал. Это приводит к некоторому ужасно нечитаемому и не поддерживаемому коду, как только класс реализует интерфейс «MyListener» для обработки двух совершенно разных типов событий. Отсутствовало разделение задач, и вы понятия не имели, когда и как этот метод может быть вызван.
public interface GenericListener {
public void handleMyEvent(Object sourceObj, int eventCode);
}
//...later on there's some implementation
public void handleMyEvent(Object sourceObj, int eventCode) {
if ( sourceObj == startDownloadButton amp;amp; eventCode == MyButton.CLICKED ) {
//... 20 lines of code to start download
} else if ( sourceObj instanceOf DownloadStatus amp;amp; eventCode == DownloadStatus.COMPLETE ) {
//... 10 lines of code to display status
} else //... and on and on...
}
Это не тот вид дублирования кода, которого вам нужно избегать. То, что два метода / интерфейса используют одну и ту же базовую сигнатуру, не означает, что их следует объединить в один. Я предлагаю вам создать интерфейсы прослушивателя, которые полностью самодокументируются в отношении того, когда и как они используются.
Ответ №2:
Есть java.util.Наблюдатель, но это работает только для наблюдаемых подклассов. (То есть что угодно может реализовать интерфейс Observer, но оно может наблюдать только наблюдаемые объекты.)
Комментарии:
1. Это единственный стандартный механизм событий, который вы можете использовать в JDK, но ваш код не будет таким осмысленным, как при использовании вашей собственной системы событий.
2. Насколько я помню, они реализованы как классы, а не интерфейсы. Это также создает проблему, когда у вашего класса уже есть parent
Ответ №3:
Если вы хотите избежать определения класса прослушивателя, рассмотрите возможность определения методов обратного вызова непосредственно в observable:
abstract class MyWorker{
public MyWorker(){
//...
onComplete();
}
protected abstract void onComplete();
}
Затем переопределите их позже:
new MyWorker(){
protected void onComplete(){
//..
}
}
Очевидно, что это подходит не для каждой ситуации. Иногда вам нужен реальный класс прослушивателя.