Для решения этой задачи я использовал простое решение - класс-уведомитель CollectionNotificators.
Поддерживаются три типа события:
- Add - добавлен элемент в контейнер
- Remove - удалён элемент из контейнера
- Change - изменен элемент контейнера
Реализуемый интерфейс приведён ниже.
/*******************************************************************************
* Copyright (c) 2009 Evgeny P. Florov.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU GENERAL PUBLIC LICENSE Version 3
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/gpl.html
*******************************************************************************/
package org.inno.des.utils;
/***
* Interface for all collections (container of items) event notificators
* @author Evgeny P. Florov
*
*/
public interface ICollectionNotificators {
/***
* Interface for events, that applicate for items. Abstract parent for all other events
* @author Ecgeny P. Florov
*/
public interface IEvents{
public Object getSubject();
}
/***
* Interface for events, that started by container changes - for example - remove chield from trees node
* @author Evgeny P. Florov
*/
public interface IContainerEvents extends IEvents{
public Object getContainer();
}
/***
* Interface for events, that applicated for item changes, for example - change some property of item
* @author Evgeny P. Florov
*/
public interface ISubjectChangeEvents extends IEvents{
public String getId();
}
/***
* Supported listener of events
* @author Evgeny P. Florov
*/
public interface IListeners{
/***
* Called after "add" event occur.
* @param event - descript add event
*/
public void onAdd(IContainerEvents event);
/***
* Called after "remove" event occure
* @param event - descript remove event
*/
public void onRemove(IContainerEvents event);
/***
* Called after "change" event occure
* @param event - descript change event
*/
public void onChange(ISubjectChangeEvents event);
}
/***
* Add listener to this notificator
* @param subj - listener to add
*/
public void add(IListeners subj);
/***
* Remove listener from this notificator
* @param subj - listener to remove
*/
public void remove(IListeners subj);
/***
* Interface for object, that started events. Only service function - not requared
* @author Evgeny P. Florov
*
*/
public interface IEventFirestarters{
public void fireAddEvent(Object subject, Object container);
public void fireRemoveEvent(Object subject, Object container);
public void fireChangeEvent(Object subject, String id);
}
}
Пример использования довольно прост. Достаточно инстанцировать нотификатор (например как аттрибут контейнера) и по мере необходимости инициировать события вызовом fire***Event.
Естественно для получения событий клиенты должны реализовать ICollectionNotificators.IListeners и зарегистрироваться в объекте нотификатора.
Ниже приведён облегченный код JUnit теста:
/*******************************************************************************
* Copyright (c) 2009 Evgeny P. Florov.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU GENERAL PUBLIC LICENSE Version 3
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/gpl.html
*******************************************************************************/
package org.inno.des.utils.tests;
import java.util.ArrayList;
import org.inno.des.utils.CollectionNotificators;
import org.inno.des.utils.ICollectionNotificators;
import org.inno.des.utils.ICollectionNotificators.IContainerEvents;
import org.inno.des.utils.ICollectionNotificators.ISubjectChangeEvents;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
/**
* Test unit for CollectionNotificators
* @author Evgeny P. Florov
*
*/
public class CollectionNotificatorsTest {
private class ExDublicateFound extends RuntimeException{
}
private final int MAX_LISTENERS = 1000;
private ArrayListlisteners = new ArrayList ();
private CollectionNotificators test;
public int addcount = 0;
public int changecount = 0;
public int removecount = 0;
private class Listener implements ICollectionNotificators.IListeners{
private int number = 0;
public Listener(int number){
this.number = number;
}
@Override
public void onAdd(IContainerEvents event) {
addcount++;
}
@Override
public void onChange(ISubjectChangeEvents event) {
changecount++;
}
@Override
public void onRemove(IContainerEvents event) {
removecount++;
}
}
public CollectionNotificatorsTest() {
for(int i = 0; i < addcount =" 0;" changecount =" 0;" removecount =" 0;" test =" new" stealthmode =" true;" i =" 0;">
Комментариев нет:
Отправить комментарий