java设计模式(三)


设计模式中的第二类是结构型模式,共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();
 }
}


。。。。。。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值