0

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

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

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 中某个组件的特定要求,我必须在 Model 中做出决定。这似乎违反了 MVVM 模式。

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

我做错了吗?有没有更好的方法让 PluggableLists 工作,而 ModelClass 不必知道特殊的 UiControllerClass 要求并且没有潜在的性能影响?

4

1 回答 1

0

我想出了一个优雅的解决方案,它保留了 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();
        }
    }
}
于 2014-10-10T16:40:44.310 回答