Java设计模式之适配器模式

转载 2015年07月06日 17:32:07

原型模式是一种创建型设计模式,通过给出一个原型对象来指明所有创建的对象的类型,然后用复制这个原型对象的办法创建出更多同类型的对象。


原型模式有两种表现形式:

1)简单形式;

2)登记形式,这两种表现形式仅仅是原型模式的不同实现。


简单形式的原型模式,涉及到三种角色分别如下:

1)客户(Client)角色:客户类提出创建对象的请求。

2)抽象原型(Prototype)角色:这是一个抽象角色,通常由一个Java接口或Java抽象类实现。此角色给出所有的具体原型类所需的接口。

3)具体原型(Concrete Prototype)角色:被复制的对象。此角色需要实现抽象的原型角色所要求的接口。


原型模式中的拷贝分为"浅拷贝"和"深拷贝":

浅拷贝: 对值类型的成员变量进行值的复制,对引用类型的成员变量只复制引用,不复制引用的对象。

深拷贝: 对值类型的成员变量进行值的复制,对引用类型的成员变量也进行引用对象的复制。


一、浅拷贝

只负责克隆按值传递的数据(比如基本数据类型、String类型),而不复制它所引用的对象,换言之,所有的对其他对象的引用都仍然指向原来的对象。

实体类,具体代码如下:

package com.yoodb;

public class Prototype implements Cloneable{
	private String name;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	@Override
	protected Object clone() {
		// TODO Auto-generated method stub
		try {
			return super.clone();
		} catch (CloneNotSupportedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
	
	
}


测试函数,具体代码如下:

package com.yoodb;

public class TestMain {
	public static void main(String[] args) {
		Prototype pro = new Prototype();
		pro.setName("欢迎收藏www.yoodb.com");
		Prototype prot = (Prototype) pro.clone();
		prot.setName("欢迎收藏www.yoodb.com");
		System.out.println("original object:" + pro.getName());
		System.out.println("cloned object:" + prot.getName());
	}
	
}


运行结果如下:

original object:欢迎收藏www.yoodb.com
cloned object:欢迎收藏www.yoodb.com


二、深拷贝

除了浅度克隆要克隆的值外,还负责克隆引用类型的数据。那些引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象。换言之,深度克隆把要复制的对象所引用的对象都复制了一遍,而这种对被引用到的对象的复制叫做间接复制。

实例一

实体类,具体代码如下:

package com.yoodb;

public class Prototype implements Cloneable{
	private String name;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	@Override
	protected Object clone() {
		// TODO Auto-generated method stub
		try {
			return super.clone();
		} catch (CloneNotSupportedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
	
	
}

//实体二
package com.yoodb;

public class NewPrototype implements Cloneable{
	private String id;
	
	private Prototype prototype;

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public Prototype getPrototype() {
		return prototype;
	}

	public void setPrototype(Prototype prototype) {
		this.prototype = prototype;
	}

	@Override
	protected Object clone() {
		NewPrototype prot = null;
		try {
			prot = (NewPrototype) super.clone();
			prot.prototype = (Prototype) this.getPrototype().clone();
			return prot;
		} catch (Exception e) {
			// TODO: handle exception
		}
		return null;
	}
	
	
}


测试函数,具体代码如下:

package com.yoodb;

public class TestMain {
	public static void main(String[] args) {
		//普通赋值
		Prototype pro = new Prototype();
		pro.setName("欢迎收藏www.yoodb.com");
		NewPrototype newPro = new NewPrototype();
		newPro.setId("yoodb");
		newPro.setPrototype(pro);
		//克隆赋值
		NewPrototype proc = (NewPrototype) newPro.clone();
		proc.setId("yoodb");
		proc.getPrototype().setName("欢迎收藏www.yoodb.com");
		
		System.out.println("original object id:" + newPro.getId());
		System.out.println("original object name:" + newPro.getPrototype().getName());
		 
		System.out.println("cloned object id:" + proc.getId());
		System.out.println("cloned object name:" + proc.getPrototype().getName());
	}
	
}


运行结果如下:

original object id:yoodb
original object name:欢迎收藏www.yoodb.com
cloned object id:yoodb
cloned object name:欢迎收藏www.yoodb.com


实例二

利用串行化来实现深克隆,把对象写道流里的过程是串行化(Serilization)过程;把对象从流中读出来是并行化(Deserialization)过程。

实体类,具体代码如下:

package com.yoodb;

import java.io.Serializable;

public class Prototype implements Serializable{
	
	private static final long serialVersionUID = 1L;
	
	private String name;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
	
}

//实体二
package com.yoodb;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class NewPrototype implements Serializable{
	
	private static final long serialVersionUID = 1L;

	private String id;
	
	private Prototype prototype;

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public Prototype getPrototype() {
		return prototype;
	}

	public void setPrototype(Prototype prototype) {
		this.prototype = prototype;
	}

	protected Object deepClone(){
		try {
			ByteArrayOutputStream bo = new ByteArrayOutputStream();
			ObjectOutputStream oo = new ObjectOutputStream(bo);
			oo.writeObject(this);
			
			ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray());
			ObjectInputStream oi = new ObjectInputStream(bi);
			return oi.readObject();
		} catch (Exception e) {
			// TODO: handle exception
		}
		return null;
	}
	
}


测试函数,具体代码如下:

package com.yoodb;

public class TestMain {
	public static void main(String[] args) {
		//普通赋值
		Prototype pro = new Prototype();
		pro.setName("欢迎收藏www.yoodb.com");
		NewPrototype newPro = new NewPrototype();
		newPro.setId("yoodb");
		newPro.setPrototype(pro);
		//克隆赋值
		NewPrototype proc = (NewPrototype) newPro.deepClone();
		proc.setId("yoodb");
		proc.getPrototype().setName("欢迎收藏www.yoodb.com");
		
		System.out.println("original object id:" + newPro.getId());
		System.out.println("original object name:" + newPro.getPrototype().getName());
		 
		System.out.println("cloned object id:" + proc.getId());
		System.out.println("cloned object name:" + proc.getPrototype().getName());
	}
	
}


运行结果如下:

original object id:yoodb
original object name:欢迎收藏www.yoodb.com
cloned object id:yoodb
cloned object name:欢迎收藏www.yoodb.com


克隆满足的条件:

clone()方法将对象复制了一份并返还给调用者。所谓“复制”的含义与clone()方法是怎么实现的。一般而言,clone()方法满足以下的描述:

1)对任何的对象x,都有:x.clone()!=x。换言之,克隆对象与原对象不是同一个对象。

2)对任何的对象x,都有:x.clone().getClass() == x.getClass(),换言之,克隆对象与原对象的类型一样。

3)如果对象x的equals()方法定义其恰当的话,那么x.clone().equals(x)应当成立的。

来源地址http://blog.yoodb.com/yoodb/article/detail/317

Java设计模式菜鸟系列(八)适配器模式建模与实现

适配器模式(Adapter):将某个类的接口转换成客户端期望的另一个接口表示,目的是消除由于接口不匹配所造成的类的兼容性问题。 主要分为三类:类的适配器模式、对象的适配器模式、接口的适配器模式。 1...
  • JAVE_LOVER
  • JAVE_LOVER
  • 2014年10月05日 19:52
  • 2350

java 设计模式-----适配器模式

现实中的问题 有一个插座,这个插座是三个口的,但是我们手上只有两个触角的插头,一种笨方法就是直接强行把两个触角掰弯,插进去(这种事情我就做过),还有一种方法就是找一个转换头来。 ...
  • yujin753
  • yujin753
  • 2015年05月31日 12:12
  • 1057

JAVA设计模式初探之适配器模式

1. 概述   将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作。 2. 解决的问题   即Adapter模式使得原本由于接口不...
  • jason0539
  • jason0539
  • 2014年03月29日 07:53
  • 45126

23种设计模式(13):适配器模式

本文主要介绍设计模式中的适配器模式。
  • psp0001060
  • psp0001060
  • 2016年02月25日 16:21
  • 587

设计模式——适配器模式 Java源代码

适配器模式,《Head First Design Patterns》给的代码的例子是关于鸭子和火鸡,然而鸭子和火鸡离日常生活比较远。这次,我改编了实验楼网站上面的例子,关于插座和充电器。...
  • u013390476
  • u013390476
  • 2016年01月01日 16:02
  • 2332

设计模式-缺省适配器模式

介绍大家所熟悉的是如果实现某一个接口,必须实现接口中的每一个方法。在适配器模式中,如果目标(Target)角色中的方法众多,需要的仅仅几个。但是根据接口的实现规则,其余的方法也必须实现,这必然造成了很...
  • IO_Field
  • IO_Field
  • 2016年10月11日 21:31
  • 1094

Java经典23种设计模式之结构型模式(三)------附代理模式、适配器模式、外观模式区别

本文介绍7种结构型模式里的剩下两种:享元模式、代理模式。一、享元模式FlyWeight 享元模式比较简单且重要,在很多场合都被用到,只不过封装起来了用户看不到。其概念:运用共享内存技术最大限度的支持大...
  • yanzi1225627
  • yanzi1225627
  • 2014年07月10日 23:33
  • 2783

JAVA设计模式之:适配器模式

适配器模式是把一个类的接口适配成用户所期待的,使得原本由于接口不兼容而不能一起工作的一些类可以在一起工作从而实现用户所期望的功能。 适配器模式的优势:通过适配器,客户端可以调用统一接口,操作简单直接...
  • true100
  • true100
  • 2015年12月16日 10:36
  • 1090

一个示例让你明白适配器模式

本文讨论适配器模式。适配器模式是23中设计模式之一,它的主要作用是在新接口和老接口之间进行适配。它非常像我们出国旅行时带的电源转换器。为了举这个例子,我还特意去京东上搜了一下电源转换器,确实看到了很多...
  • brave2211
  • brave2211
  • 2014年01月26日 00:08
  • 42252

适配器模式之观察者模式

设计模式目录 http://blog.csdn.net/fenglailea/article/details/52733435 风.fox观察者模式定义对象间一种一对多的依赖关系,使得每当一个...
  • wljk506
  • wljk506
  • 2016年10月06日 14:06
  • 406
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Java设计模式之适配器模式
举报原因:
原因补充:

(最多只允许输入30个字)