首页 > 解决方案 > 带有 HashMap 的装饰器设计模式返回空 HashMap

问题描述

我正在尝试为 HashMap 实现装饰器设计模式。

我有两个装饰器——“UpperCaseHashMap”和“AddHashMap”。

实施1:-

但是,结果映射仅包含装饰器之一的效果,例如:-

以下是装饰器类的代码:-

    public class UpperCaseHashMap<K, V> extends HashMap<K, V> {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    
    Map<K, V> map;
    
    public UpperCaseHashMap() {
        map = new HashMap<>();
    }

    UpperCaseHashMap(Map<K, V> map) {
        this.map = map;
    }

    public V put(K key, V value) {
        String temp = key.toString().toUpperCase();
        key = (K) temp;
        return super.put(key, value);
    }
    
}

    public class AddHashMap<K, V> extends HashMap<K, V> {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    
    Map<K, V> map;
    AddHashMap(Map<K, V> map) {
        this.map = map;
    }

    public V put(K key, V value) {
        String temp = key.toString().concat("ADDED_BY_DECORATOR");
        key = (K) temp;
        return super.put(key, value);
        
    }
    
}

实施 2 :- -结果地图为空

公共类 AddHashMapImpl2<K, V> 扩展 HashMapDecorator<K, V> {

/**
 * 
 */
private static final long serialVersionUID = 1L;

Map<K, V> map;
AddHashMapImpl2(Map<K, V> map) {
    this.map = map;
}

public V put(K key, V value) {
    String temp = key.toString().concat("ADDED_BY_DECORATOR");
    key = (K) temp;
    return map.put(key, value);
    
}

}

public class UpperCaseHashMapImpl2<K, V> extends HashMapDecorator<K, V> {

/**
 * 
 */
private static final long serialVersionUID = 1L;

Map<K, V> map;

public UpperCaseHashMapImpl2() {
    map = new HashMap<>();
}

UpperCaseHashMapImpl2(Map<K, V> map) {
    this.map = map;
}

public V put(K key, V value) {
    String temp = key.toString().toUpperCase();
    key = (K) temp;
    return map.put(key, value);
}

}

标签: javadesign-patternshashmapdecorator

解决方案


您的线路:

return super.put(key, value);

HashMap.put无论传递给构造函数的映射的实现如何,都在调用。相反,您需要:

return map.put(key, value);

但是我觉得你可能误解了装饰器的工作原理。如果您使用子类化,则需要将每个方法转发给委托。目前,您的课程正在扩展,HashMap但随后专门进行委派put。这是行不通的。所有其他方法都将转到扩展HashMap,并且不会找到您放入委托中的数据。你需要重新考虑你的设计。

您可能需要考虑如下设计:

@FunctionalInterface
interface MapDecorator<V> {
    V decorate(V value);
}

class DecoratedMap<K, V> extends HashMap<K, V> {
    private final List<MapDecorator<V>> decorators = new ArrayList<>();

    public void addDecorator(MapDecorator<V> decorator) {
        decorators.add(decorator);
    }

    @Override
    public V put(K key, V value) {
        for (MapDecorator<V> decorator: decorators)
            value = decorator.decorate(value);
        return super.put(key, value);
    }
}

我在此代码中使用了“装饰器”来匹配您的原始问题,但实际上,这并没有使用装饰器设计模式,因此,实际上,我会使用不同的名称,例如“变压器”。


推荐阅读