博客详情

java设计模式(三) (原创)

作者: 朝如青丝暮成雪
发布时间:2017-09-23 09:18:13  文章分类:java编程   阅读(730)  评论(0)
设计模式中的第二类是结构型模式,共7种:
      合成、适配器、装饰器、享元、门面(外观)、代理、桥梁

本篇介绍其前4种  。

Componsite
合成模式:
  1 合成模式属于对象的结构模式,又叫做整体--部分模式, 合成模式将对象组织到树形结构中,可以用来描述整体与部分的关系
  2 合成模式通常为树形结构,其中包括了树枝节点和树叶节点。树枝节点可以有子节点(树叶节点),树叶节点无子节点。
  3 树枝节点维护树叶节点的聚集与操作。

Component 抽象组件类

package com.jelly.mypattern.composite;  
  
/** 
 * 抽象构件 
 * 这是一个抽象角色,它给参与组合的对象定义出公共的接口及默认行为 
 */  
public interface Component {  
     
    //示例操作方法  
    public void sampleOperation();  
    //返回自己  
    public  Composite getComposite();  
      
}  

Composite   树枝

package com.jelly.mypattern.composite;  
  
import java.util.ArrayList;  
import java.util.Iterator;  
import java.util.List;  
/** 
 * 树枝组件  
 *  可以有子节点--树枝或树叶节点 
 * @author jelly 
 */  
public class Composite  implements Component{  
    private List<Component> comList=new ArrayList<Component>();  
  
    //操作方法  
    @Override  
    public void sampleOperation() {  
        for(Component component  :comList){  
            component.sampleOperation();  
        }  
    }  
    //返回自身  
    @Override  
    public Composite getComposite() {  
         return this;  
    }  
  
    /** 
     * 管理聚集的方法  添加 
     * @param component 
     */  
    public void add(Component component){  
        comList.add(component);  
    }  
    /** 
     * 管理聚集的方法  删除 
     * @param component 
     */  
    public void  remove(Component component){  
        comList.remove(component);  
    }  
    /** 
     * 返回管理聚集的迭代器对象 
     * @return 
     */  
    public Iterator<Component>  iterator(){  
        return comList.listIterator();  
    }  
}  

Leaf 树叶

package com.jelly.mypattern.composite;  
  
  
/** 
 * 树叶组件 
 * @author jelly 
 * 
 */  
public class Leaf  implements Component{  
  
  
    @Override  
    public void sampleOperation() {  
         System.out.println("leaf  some operation...");  
    }  
  
  
    @Override  
    public Composite getComposite() {  
       
        return null;  
    }  
  
  
}  

客户端测试代码

package com.jelly.mypattern.composite;  
/** 
 * 客户端测试代码 
 * @author jelly 
 * 
 */  
public class CompositeTest {  
   public static void main(String[] args) {  
         Component com=new Composite();  
        Composite componsite=  com.getComposite();  
        Component leaf1=new Leaf();  
        Component leaf2=new Leaf();  
        Component leaf3=new Leaf();  
        Component leaf4=new Leaf();  
        componsite.add(leaf1);  
        componsite.add(leaf2);  
        Component  comsite=new Composite();  
        comsite.getComposite().add(leaf3);  
        comsite.getComposite().add(leaf4);  
        componsite.add(comsite);  
        componsite.sampleOperation();  
    }  
}  


Adapter
适配器模式:
将一个类的接口变成客户端期望的另一种接口,使得原本因接口不匹配而不能一起工作的两个类能够在一起工作,解决接口不兼容的问题。
 1  适配器模式分为类的适配和对象的适配2种方式,前者采用继承,后者采用引用关联。两种方式中,后者更为常见、灵活、易于扩展。
 2   适配器负责将原接口向目标接口转换、靠拢,倾向于目标接口,适配过程中可能会补充原接口没有的方法。
 3  例子,从 Iterator 到Enumerator接口的适配:  Itermeration 。 从 Enumerator 到Iterator 接口的适配:Enuterator
4   缺省适配器模式( DefaultAdapter Pattern) 也属于适配器模式(java awt/swing 类库十分常见的模式),缺省适配器提供的父接口中所有方法的空实现(称为钩子方法)。
      子类中可以通过继承缺省适配器,而不是父接口,然后覆盖几个自己关注的钩子方法就可以实现自己的业务需求。  
Itermeration 适配器

package com.jelly.mypattern.adapter;  
  
import java.util.Enumeration;  
import java.util.Iterator;  
  
/** 
 * Itermeration  
 * 从 Iterator 到Enumerator 的适配。 
 * Itermeration 名称取自Iterator的前部分和Enumeration的后部分 
 * @author jelly 
 * 
 */  
  
public class Itermeration<E> implements Enumeration<E> {  
     private Iterator<E> it;  
    public Itermeration(Iterator<E> it) {  
      this.it=it;  
    }  
    @Override  
    public boolean hasMoreElements() {  
       return    it.hasNext();  
    }  
    @Override  
    public E nextElement() {  
       return it.next();  
    }  
}  

Enuterator 适配器

package com.jelly.mypattern.adapter;  
import java.util.Enumeration;  
import java.util.Iterator;  
/** 
 * Enuterator 
 * 从Enumerator  到Iterator 的适配。 
 * Enuterator 名称取自Enumerator的前部分和Iterator的后部分 
 * @author jelly 
 * 
 */  
public class Enuterator<E> implements Iterator<E>{  
    private Enumeration<E> enu;  
      
    public Enuterator(Enumeration<E> enu ) {  
        this.enu=enu;  
    }  
    @Override  
    public boolean hasNext() {  
        return enu.hasMoreElements();  
    }  
    @Override  
    public E next() {  
        return enu.nextElement();  
    }  
    @Override  
    public void remove() {  
        throw new UnsupportedOperationException();  
    }  
}  

java I/O库中的设计 --两大对称与两大模式
两大对称: 1 输入与输出的对称    reader与writer ,inputStream与outputStream
                   2  字节流与字符流的对称  reader 与inputStream  ,writer与outputStream
两大模式:装饰模式与适配器模式
如  
BufferedReader、 BufferInputStream 、LineNumberInputStream 等 采用了装饰模式。
ByteArrayInputStream 、BufferedReaderInputStream、 InputStreamReader、 OutputStreamWriter 等均采用了适配器模式。
 

Decorator 
 装饰模式:
 以客户端透明的方式扩展对象的功能,是继承关系的一种替代方案
 1 装饰器通常与被装饰者实现相同的接口,并持有被装饰者的对象引用
 2 装饰器在不改变原有接口的基础上进行功能的增强(称为纯粹的装饰器)
 3 大多数情况下装饰器在增强功能的同时还会新增新的方法,称为非纯装饰器。
如JDK类库中BufferedReader 是reader的装饰类,增强了reader的功能,
但同时也引加入了一个新的readLine方法,使得BufferedReader 不能够使用父类Reader来引用自身。这种现象在jdk io类库中十分常见。
对于装饰器类而言,纯粹的装饰类十分少见,非纯装饰类十分常见,它们处于装饰模式与适配器模式之间(尽管如此我们依然称它为装饰器类)
它们含有的新方法越多,则它离装饰模式越远,离适配器模式越近;含有的新方法越少, 则离装饰器模式越近,离适配器模式越远
IComponent 抽象组件 接口

package com.jelly.mypattern.decorator;  
  
/** 
 * 抽象组件  
 * @author jelly 
 * 
 */  
public interface IComponent {  
    /** 
     * 组件显示  通知消息 
     * @param msg 
     */  
   public void showMsg(String msg);  
     
   /** 
    * 组件显示 警告消息 
    * @param name 
    */  
   public void showWarning(String warning);  
}  

Componet具体的组件类

package com.jelly.mypattern.decorator;  
  
/** 
 * 具体的某个组件  实现IComponent接口 
 * @author jelly 
 * 
 */  
public class Component implements IComponent{  
    @Override  
    public void showMsg(String msg) {  
         System.out.println("message: "+msg);  
    }  
    @Override  
    public void showWarning(String warning) {  
         System.out.println("warning: "+warning);  
    }  
}  

ComponentDecorator 装饰器

package com.jelly.mypattern.decorator;  
  
/** 
 * ComponentDecorator 类 
 * 是 Componet的装饰类,与Component类实现相同的接口, 
 * 并在后者的基础上进行功能的增强 
 * @author jelly 
 * 
 */  
public class ComponentDecorator implements IComponent{  
    private Component component;  
    public ComponentDecorator(Component   component) {  
         this.component=component;   
    }  
    @Override  
    public void showMsg(String msg) {  
        System.out.println("please read the message .");  
        component.showMsg(msg);  
    }  
    @Override  
    public void showWarning(String warning) {  
        component.showWarning(warning);  
        System.out.println("your alarm sounded!!!");  
    }  
}  

客户端测试代码

package com.jelly.mypattern.decorator;  
  
/** 
 * 客户端测试类 
 * @author jelly 
 * 
 */  
public class DecoratorTest {  
    /** 
     * Decorator  
     * 装饰模式:  
     *   1 装饰器通常与被装饰者实现相同的接口,并持有被装饰者的对象引用 
     *   2 装饰器在不改变原有接口的基础上进行功能的增强(称为纯粹的装饰器) 
     *   3 大多数情况下装饰器在增强功能的同时还会新增新的方法,称为非纯装饰器。 
     *     如JDK类库中BufferedReader 是reader的装饰类,增强了reader的功能, 
     *     但同时也引加入了一个新的readLine方法,使得BufferedReader 不能够使用父类Reader 
     *     来引用自身。这种现象在jdk io类库中是否常见。 
     *     对于装饰器类而言,纯粹的装饰类十分少见,非纯装饰类十分常见,它们处于装饰模式与适配器模式之间(尽管如此我们依然称它为装饰器类) 
     *     它们含有的新方法越多,则它离装饰模式越远,离适配器模式越近;含有的新方法越少,则离装饰器模式越近,离适配器模式越远。 
     *     
     * @param args 
     */  
    public static void main(String[] args) {  
        Component  component=new Component();  
        component.showMsg("Goods morning boys and girls!");  
        component.showWarning("Hurry up, you're going to be late. ");  
        System.out.println("----------");  
        ComponentDecorator comDecorator=new ComponentDecorator(component);  
        comDecorator.showMsg("Goods morning boys and girls!");  
        comDecorator.showWarning("Hurry up, you're going to be late. ");  
          
    }  
}  


FlyWeight
享元模式
1 当应用系统中存在大量可共享的微小的对象时,可以考虑使用享元模式
2 享元模式需要一个享元工厂来维护享元对象的集合,该工厂通常是单例的。
3 享元对象之所以可以被很多客户端共享,是因为它们只含只含有可共享的状态
4 享元模式要求享元对象必须是可共享的而不是状态不变的 (状态可变,但不能受环境影响)
 Word  字类 --享元类

package com.jelly.mypattern.flyWeight;  
  
/** 
 *  
 * ‘字 ’ 类 
 * @author jelly 
 * 
 */  
public class Word {  
     
    //内蕴状态 共享的   不允许外部修改,  
    private String letters;//组成单词的字母    
    public Word(String letters) {  
         this.letters=letters;  
    }  
   /** 
    * 显示‘字’  ,size 是外蕴状态可以在方法中传入,但方法中不能修改享元实体的内蕴状态 
    * @param size 
    */  
    public void display(int size){  
        System.out.println("【"+letters+"】, display in "+size+" px");  
    }  
}  


WordFacotry  类--享元工厂

package com.jelly.mypattern.flyWeight;  
  
import java.util.HashMap;  
import java.util.Map;  
import java.util.Map.Entry;  
import java.util.Set;  
  
/** 
 * 生产 ‘字’ 的工厂 
 * @author jelly 
 * 
 */  
public class WordFactory {  
    private static  WordFactory wordFactory=new WordFactory();  
    private  Map<String,Word> wordCache=new HashMap<String,Word>();  
      
    /** 
     * 私有化构造函数 
     */  
    private WordFactory(){  
    }  
    /** 
     * 暴露一个静态工厂方法,返回自身的唯一实例 
     * 享元工厂 
     * @return 
     */  
    public static WordFactory  getInstance(){  
        return wordFactory;  
    }  
    /** 
     * 生产 ‘字’ 的方法  线程同步方法 
     * @param letters 
     * @return 
     */  
    public synchronized  Word getWord(String letters){  
        Word word=wordCache.get(letters);  
        if(word==null){  
            word=new Word(letters);  
            wordCache.put(letters, word);  
        }  
        return word;  
    }  
    //遍历显示缓存池中所有的享元对象。    
    public void  dispayAllWord(){  
        Set<Entry<String, Word>> entrySet=   wordCache.entrySet();  
        for(Entry<String, Word> en:   entrySet){  
            System.out.println(en.getKey()+"-->"+en.getValue());  
        }  
     }  
}  


客户端测试代码 

package com.jelly.mypattern.flyWeight;  
  
public class FlyWeightTest {  
    /** 
     * 享元模式 
     *  1 当应用系统中存在大量可共享的微小的对象时,可以考虑使用享元模式 
     *  2 享元模式需要一个享元工厂来维护享员对象的集合,该工厂通常是单例的。 
     *  3 享元对象之所以可以被很多客户端共享,是因为它们只含只含有可共享的状态 
     *  4 享元模式要求享元对象必须是可共享的而不是状态不变的。  
     */  
  public static void main(String[] args) {  
     WordFactory factory=WordFactory.getInstance();  
      Word  word1=factory.getWord("hello");  
      word1.display(10);  
      Word  word2=factory.getWord("hello");  
      word2.display(12);  
      Word  word3=factory.getWord("good");  
      word3.display(13);  
        
      System.out.println("word1 的内存地址:"+word1);  
      System.out.println("word2 的内存地址:"+word2);  
      if(word1==word2){  
          //如果内存地址相等,说明从工厂中得到的同一个 共享对象 (享元对象)  
          System.out.println("从工厂中得到的同一个共享对象 (享元对象)");  
      }  
      factory.dispayAllWord();  
 }  
}  

关键字:  设计模式  java
评论信息
暂无评论
发表评论

亲,您还没有登陆,暂不能评论哦! 去 登陆 | 注册

博主信息
   
数据加载中,请稍候...
文章分类
   
数据加载中,请稍候...
阅读排行
 
数据加载中,请稍候...
评论排行
 
数据加载中,请稍候...

Copyright © 叮叮声的奶酪 版权所有
备案号:鄂ICP备17018671号-1

鄂公网安备 42011102000739号