设计模式之适配器模式、外观模式浅析


外观模式强调统一和简化接口,而适配器模式强调转换接口



1、适配器模式

/**
 * 
 * 适配器模式
 *     将一种接口转换为用户所期望的另一种接口
 * 
 * 对象适配器--使用组合拥有被适配者接口,使用实现实现目的接口
 * 类适配器--使用继承拥有被适配者与目的类
 * 
 * 目的接口:用户所期望的接口
 * 被适配器接口:待转换的接口
 * 适配器:实现目的接口,同时使用组合包含被适配器接口,将被适配器接口转换为目的接口
 * 适配器让原本接口不兼容的类可以合作无间
 *     
 * 实例
 *   火鸡与鸭子
 *     鸭子会叫,也会飞
 *     火鸡只会咯咯叫 飞的很近
 *     将火鸡转换为鸭子
 * 
 * @author Administrator
 *
 */


鸭子接口


package com.undergrowth.adapter;

/**
 * 
 * 适配器模式
 *     将一种接口转换为用户所期望的另一种接口
 * 
 * 对象适配器--使用组合拥有被适配者接口,使用实现实现目的接口
 * 类适配器--使用继承拥有被适配者与目的类
 * 
 * 目的接口:用户所期望的接口
 * 被适配器接口:待转换的接口
 * 适配器:实现目的接口,同时使用组合包含被适配器接口,将被适配器接口转换为目的接口
 * 适配器让原本接口不兼容的类可以合作无间
 *     
 * 实例
 *   火鸡与鸭子
 *     鸭子会叫,也会飞
 *     火鸡只会咯咯叫 飞的很近
 *     将火鸡转换为鸭子
 * 
 * @author Administrator
 *
 */
public interface Duck {
	
	public void quack();
	public void fly();
	
	
}

绿头鸭

package com.undergrowth.adapter;

/**
 * 绿头鸭
 * @author Administrator
 *
 */
public class MallardDuck implements Duck {

	@Override
	public void quack() {
		// TODO Auto-generated method stub
		System.out.println("quack");
	}

	@Override
	public void fly() {
		// TODO Auto-generated method stub
		System.out.println("i can fly");
	}

}

火鸡接口

package com.undergrowth.adapter;



/**
 * 火鸡
 * @author Administrator
 *
 */
public interface Turkey {
	public void gobble();
	public void fly();
}

野生火鸡

package com.undergrowth.adapter;

public class WildTurkey implements Turkey {

	@Override
	public void gobble() {
		// TODO Auto-generated method stub
		System.out.println("gobble");
	}

	@Override
	public void fly() {
		// TODO Auto-generated method stub
		System.out.println("i can fly,but slower");
	}

}

将火鸡转换为鸭子的适配器

package com.undergrowth.adapter;

/**
 * 火鸡适配器 将火鸡转换为鸭子
 * 
 * @author Administrator
 * 
 */
public class TurkeyAdapter implements Duck {

	Turkey turkey;

	public TurkeyAdapter(Turkey turkey) {
		this.turkey = turkey;
	}

	@Override
	public void quack() {
		// TODO Auto-generated method stub
		turkey.gobble();
	}

	@Override
	public void fly() {
		// TODO Auto-generated method stub
		turkey.fly();
	}

}

测试类

package com.undergrowth.adapter.test;

import static org.junit.Assert.*;

import org.junit.Test;

import com.undergrowth.adapter.Duck;
import com.undergrowth.adapter.Turkey;
import com.undergrowth.adapter.TurkeyAdapter;
import com.undergrowth.adapter.WildTurkey;

public class TurkeyAdapterTest {

	@Test
	public void test() {
		Turkey turkey=new WildTurkey();
		//将火鸡转为鸭子
		Duck duck=new TurkeyAdapter(turkey);
		duck.quack();
		duck.fly();
	}

}


输出

gobble
i can fly,but slower

另外一个适配器实例 将枚举接口转换为迭代器接口

枚举数据类

package com.undergrowth.adapter;

import java.util.Enumeration;

public class  NumEnum implements Enumeration{

	int length;
	int count;
	String[] data=null;
	public NumEnum(String[] data){
		this.data=data;
		count=0;
		length=data.length;
	}
	
	@Override
	public boolean hasMoreElements() {
		// TODO Auto-generated method stub
		return (count<length);
	}

	@Override
	public Object nextElement() {
		// TODO Auto-generated method stub
		return data[count++];
	}
	
}


枚举适配器

package com.undergrowth.adapter;

/**
 * 将Enumeration转换为Iterator
 */
import java.util.Enumeration;
import java.util.Iterator;

public class EnumeIteratorAdapter implements Iterator {

	Enumeration enumeration;
	
	public EnumeIteratorAdapter(Enumeration enumeration){
		this.enumeration=enumeration;
	}
	
	@Override
	public boolean hasNext() {
		// TODO Auto-generated method stub
		return enumeration.hasMoreElements();
	}

	@Override
	public Object next() {
		// TODO Auto-generated method stub
		return enumeration.nextElement();
	}

	@Override
	public void remove() {
		// TODO Auto-generated method stub
		throw new UnsupportedOperationException();
	}

}

测试

package com.undergrowth.adapter.test;

import static org.junit.Assert.*;

import java.util.Enumeration;
import java.util.Iterator;

import org.junit.Test;

import com.undergrowth.adapter.EnumeIteratorAdapter;
import com.undergrowth.adapter.NumEnum;
import com.undergrowth.decorate.Price;

public class EnumeIteratorAdapterTest {

	@Test
	public void test() {
		String[] data={"百度","谷歌","IBM","Oracle","Microsoft","HP","Lenovo","Tecent"};
		Enumeration enumeration=new NumEnum(data);
		Iterator iterator=new EnumeIteratorAdapter(enumeration);
		while(iterator.hasNext()){
			System.out.println(iterator.next());
		}
	}

}

输出

百度
谷歌
IBM
Oracle
Microsoft
HP
Lenovo
Tecent


2、外观模式

/**
 * 设计原则:
 *   最少知识原则:只和你的密友交谈
 * 为了只和你的密友交谈,对象中方法应该只出现在一下四种情况调用
 *   1、对象本身中
 *   2、对象作为其他对象的任何组件
 *   3、对象作为方法参数进行传递
 *   4、此方法所创建的实例化对象中
 *   1、3、4的意味着不要在调用其他方法返回的对象上调用其方法  
 *   
 *   
 * 外观模式
 *   提供了一个统一的接口,用来访问子系统的一群接口
 *   定义了一个高层接口,让子系统更容易使用  
 * 外观模式只是提供了一个子系统的访问接口,并不影响子系统的单独使用
 * 外观强调统一和简化接口,而适配器强调转换接口
 * 
 * 示例
 *   家庭影院
 * 
 * @author Administrator
 *
 */
家庭影院类

package com.undergrowth.facade;


/**
 * 设计原则:
 *   最少知识原则:只和你的密友交谈
 * 为了只和你的密友交谈,对象中方法应该只出现在一下四种情况调用
 *   1、对象本身中
 *   2、对象作为其他对象的任何组件
 *   3、对象作为方法参数进行传递
 *   4、此方法所创建的实例化对象中
 *   1、3、4的意味着不要在调用其他方法返回的对象上调用其方法  
 *   
 *   
 * 外观模式
 *   提供了一个统一的接口,用来访问子系统的一群接口
 *   定义了一个高层接口,让子系统更容易使用  
 * 外观模式只是提供了一个子系统的访问接口,并不影响子系统的单独使用
 * 外观强调统一和简化接口,而适配器强调转换接口
 * 
 * 示例
 *   家庭影院
 * 
 * @author Administrator
 *
 */
public class HomeTheatre {

	Amplifier amp;
	Projector pro;
	Screen scr;
	Curtain cur;
	public HomeTheatre(Amplifier amp,Projector pro,Screen scr,Curtain cur){
		this.amp=amp;
		this.pro=pro;
		this.cur=cur;
		this.scr=scr;
	}
	
	public void watchMovie(){
		cur.close();
		scr.down();
		pro.open();
		amp.openAmp();
		amp.setPlayer(0);
		amp.setVolume(10);
	}
	public void closeMovie(){
		amp.closeAmp();
		pro.close();
		scr.up();
		cur.open();
	}
	
	
}

攻放

package com.undergrowth.facade;


/**
 * 功放
 * @author Administrator
 *
 */
public class Amplifier {
	
	 public void openAmp(){
		 System.out.println("打开功放");
	 }
	
	 public void closeAmp(){
		 System.out.println("关闭功放");
	 }
	 
	 public void setVolume(int volume){
		 System.out.println("设置音量为"+5);
	 }
	 
	 public void setPlayer(int num){
		 switch (num) {
		case 1:
			System.out.println("设置CD播放");
			break;
		default:
			System.out.println("设置DVD播放");
			break;
		}
		 
	 }
}


投影仪

package com.undergrowth.facade;

/**
 * 投影仪
 * @author Administrator
 *
 */
public class Projector {

	public void open()
	{
		System.out.println("打开投影仪");
	}
	public void close(){
		System.out.println("关闭投影仪");
	}
}


屏幕

package com.undergrowth.facade;

/**
 * 将投影的屏幕放下
 * @author Administrator
 *
 */
public class Screen {
	
	public void down(){
		System.out.println("放下投影屏幕");
	}
	public void up(){
		System.out.println("收起投影屏幕");
	}
	
}


窗帘

package com.undergrowth.facade;

/**
 * 窗帘
 * @author Administrator
 *
 */
public class Curtain {
	
	public void close(){
		System.out.println("关上窗帘");
	}
	public void open(){
		System.out.println("打开窗帘");
	}
}

测试类

package com.undergrowth.facade;

import static org.junit.Assert.*;

import org.junit.Test;

public class HomeTheatreTest {

	@Test
	public void test() {
		Amplifier amp=new Amplifier();
		Projector pro=new Projector();
		Screen scr=new Screen();
		Curtain cur=new Curtain();
		HomeTheatre homeTheatre=new HomeTheatre(amp, pro, scr, cur);
		homeTheatre.watchMovie();
		System.out.println("=================我是分割线==================");
		homeTheatre.closeMovie();
	}

}

输出

关上窗帘
放下投影屏幕
打开投影仪
打开功放
设置DVD播放
设置音量为5
=================我是分割线==================
关闭功放
关闭投影仪
收起投影屏幕
打开窗帘





posted on 2014-12-08 21:55  liangxinzhi  阅读(166)  评论(0编辑  收藏  举报