Feb 16, 2009 21:10
Вот в который раз сталкиваюсь с тем, что проектирование любого нетривиального интерфейса надо строить на предположении что любая операция может быть асинхронной. И соотвественно проектировать API.
В Идее много где в кишках зашита синхронность, и от этого куча проблем. UI втыкает, фокус уходит в задницу, один фикс переоткрывает два закрытых бага ранее. А тестировать UI -- ой, ой, ой, это тема для отдельного долгого разговора.
Не все так плохо, конечно. В той же Идее потихоньку популяризируется вот такой вот подход (пример):
myTabbedPane.removeTabAt(componentIndex, indexToSelect).doWhenDone(new Runnable() {
public void run() {
editorManager.disposeComposite(editor);
}
});
В данном случае -- не мои проблемы когда и как дернут doWhenDone. Главное что операция будет завершена, можно безопасно грохать какие-то там мои компоненты.
То есть правильные методы возвращают не void, а некий объект, на который можно зацепиться. В Идее это объекты класса ActionCallback. У него есть методы типа doWhenDone(Runnable), doWhenRejected(Runnable) и doWhenProcessed(Runnable). И даже notifyWhenDone(ActionCallback) для чейнинга этих колбеков.
Внутри метода делается new ActionCallback(), возращается, и на нем дергается как угодно асинхронно setDone(), setRejected().
Очень правильный подход. Для UI его точно можно не бояться внедрять сразу для всех операций, самого начала. Очень удобно.