浏览 2730 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2010-01-09
最后修改:2010-01-22
这个列子是关于汉堡包要和什么材料搭配 汉堡包核心是面包 但中间夹得材料可以是各种食物 即装饰面包以不同的材料
Ingredient 装饰器和被装饰着都要继承的类 也可定义为接口
package decoratorPatternSample; public abstract class Ingredient { public abstract String getDescription(); public abstract double getCost(); public void printDescription(){ System.out.println(" Name "+ this.getDescription()); System.out.println(" Price RMB "+ this.getCost()); } }
Bread 核心组件
package decoratorPatternSample; public class Bread extends Ingredient { private String description; public Bread(String desc) { this.description = desc; } public String getDescription() { return description; } public double getCost() { return 2.48; } }
Decorator 装饰器类基类 package decoratorPatternSample; public abstract class Decorator extends Ingredient { Ingredient ingredient ; public Decorator(Ingredient igd){ this.ingredient = igd; } public abstract String getDescription(); public abstract double getCost(); }
下面是4中装饰器实现类
package decoratorPatternSample; public class Celery extends Decorator{ public Celery(Ingredient igd){ super(igd); } public String getDescription(){ String base = ingredient.getDescription(); return base +"\n"+"Decrocated with Celery !"; } public double getCost(){ double basePrice = ingredient.getCost(); double celeryPrice =0.6; return basePrice + celeryPrice ; } }
package decoratorPatternSample; public class GreenGrocery extends Decorator{ public GreenGrocery (Ingredient igd){ super(igd); } public String getDescription(){ String base = ingredient.getDescription(); return base +"\n"+"Decrocated with GreenGrocery !"; } public double getCost(){ double basePrice = ingredient.getCost(); double greenGroceryPrice = 0.4; return basePrice + greenGroceryPrice ; } }
package decoratorPatternSample; public class Mutton extends Decorator{ public Mutton(Ingredient igd){ super(igd); } public String getDescription(){ String base = ingredient.getDescription(); return base +"\n"+"Decrocated with Mutton !"; } public double getCost(){ double basePrice = ingredient.getCost(); double muttonPrice = 2.3; return basePrice + muttonPrice ; } }
package decoratorPatternSample; public class Pork extends Decorator{ public Pork(Ingredient igd){ super(igd); } public String getDescription(){ String base = ingredient.getDescription(); return base +"\n"+"Decrocated with Pork !"; } public double getCost(){ double basePrice = ingredient.getCost(); double porkPrice = 1.8; return basePrice + porkPrice ; } }
测试类
package decoratorPatternSample; public class DecoratorTest { public static void main(String[] args) { Ingredient compound = new Mutton(new Celery(new Bread("Master24's Bread"))); compound.printDescription(); compound = new Celery(new GreenGrocery(new Bread("Bread with milk"))); compound.printDescription(); compound = new Mutton(new Pork(new Bread("Bread with cheese"))); compound.printDescription(); } }
输出 Name Master24's Bread Decrocated with Celery ! Decrocated with Mutton ! Price RMB 5.38 Name Bread with milk Decrocated with GreenGrocery ! Decrocated with Celery ! Price RMB 3.48 Name Bread with cheese Decrocated with Pork ! Decrocated with Mutton ! Price RMB 6.58 ===========================
java基础类库上的用法
Collections 类提供了一些集合类的帮助方法 ,如把集合转换成 checked unmodifiable Synchronized等 这些都是用的装饰器模式 这面给出一个把map转成同步map的列子
调用代码如下 相当于客户代码 public static <K,V> Map<K,V> synchronizedMap(Map<K,V> m) { return new SynchronizedMap<K,V>(m); } 给一个map return一个 SynchronizedMap ,给原来的map添加了同步的功能(实际上这个新的map和原来的不是一个对象了,但客户是看不到这一点,但假如使用==的话 就会发现),保证线程的安全
接下来看下SynchronizedMap 是如何包装的 private static class SynchronizedMap<K,V> implements Map<K,V>, Serializable { // use serialVersionUID from JDK 1.2.2 for interoperability private static final long serialVersionUID = 1978198479659022715L; private Map<K,V> m; // Backing Map Object mutex; // Object on which to synchronize SynchronizedMap(Map<K,V> m) { if (m==null) throw new NullPointerException(); this.m = m; mutex = this; } SynchronizedMap(Map<K,V> m, Object mutex) { this.m = m; this.mutex = mutex; } public int size() { synchronized(mutex) {return m.size();} } public boolean isEmpty(){ synchronized(mutex) {return m.isEmpty();} } public boolean containsKey(Object key) { synchronized(mutex) {return m.containsKey(key);} } public boolean containsValue(Object value){ synchronized(mutex) {return m.containsValue(value);} } public V get(Object key) { synchronized(mutex) {return m.get(key);} } public V put(K key, V value) { synchronized(mutex) {return m.put(key, value);} } public V remove(Object key) { synchronized(mutex) {return m.remove(key);} } public void putAll(Map<? extends K, ? extends V> map) { synchronized(mutex) {m.putAll(map);} } public void clear() { synchronized(mutex) {m.clear();} } private transient Set<K> keySet = null; private transient Set<Map.Entry<K,V>> entrySet = null; private transient Collection<V> values = null; public Set<K> keySet() { synchronized(mutex) { if (keySet==null) keySet = new SynchronizedSet<K>(m.keySet(), mutex); return keySet; } } public Set<Map.Entry<K,V>> entrySet() { synchronized(mutex) { if (entrySet==null) entrySet = new SynchronizedSet<Map.Entry<K,V>>((Set<Map.Entry<K,V>>)m.entrySet(), mutex); return entrySet; } } public Collection<V> values() { synchronized(mutex) { if (values==null) values = new SynchronizedCollection<V>(m.values(), mutex); return values; } } public boolean equals(Object o) { synchronized(mutex) {return m.equals(o);} } public int hashCode() { synchronized(mutex) {return m.hashCode();} } public String toString() { synchronized(mutex) {return m.toString();} } private void writeObject(ObjectOutputStream s) throws IOException { synchronized(mutex) {s.defaultWriteObject();} } }
SynchronizedMap 实现了map接口,然后在内部把传进来的map用一个property保存住,然后在所有的map接口方法中都加上了锁
同理的看下 UnmodifiableMap private static class UnmodifiableMap<K,V> implements Map<K,V>, Serializable { // use serialVersionUID from JDK 1.2.2 for interoperability private static final long serialVersionUID = -1034234728574286014L; private final Map<? extends K, ? extends V> m; UnmodifiableMap(Map<? extends K, ? extends V> m) { if (m==null) throw new NullPointerException(); this.m = m; } public int size() {return m.size();} public boolean isEmpty() {return m.isEmpty();} public boolean containsKey(Object key) {return m.containsKey(key);} public boolean containsValue(Object val) {return m.containsValue(val);} public V get(Object key) {return m.get(key);} public V put(K key, V value) { throw new UnsupportedOperationException(); } public V remove(Object key) { throw new UnsupportedOperationException(); } public void putAll(Map<? extends K, ? extends V> t) { throw new UnsupportedOperationException(); } public void clear() { throw new UnsupportedOperationException(); } private transient Set<K> keySet = null; private transient Set<Map.Entry<K,V>> entrySet = null; private transient Collection<V> values = null; public Set<K> keySet() { if (keySet==null) keySet = unmodifiableSet(m.keySet()); return keySet; } public Set<Map.Entry<K,V>> entrySet() { if (entrySet==null) entrySet = new UnmodifiableEntrySet<K,V>(m.entrySet()); return entrySet; } public Collection<V> values() { if (values==null) values = unmodifiableCollection(m.values()); return values; } public boolean equals(Object o) {return m.equals(o);} public int hashCode() {return m.hashCode();} public String toString() {return m.toString();} /** * We need this class in addition to UnmodifiableSet as * Map.Entries themselves permit modification of the backing Map * via their setValue operation. This class is subtle: there are * many possible attacks that must be thwarted. * * @serial include */ static class UnmodifiableEntrySet<K,V> extends UnmodifiableSet<Map.Entry<K,V>> { private static final long serialVersionUID = 7854390611657943733L; UnmodifiableEntrySet(Set<? extends Map.Entry<? extends K, ? extends V>> s) { super((Set<Map.Entry<K,V>>)(Set)s); } public Iterator<Map.Entry<K,V>> iterator() { return new Iterator<Map.Entry<K,V>>() { Iterator<? extends Map.Entry<? extends K, ? extends V>> i = c.iterator(); public boolean hasNext() { return i.hasNext(); } public Map.Entry<K,V> next() { return new UnmodifiableEntry<K,V>(i.next()); } public void remove() { throw new UnsupportedOperationException(); } }; } public Object[] toArray() { Object[] a = c.toArray(); for (int i=0; i<a.length; i++) a[i] = new UnmodifiableEntry<K,V>((Map.Entry<K,V>)a[i]); return a; } public <T> T[] toArray(T[] a) { // We don't pass a to c.toArray, to avoid window of // vulnerability wherein an unscrupulous multithreaded client // could get his hands on raw (unwrapped) Entries from c. Object[] arr = c.toArray( a.length==0 ? a : (T[])java.lang.reflect.Array.newInstance(a.getClass().getComponentType(), 0)); for (int i=0; i<arr.length; i++) arr[i] = new UnmodifiableEntry<K,V>((Map.Entry<K,V>)arr[i]); if (arr.length > a.length) return (T[])arr; System.arraycopy(arr, 0, a, 0, arr.length); if (a.length > arr.length) a[arr.length] = null; return a; } /** * This method is overridden to protect the backing set against * an object with a nefarious equals function that senses * that the equality-candidate is Map.Entry and calls its * setValue method. */ public boolean contains(Object o) { if (!(o instanceof Map.Entry)) return false; return c.contains(new UnmodifiableEntry<K,V>((Map.Entry<K,V>) o)); } /** * The next two methods are overridden to protect against * an unscrupulous List whose contains(Object o) method senses * when o is a Map.Entry, and calls o.setValue. */ public boolean containsAll(Collection<?> coll) { Iterator<?> e = coll.iterator(); while (e.hasNext()) if (!contains(e.next())) // Invokes safe contains() above return false; return true; } public boolean equals(Object o) { if (o == this) return true; if (!(o instanceof Set)) return false; Set s = (Set) o; if (s.size() != c.size()) return false; return containsAll(s); // Invokes safe containsAll() above } /** * This "wrapper class" serves two purposes: it prevents * the client from modifying the backing Map, by short-circuiting * the setValue method, and it protects the backing Map against * an ill-behaved Map.Entry that attempts to modify another * Map Entry when asked to perform an equality check. */ private static class UnmodifiableEntry<K,V> implements Map.Entry<K,V> { private Map.Entry<? extends K, ? extends V> e; UnmodifiableEntry(Map.Entry<? extends K, ? extends V> e) {this.e = e;} public K getKey() {return e.getKey();} public V getValue() {return e.getValue();} public V setValue(V value) { throw new UnsupportedOperationException(); } public int hashCode() {return e.hashCode();} public boolean equals(Object o) { if (!(o instanceof Map.Entry)) return false; Map.Entry t = (Map.Entry)o; return eq(e.getKey(), t.getKey()) && eq(e.getValue(), t.getValue()); } public String toString() {return e.toString();} } } } 当尝试改变map的时候就会抛出UnsupportedOperationException 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2010-03-22
楼主如果说Wrapper,更好地理解。
|
|
返回顶楼 | |
发表时间:2010-03-23
一码子事,长沙程序员3年经验工资几何?房价几何
|
|
返回顶楼 | |
发表时间:2010-03-23
lich0079 写道 一码子事,长沙程序员3年经验工资几何?房价几何
一般来说,工资买不起房~ |
|
返回顶楼 | |
发表时间:2010-03-23
我要知道数据 不要结论
|
|
返回顶楼 | |