通过将对象放入包含行为的特殊封装对象中来为原对象绑定新的行为。
public interface IA {
void func();
}
public class A implements IA {
@Override
public void func() {
}
}
public class ADecorator implements IA {
private IA ia;
public ADecorator(IA ia) {
this.ia = ia;
}
@Override
public void func() {
// 增强...
ia.func();
// 增强...
}
}
为了让DataInputStream只重写InputStream中,自己关注的方法。
在FileInputStream中,对继承自InputStream的方法都重写了,并且内部调用的是组合的InputStream,而不是父类的方法。那为什么不直接用父类的方法呢?原因是组合的InputStream是外部传进来的,运用了多态,这个InputStream可能是其子类,包含额外对数据加工的操作。
为了达到此目的,需要对InputStream的所有方法进行重写,这部分重复的工作就交给了FileInputStream。
两者代码结构类似,但应用场景不同。装饰者模式是对原有功能增强,例如原功能是读取字符串,增强后可缓存的读取字符串。而代理模式增强的是和原功能无关的功能,例如对API接口增强,可记录接口调用时间,参数等。
java.util.Collections#unmodifiableList
也使用了装饰器模式
public static <T> List<T> unmodifiableList(List<? extends T> list) {
return (list instanceof RandomAccess ?
new UnmodifiableRandomAccessList<>(list) :
new UnmodifiableList<>(list));
}
static class UnmodifiableList<E> extends UnmodifiableCollection<E>
implements List<E> {
private static final long serialVersionUID = -283967356065247728L;
final List<? extends E> list;
UnmodifiableList(List<? extends E> list) {
super(list);
this.list = list;
}
public boolean equals(Object o) {return o == this || list.equals(o);}
public int hashCode() {return list.hashCode();}
public E get(int index) {return list.get(index);}
public E set(int index, E element) {
throw new UnsupportedOperationException();
}
public void add(int index, E element) {
throw new UnsupportedOperationException();
}
public E remove(int index) {
throw new UnsupportedOperationException();
}
public int indexOf(Object o) {return list.indexOf(o);}
public int lastIndexOf(Object o) {return list.lastIndexOf(o);}
public boolean addAll(int index, Collection<? extends E> c) {
throw new UnsupportedOperationException();
}
@Override
public void replaceAll(UnaryOperator<E> operator) {
throw new UnsupportedOperationException();
}
@Override
public void sort(Comparator<? super E> c) {
throw new UnsupportedOperationException();
}
public ListIterator<E> listIterator() {return listIterator(0);}
public ListIterator<E> listIterator(final int index) {
return new ListIterator<E>() {
private final ListIterator<? extends E> i
= list.listIterator(index);
public boolean hasNext() {return i.hasNext();}
public E next() {return i.next();}
public boolean hasPrevious() {return i.hasPrevious();}
public E previous() {return i.previous();}
public int nextIndex() {return i.nextIndex();}
public int previousIndex() {return i.previousIndex();}
public void remove() {
throw new UnsupportedOperationException();
}
public void set(E e) {
throw new UnsupportedOperationException();
}
public void add(E e) {
throw new UnsupportedOperationException();
}
@Override
public void forEachRemaining(Consumer<? super E> action) {
i.forEachRemaining(action);
}
};
}