- 浏览: 1233916 次
- 性别:
- 来自: 上海
文章分类
最新评论
-
lankk:
lankk 写道事实上,在运行String s1=new St ...
理解String 及 String.intern() 在实际中的应用 -
lankk:
事实上,在运行String s1=new String(&qu ...
理解String 及 String.intern() 在实际中的应用 -
lankk:
同意1楼的说法http://docs.oracle.com/j ...
理解String 及 String.intern() 在实际中的应用 -
raoyutao:
...
jdk 线程池 ThreadPoolExecutor -
hongdanning:
理解了。之前困惑的一些明白了。谢谢分享。
理解String 及 String.intern() 在实际中的应用
这个列子是关于汉堡包要和什么材料搭配 汉堡包核心是面包 但中间夹得材料可以是各种食物 即装饰面包以不同的材料
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
评论
4 楼
lich0079
2010-03-23
我要知道数据 不要结论
3 楼
mercyblitz
2010-03-23
lich0079 写道
一码子事,长沙程序员3年经验工资几何?房价几何
一般来说,工资买不起房~
2 楼
lich0079
2010-03-23
一码子事,长沙程序员3年经验工资几何?房价几何
1 楼
mercyblitz
2010-03-22
楼主如果说Wrapper,更好地理解。
发表评论
-
设计模式 笔记
2012-09-19 16:45 1563http://www.evernote.com/shar ... -
代理 与 子类化
2010-12-02 16:11 1196最近看一个斯坦福的视频, 里面的Cocoa框架大量使用了代理模 ... -
bridge 桥接模式
2010-02-04 16:42 1259假想需求 有白人 ... -
享元模式 flyweight
2010-02-04 10:00 1128Ext.get()与Ext.fly()之区别 从一开始接 ... -
动态代理 java
2010-01-13 10:15 1120代理工具类 /** * created on Jan 1 ... -
策略模式 状态模式
2010-01-04 09:55 1689当设计一个对象可能在不同情况下有不同的行为时,一般使用的是父类 ... -
ThreadLocal
2009-12-11 17:05 847ThreadLocal是线程的本地变量,可以防止线程安全问题 ... -
代理模式
2009-12-11 16:58 1187静态代理 接口 public interfac ... -
单例 延迟
2009-11-24 15:22 1091public class Single { privat ... -
Adapter
2008-07-13 17:38 1275以下是自己学习Adapter模式时的理解 interface ...
相关推荐
### Java类库中Decorator模式的应用研究 #### 一、引言 随着软件开发技术的不断发展,设计模式在软件工程中的重要性日益凸显。设计模式能够帮助开发者构建出具有良好结构、高度可扩展性和易于维护的软件系统。其中...
装饰器(Decorator)模式 装饰器(Decorator)模式是一种典型的结构型模式,主要用意是动态地为对象添加一些额外的功能。它提供了一个灵活的替代方案来继承子类,以扩展对象的功能。 在《Element of Reusable ...
装饰模式(Decorator Pattern)是设计模式中的一种结构型模式,它允许在运行时给对象添加新的行为或职责,而无需改变对象的类。在Java中,装饰模式通常通过继承和组合来实现,使得代码具有更好的扩展性和灵活性。...
在Java中,`InputStream`和其相关的装饰类(如`BufferedInputStream`、`DataInputStream`)就是很好的装饰器模式示例。`InputStream`是组件接口,`FileInputStream`等是具体组件,而`BufferedInputStream`则是一个...
4. **具体装饰器(Concrete Decorator)**:实现了Decorator接口,并且在Component的基础上添加了新的行为。具体装饰器通常会包含对Component的实例化,并在其内部方法中调用Component的方法。 举个例子,假设我们...
装饰模式(Decorator Pattern)是设计模式中的一种结构型模式,它在不改变原有对象的基础上,通过添加额外的职责来扩展对象的功能。在C#中,装饰模式尤其适用于那些需要动态地增加或减少对象功能的情况,避免了使用...
装饰者模式是软件设计模式中的一种结构型模式,它...综上所述,装饰者模式在Java编程中是一种重要的设计模式,尤其适用于需要动态添加或删除对象功能的场景。通过以上示例和解释,我们可以更好地理解和应用装饰者模式。
在装饰者模式中,我们通常有两个主要的角色:Component(组件)和Decorator(装饰器)。Component是被装饰的对象接口,定义了所有装饰器和原始对象共同拥有的行为。Concrete Component是Component的具体实现,是实际...
Decorator模式,也称为装饰模式,是设计模式中的一个重要组成部分,它在不改变原有对象接口的前提下,动态地给对象添加新的功能,从而扩展了对象的能力。这篇博客()将深入探讨这个模式的细节。 装饰模式的核心...
Java的IO库是一个复杂而强大的系统,其设计思想和实现方式体现了多种设计模式,包括Decorator(装饰者)模式和Adapter(适配器)模式。本文将深入探讨这两个模式在Java/IO中的应用,并通过实例解释它们如何使得Java...
装饰器模式(Decorator Pattern)是一种结构型设计模式,主要用于在运行时动态地给对象添加新的职责或行为,而不必改变现有对象的类定义。在面向对象编程中,装饰器模式提供了一种相对于继承更加灵活的方式来增强或...
首先,Decorator模式的核心组件包括抽象组件(Component)、具体组件(Concrete Component)、装饰器(Decorator)以及具体装饰器(Concrete Decorator)。抽象组件定义了对象的基本接口,所有组件都必须实现这个...
Java 装饰器设计模式 Java 装饰器设计模式是一种动态给对象添加额外职责的设计模式,通过在运行时添加新的行为,而不是在编译时继承的方式达到功能的扩充。这种模式可以使得系统更加灵活、可维护和可扩展。 首先,...
总的来说,装饰器模式提供了一种优雅的方式,使得在不改变原有对象的基础上,可以通过组合多个装饰器来扩展对象的功能,保持了代码的灵活性和可维护性。在Java的IO库、GUI组件以及其他需要动态扩展功能的场景中,...
装饰模式(Decorator Pattern)是一种结构型设计模式,它在不改变原有对象的基础上,通过包裹一个对象并为其添加新的行为或责任,实现对对象功能的扩展。这种模式在软件开发中非常常见,尤其当需要在运行时动态改变...
“就增加功能来说,Decorator 模式相比生成子类更为灵活” 这句话的含义是,组合比继承更灵活,当可拓展的功能很多时,继承方案会产生大量的子类,而组合可以提
装饰器模式(Decorator Pattern)是一种结构性设计模式,它允许您在不影响同一类的其他对象的行为的情况下,静态或动态地向单个对象添加行为。该模式非常有用,当您想要在运行时添加或删除对象的功能时,或者当您想...
装饰器模式(Decorator)是Java设计模式中的一种结构型模式,它的主要目的是为了在不修改原有对象的基础上,通过添加额外的职责来扩展对象的功能。这种模式可以看作是一种灵活的替代继承来实现功能扩展的方式。 在...
例如,我们可以创建一个`BorderLabel`装饰类,它在普通的UILabel基础上添加边框。 博客链接中提到的简单解释可能涵盖了如何创建装饰器类以及如何使用它来包装原始对象的基本步骤。通常,装饰器模式包含以下几个关键...