设计模式--decorator模式

decorator模式

名词解释

decorator表示装修的意思,在一个对象已经存在的情况下,在不改变此对象内核的情况
下,对该对象进行装饰,达到动态修改原始对象功能的目的。

概述

Namecategoryintent
decoratorStructural动态地修改原始对象

应用在

一些原始类我们不希望修改它的逻辑,但是我们又想动态的修改其功能。装饰者模式与代理模
式相差无几,什么情况下叫代理模式,什么情况下叫装饰者模式,还需要我深入了解。

类图

代码

下面代码模拟的是一个数据获取的过程。具体情境是获取每天股票对应的数据,这些数据可能需要全部放在一个list里面,也有可能需要进行聚合操作。比如说我需要得到一段时间内所有股票每天的收盘价,也有可能需要获取到一段时间内所有股票的最高价,最低价等。这时候怎么组装所有数据,就可以用到装饰者模式。

package com.liang.designpattern.decorator;

import java.util.List;

public interface DataCollection {

    List<Data> getDataCollection();
    void addData(Data data);

}
package com.liang.designpattern.decorator;

import java.util.ArrayList;
import java.util.List;

/**
 * 将所有数据放在一个list上面,模拟获取所有数据,而不加以改变。
 *
 */
public class SimpleDataCollecition implements DataCollection {

    List<Data> datas;

    SimpleDataCollecition () {
        datas = new ArrayList<Data>();
    }

    @Override
    public List<Data> getDataCollection() {
        return datas;
    }

    @Override
    public void addData(Data data) {
        datas.add(data);
    }

}
package com.liang.designpattern.decorator;

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

/**
 * 
 * 通过装饰者模式对原始的dataCollection进行装饰
 *
 */
public class AggregateDataCollection implements DataCollection {

    DataCollection dataCollection;
    Aggregator aggregator;
    Map<String, Integer> positionMap = null;

    public AggregateDataCollection(SimpleDataCollecition dataCollection, Aggregator aggregator) {
        super();
        this.dataCollection = dataCollection;
        this.aggregator = aggregator;
        positionMap = new HashMap<String, Integer>();
    }

    @Override
    public List<Data> getDataCollection() {
        return dataCollection.getDataCollection();
    }

    @Override
    public void addData(Data data) {
        if (aggregator == null) {
            dataCollection.addData(data);
        } else {
            Integer position = positionMap.get(data.getStkcode());
            if (position == null) {
                dataCollection.getDataCollection().add(data);
                positionMap.put(data.getStkcode(), dataCollection.getDataCollection().size() - 1);
            } else {
                dataCollection.getDataCollection().set(position, aggregator.aggregator(dataCollection.getDataCollection().get(position), data));
            }
        }
    }
}
package com.liang.designpattern.decorator;

/**
 * 该类表示一只股票一天某个指标的数据
 *
 */
public class Data {

    private String stkcode;
    private Double value;
    private long timestamp;

    public Data(String stkcode, Double value, long timestamp) {
        super();
        this.stkcode = stkcode;
        this.value = value;
        this.timestamp = timestamp;
    }

    public String getStkcode() {
        return stkcode;
    }

    public void setValue(Double value) {
        this.value = value;
    }

    public Double getValue() {
        return value;
    }

    public long getTimestamp() {
        return timestamp;
    }

    @Override
    public String toString() {
        return String.format("{stocode:%s, value:%f, time:%d}", stkcode, value, timestamp);
    }
}
package com.liang.designpattern.decorator;

public interface Aggregator {

    public Data aggregator(Data data1, Data data2);

}
package com.liang.designpattern.decorator;

public class MaxAggregator implements Aggregator {

    @Override
    public Data aggregator(Data data1, Data data2) {
        if (data1 == null) {
            return data2;
        } else if (data2 == null) {
            return data1;
        } else {
            if (data2.getValue() > data1.getValue()) {
                return data2;
            } else {
                return data1;
            }
        }
    }

}
package com.liang.designpattern.decorator;

public class MinAggregator implements Aggregator {

    @Override
    public Data aggregator(Data data1, Data data2) {
        if (data1 == null) {
            return data2;
        } else if (data2 == null) {
            return data1;
        } else {
            if (data2.getValue() < data1.getValue()) {
                return data2;
            } else {
                return data1;
            }
        }
    }

}
package com.liang.designpattern.decorator;

import java.util.ArrayList;
import java.util.List;

public class DecoratorClient {

    public static void main (String[] args) {
        DataCollection c = new SimpleDataCollecition();
        DataCollection max = new AggregateDataCollection(new SimpleDataCollecition(), new MaxAggregator());
        DataCollection min = new AggregateDataCollection(new SimpleDataCollecition(), new MinAggregator());

        List<Data> datas = datas();
        addDatas(datas, c);
        addDatas(datas, max);
        addDatas(datas, min);


    }

    public static void addDatas(List<Data> datas, DataCollection c) {
        for (Data data : datas) {
            c.addData(data);
        }

        for (Data data : c.getDataCollection()) {
            System.out.println(data);
        }
        System.out.println("==============================");
    }

    private static List<Data> datas() {
        List<Data> datas = new ArrayList<Data>();
        datas.add(new Data("300033", 50d, 20180825));
        datas.add(new Data("300033", 40d, 20180826));
        datas.add(new Data("300033", 60d, 20180827));
        datas.add(new Data("300033", 70d, 20180828));
        datas.add(new Data("300033", 10d, 20180829));

        datas.add(new Data("300034", 80d, 20180825));
        datas.add(new Data("300034", 40d, 20180826));
        datas.add(new Data("300034", 60d, 20180827));
        datas.add(new Data("300034", 5d, 20180828));
        datas.add(new Data("300034", 10d, 20180829));

        return datas;
    }

}

真实案例

  1. InputStream
  2. Reader FileReader BufferedFileReader
  3. Collections.unmodifiableList, Collections.unmodifiableMap
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值