【问题标题】:Decorator Design Pattern with HashMap returning empty HashMap带有 HashMap 的装饰器设计模式返回空 HashMap
【发布时间】:2021-02-15 14:50:14
【问题描述】:

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

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

实施 1:-

但是,结果映射只包含其中一个装饰器的效果,例如:-

  • 只有 AddHashMap 效果,即结果是 - {AA=AA}

    Map map = new AddHashMap(new UpperCaseHashMap(new HashMap ())); map.add("aa", "aa"); System.out.println(map);

  • 只有 UpperCaseHashMap 效果,即结果是 - {aaADDED_BY_DECORATOR=aa}

    Map map = new UpperCaseHashMap(new AddHashMap(new HashMap ())); map.add("aa", "aa"); System.out.println(map);

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

    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 扩展 HashMapDecorator {

/**
 * 
 */
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);
}

}

【问题讨论】:

    标签: java design-patterns hashmap decorator


    【解决方案1】:

    您的线路:

    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);
        }
    }
    

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

    【讨论】:

    • 装饰器设计模式取决于子类化 - blogs.oracle.com/javamagazine/the-decorator-pattern-in-depth 提供的示例似乎正在使用访问者设计模式
    • 是的,由于我在答案中给出的原因,地图是空的:您只是转发put。您需要转发每种方法。这会破坏继承 HashMap 的目的。
    • 你能建议一些方法吗?另外,您能否编辑您的答案(任何内容),以便我支持您的答案
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-05
    • 1970-01-01
    • 1970-01-01
    • 2012-10-20
    • 2013-11-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多