如何处理GlazedLists对共享发布者和锁定的可插拔列表要求



我刚刚开始在一个广泛使用beansbinding(MVVM模式)的Java项目中使用GlazedList。

PluggableList允许我将源列表绑定到表,然后在运行时更改源列表。为了实现这一点,每个源列表都必须共享相同的ListEventPublisher和ReadWriteLock,因为PlugableList必须与其源共享一个锁和重新发布器。我通过创建一个静态发布者并锁定我的类来实现这一点,该类拥有潜在的源列表,在类的每个实例化中使用这些静态值来创建列表以及PlugableList,如下面的伪代码所示:

public class ModelClass
{
    final static EventList          LIST               = new BasicEventList();
    final static ListEventPublisher LISTEVENTPUBLISHER = LIST.getPublisher();
    final static ReadWriteLock      READWRITELOCK      = LIST.getReadWriteLock();
    final EventList                 sourceList         = 
            new BasicEventList(LISTEVENTPUBLISHER, READWRITELOCK);
}

public class UiControllerClass
{
    final PluggableList pluggableList = 
        new PluggableList(ModelClass.LISTEVENTPUBLISHER, ModelClass.READWRITELOCK);
    // ... call pluggableList.setSource(someSourceList) 
}

我对此有两个担忧:

(1) 由于UiController中某个组件的特定要求,我必须在模型中做出决定。这似乎违反了MVVM模式。

(2) 如果列表非常多并且频繁访问,共享锁可能会影响列表的性能,因为它们都共享同一个锁。否则,这些列表中的每一个都应该能够独立运行,而不必相互关心。

我是不是搞错了?有没有更好的方法可以让PluggableLists在ModelClass不必知道特殊UiControllerClass要求的情况下工作,并且不会对性能造成潜在影响?

我提出了一个优雅的解决方案,它既保留了MVVM模式,又消除了对共享锁和发布器的需求。

我创建了一个自定义列表转换,它扩展了PluggableList并覆盖了它的setSource方法。然后,新的源列表将与PluggableList创建的新列表同步(它将具有与PluggableList相同的发布者和锁)。

public class HotSwappablePluggableList<T>
        extends PluggableList<T>
{
    private EventList<T>         syncSourceList    = new BasicEventList<>();
    private ListEventListener<T> listEventListener = null;
    public HotSwappablePluggableList()
    {
        super(new BasicEventList<T>());
    }
    @Override
    public void setSource(final EventList<T> sourceList)
    {
        getReadWriteLock().writeLock().lock();
        try
        {
            if (listEventListener != null)
            {
                syncSourceList.removeListEventListener(listEventListener);
            }
            syncSourceList = sourceList;
            final EventList<T> syncTargetList = createSourceList();
            listEventListener = GlazedLists.syncEventListToList(syncSourceList, syncTargetList);
            super.setSource(syncTargetList);
        }
        finally
        {
            getReadWriteLock().writeLock().unlock();
        }
    }
}

最新更新