decorator模式
名词解释
decorator表示装修的意思,在一个对象已经存在的情况下,在不改变此对象内核的情况
下,对该对象进行装饰,达到动态修改原始对象功能的目的。
概述
Name | category | intent |
---|---|---|
decorator | Structural | 动态地修改原始对象 |
应用在
一些原始类我们不希望修改它的逻辑,但是我们又想动态的修改其功能。装饰者模式与代理模
式相差无几,什么情况下叫代理模式,什么情况下叫装饰者模式,还需要我深入了解。
类图
代码
下面代码模拟的是一个数据获取的过程。具体情境是获取每天股票对应的数据,这些数据可能需要全部放在一个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;
}
}
真实案例
- InputStream
- Reader FileReader BufferedFileReader
- Collections.unmodifiableList, Collections.unmodifiableMap