`

Decorator 装饰器 模式 java基础类库上的列子

阅读更多

这个列子是关于汉堡包要和什么材料搭配  汉堡包核心是面包 但中间夹得材料可以是各种食物 即装饰面包以不同的材料

 

 

 

 

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,更好地理解。

相关推荐

    Java类库中Decorator模式的应用研究.pdf

    ### Java类库中Decorator模式的应用研究 #### 一、引言 随着软件开发技术的不断发展,设计模式在软件工程中的重要性日益凸显。设计模式能够帮助开发者构建出具有良好结构、高度可扩展性和易于维护的软件系统。其中...

    装饰器(Decorator)模式

    装饰器(Decorator)模式 装饰器(Decorator)模式是一种典型的结构型模式,主要用意是动态地为对象添加一些额外的功能。它提供了一个灵活的替代方案来继承子类,以扩展对象的功能。 在《Element of Reusable ...

    java Decorator装饰模式例子

    装饰模式(Decorator Pattern)是设计模式中的一种结构型模式,它允许在运行时给对象添加新的行为或职责,而无需改变对象的类。在Java中,装饰模式通常通过继承和组合来实现,使得代码具有更好的扩展性和灵活性。...

    JAVA设计模式学习12——装饰器模式

    在Java中,`InputStream`和其相关的装饰类(如`BufferedInputStream`、`DataInputStream`)就是很好的装饰器模式示例。`InputStream`是组件接口,`FileInputStream`等是具体组件,而`BufferedInputStream`则是一个...

    装饰器模式[Decorator]

    4. **具体装饰器(Concrete Decorator)**:实现了Decorator接口,并且在Component的基础上添加了新的行为。具体装饰器通常会包含对Component的实例化,并在其内部方法中调用Component的方法。 举个例子,假设我们...

    C#设计模式之Decorator 装饰模式

    装饰模式(Decorator Pattern)是设计模式中的一种结构型模式,它在不改变原有对象的基础上,通过添加额外的职责来扩展对象的功能。在C#中,装饰模式尤其适用于那些需要动态地增加或减少对象功能的情况,避免了使用...

    设计模式--装饰者模式java例子

    装饰者模式是软件设计模式中的一种结构型模式,它...综上所述,装饰者模式在Java编程中是一种重要的设计模式,尤其适用于需要动态添加或删除对象功能的场景。通过以上示例和解释,我们可以更好地理解和应用装饰者模式。

    Decorator装饰者模式

    在装饰者模式中,我们通常有两个主要的角色:Component(组件)和Decorator(装饰器)。Component是被装饰的对象接口,定义了所有装饰器和原始对象共同拥有的行为。Concrete Component是Component的具体实现,是实际...

    Java设计模式之-Decorator装饰模式

    Decorator模式,也称为装饰模式,是设计模式中的一个重要组成部分,它在不改变原有对象接口的前提下,动态地给对象添加新的功能,从而扩展了对象的能力。这篇博客()将深入探讨这个模式的细节。 装饰模式的核心...

    Java-从Decorator,Adapter模式看Java/IO

    Java的IO库是一个复杂而强大的系统,其设计思想和实现方式体现了多种设计模式,包括Decorator(装饰者)模式和Adapter(适配器)模式。本文将深入探讨这两个模式在Java/IO中的应用,并通过实例解释它们如何使得Java...

    PHP设计模式(八)装饰器模式Decorator实例详解【结构型】

    装饰器模式(Decorator Pattern)是一种结构型设计模式,主要用于在运行时动态地给对象添加新的职责或行为,而不必改变现有对象的类定义。在面向对象编程中,装饰器模式提供了一种相对于继承更加灵活的方式来增强或...

    java Decorator模式的简单例子

    首先,Decorator模式的核心组件包括抽象组件(Component)、具体组件(Concrete Component)、装饰器(Decorator)以及具体装饰器(Concrete Decorator)。抽象组件定义了对象的基本接口,所有组件都必须实现这个...

    Java装饰器设计模式_动力节点Java学院整理

    Java 装饰器设计模式 Java 装饰器设计模式是一种动态给对象添加额外职责的设计模式,通过在运行时添加新的行为,而不是在编译时继承的方式达到功能的扩充。这种模式可以使得系统更加灵活、可维护和可扩展。 首先,...

    Java设计模式之装饰器模式.docx

    总的来说,装饰器模式提供了一种优雅的方式,使得在不改变原有对象的基础上,可以通过组合多个装饰器来扩展对象的功能,保持了代码的灵活性和可维护性。在Java的IO库、GUI组件以及其他需要动态扩展功能的场景中,...

    设计模式之装饰模式(Decorator Pattern)

    装饰模式(Decorator Pattern)是一种结构型设计模式,它在不改变原有对象的基础上,通过包裹一个对象并为其添加新的行为或责任,实现对对象功能的扩展。这种模式在软件开发中非常常见,尤其当需要在运行时动态改变...

    jouryfirst#weekly-1#175.精读《设计模式 - Decorator 装饰器模式》1

    “就增加功能来说,Decorator 模式相比生成子类更为灵活” 这句话的含义是,组合比继承更灵活,当可拓展的功能很多时,继承方案会产生大量的子类,而组合可以提

    java常用设计模式-装饰器模式

    装饰器模式(Decorator Pattern)是一种结构性设计模式,它允许您在不影响同一类的其他对象的行为的情况下,静态或动态地向单个对象添加行为。该模式非常有用,当您想要在运行时添加或删除对象的功能时,或者当您想...

    java设计模式之装饰器模式(Decorator)

    装饰器模式(Decorator)是Java设计模式中的一种结构型模式,它的主要目的是为了在不修改原有对象的基础上,通过添加额外的职责来扩展对象的功能。这种模式可以看作是一种灵活的替代继承来实现功能扩展的方式。 在...

    设计模式-装饰器模式

    例如,我们可以创建一个`BorderLabel`装饰类,它在普通的UILabel基础上添加边框。 博客链接中提到的简单解释可能涵盖了如何创建装饰器类以及如何使用它来包装原始对象的基本步骤。通常,装饰器模式包含以下几个关键...

Global site tag (gtag.js) - Google Analytics