В ответ на уточняющие комментарии от OP:
справа, вот краткий пример шаблона Observer:
public interface JNotifyListener {
void fileRenamed(int wd, String rootPath, String oldName, String newName);
void fileModified(int wd, String rootPath, String name);
void fileDeleted(int wd, String rootPath, String name);
void fileCreated(int wd, String rootPath, String name);
}
public enum Type {
RENAMED,
MODIFIED,
DELETED,
CREATED;
}
public class FileChangeEvent {
final Type type;
final int wd;
final String rootPath;
final String name;
final String newName;
public FileChangeEvent(Type type, int wd, String rootPath, String name, String newName) {
this.type = type;
this.wd = wd;
this.rootPath = rootPath;
this.name = name;
this.newName = newName;
}
public FileChangeEvent(Type type, int wd, String rootPath, String name) {
this(type, wd, rootPath, name, null);
}
public int getWd() {
return wd;
}
public String getRootPath() {
return rootPath;
}
public String getName() {
return name;
}
public String getNewName() {
return newName;
}
}
public interface FileChangeEventListener {
void notify(FileChangeEvent fileChangeEvent);
}
public class FileChangeEventNotifyer implements JNotifyListener {
final Collection<FileChangeEventListener> listeners = new ConcurrentLinkedQueue<FileChangeEventListener>();
@Override
public void fileRenamed(int wd, String rootPath, String oldName, String newName) {
notifyAll(new FileChangeEvent(Type.RENAMED, wd, rootPath, oldName, newName));
}
@Override
public void fileModified(int wd, String rootPath, String name) {
notifyAll(new FileChangeEvent(Type.MODIFIED, wd, rootPath, name));
}
@Override
public void fileDeleted(int wd, String rootPath, String name) {
notifyAll(new FileChangeEvent(Type.DELETED, wd, rootPath, name));
}
@Override
public void fileCreated(int wd, String rootPath, String name) {
notifyAll(new FileChangeEvent(Type.CREATED, wd, rootPath, name));
}
private void notifyAll(final FileChangeEvent changeEvent) {
for (final FileChangeEventListener changeEventListener : listeners) {
changeEventListener.notify(changeEvent);
}
}
public void registerListener(final FileChangeEventListener eventListener) {
listeners.add(eventListener);
}
public void unregisterListener(final FileChangeEventListener eventListener) {
listeners.remove(eventListener);
}
}
Вы можете видеть, что class
нужно только реализовать FileChangeEventListener
и зарегистрировать свой интерес с основным FileChangeEventNotifyer
. Затем он будет иметь свой метод notify
, вызванный с событием.
Здесь есть пара общих подводных камней. Одна из них заключается в том, что эта реализация не использует synchronized
, поэтому класс может пропустить уведомление, если оно регистрируется по мере того, как происходит событие. Преимущество заключается в том, что это неблокирование. Поэтому вам решать, желательно ли иметь неблокирующую коллекцию или блокировку.
Также вам необходимо обеспечить, чтобы зарегистрированные зарегистрированные слушатели были незарегистрированы впоследствии, иначе они будут накапливаться, и вы можете потерять память.
Я реализовал это как единый FileChangeEvent
с Type
- очевидно, вы могли бы иметь родительский класс FileChangeEvent
, а затем продлить его подклассов типов. Опять же, это зависит от ваших потребностей.
В любом случае, это должно вас начать.
Нет, вы не можете изменить сигнатуру метода таким образом, когда вы реализуете интерфейс, иначе люди не знают, чего ожидать от метода (вся точка интерфейса - это то, что вы знаете, что нужно передавать и что ожидать) – eldris
Если интерфейс ожидает 'void', реализация должна возвращать' void'. –
Вы можете использовать шаблон адаптера - оберните 'JNotifyListener' в другой' class', который возвращает значения. –