Самый простой способ создать MutableGuiceKeyToInstanceMap? - PullRequest
1 голос
/ 09 мая 2011

Я бы хотел найти или реализовать MutableGuiceKeyToInstanceMap, работающий так же, как com.google.common.collect.MutableClassToInstanceMap из Гуавы, но с использованием com.google.inject.Key<T> из Guice вместо Class<T>.

Я не смог его найтив Guice, и я не могу реализовать его так, как был реализован MutableClassToInstanceMap, потому что его суперкласс ConstrainedMap был закрыт для пакета.Я также не могу использовать MapConstraint.constrainedMap, поскольку у меня не было бы возможности добавить методы getInstance и putInstance (а без них все это совершенно бессмысленно).

Создание собственной копии ConstrainedMap класс заставит меня скопировать довольно много дополнительных классов, так что это не тот путь.Создание помощника Map через MapConstraint.constrainedMap и создание MutableGuiceKeyToInstanceMap extends ForwardingMap, который делегирует все помощнику, может сработать, но это все еще довольно громоздко.Есть идея получше?

Как вы думаете, хорошая идея сделать ConstrainedMap публичной?

Ответы [ 2 ]

2 голосов
/ 10 мая 2011

Некоторые мысли:

  1. Мне любопытно, почему вы хотите это сделать.
  2. A ForwardingMap кажется вполне подходящим для этого.Что в этом обременительного?
  3. Публичное распространение ConstrainedMap не будет хорошей идеей.
1 голос
/ 10 мая 2011

Не понимаю, почему вам не нравится комбинация ForwardingMap и MapConstraint.constrainedMap. Код довольно прост и выглядит почти так же, как если бы вы расширили ConstrainedMap напрямую:

import com.google.common.collect.ForwardingMap;
import com.google.common.collect.MapConstraint;
import com.google.common.collect.MapConstraints;
import com.google.inject.Key;
import org.apache.commons.lang.NotImplementedException;

import java.util.HashMap;
import java.util.Map;


public final class MutableGuiceKeyToInstanceMap<B>
        extends ForwardingMap<Key<? extends B>, B> {

    /**
     * Returns a new {@code MutableGuiceKeyToInstanceMap} instance backed by a {@link
     * java.util.HashMap} using the default initial capacity and load factor.
     */
    public static <B> MutableGuiceKeyToInstanceMap<B> create() {
        return new MutableGuiceKeyToInstanceMap<B>(new HashMap<Key<? extends B>, B>());
    }

    /**
     * Returns a new {@code MutableGuiceKeyToInstanceMap} instance backed by a given
     * empty {@code backingMap}. The caller surrenders control of the backing map,
     * and thus should not allow any direct references to it to remain accessible.
     */
    public static <B> MutableGuiceKeyToInstanceMap<B> create(Map<Key<? extends B>, B> backingMap) {
        return new MutableGuiceKeyToInstanceMap<B>(backingMap);
    }


    private final Map<Key<? extends B>, B> delegate;

    private MutableGuiceKeyToInstanceMap(Map<Key<? extends B>, B> delegate) {
        this.delegate = MapConstraints.constrainedMap(delegate, VALUE_MATCHES_GUICE_KEY);
    }

    @Override
    protected Map<Key<? extends B>, B> delegate() {
        return delegate;
    }

    private static final MapConstraint<Key<?>, Object> VALUE_MATCHES_GUICE_KEY = new MapConstraint<Key<?>, Object>() {
        @Override
        public void checkKeyValue(Key<?> key, Object value) {
            matchesGuiceKey(key, value);
        }
    };

    public <T extends B> T putInstance(Key<T> key, T value) {
        return matchesGuiceKey(key, put(key, value));
    }

    public <T extends B> T getInstance(Key<T> key) {
        return matchesGuiceKey(key, get(key));
    }

    private static <B, T extends B> T matchesGuiceKey(Key<T> key, B value) {
        throw new NotImplementedException("TODO");
    }

    private static final long serialVersionUID = 0;
}

Код очень похож на MutableClassToInstanceMap, и нет необходимости расширять ForwardingMap ... Конечно, вам нужно добавить метод delegate() и соответствующее поле, но остальное идентично. *

Я упустил реализацию matchesGuiceKey() в качестве упражнения для читателя. Удачи! Вам может нужно это .

...