allbet gaming电脑版下载:原型模式

admin 3个月前 (07-16) 科技 47 0

目录
  • 原型模式的基本先容
  • 原型模式(浅克隆)
  • 原型模式(深克隆)
    • 逐层克隆
    • 序列化

序言:今天我们来聊一下原型模式,我个人认为原型模式的命名不太好明白,称谓其为克隆模式会更稳健一点。原型模式的目的是通过复制一个现有的工具来天生一个新的工具,而不是通过实例化的方式。

原型模式的基本先容

  • 用已经建立的实例工具作为原型,通过复制工具来建立一个和原型相同的工具或相似的新工具

  • 原型模式属于建立型模式,主要通过 Cloneable 接口去完成 工具的复制

     

在原型模式结构图中,会有这么几个角色

  • 抽象原型角色(Prototype):是声明克隆方式的接口,是所有原型类的公共父类
  • 详细原型角色(Realizetype):它实现在抽象原型类中所声明的克隆方式,在克隆方式中返回一个克隆工具
  • 接见角色(PrototypeTest): 使用详细原型类中的 clone() 方式来复制新的工具

 

需要注重的点:

在 Java 中 能够克隆的 Java类 务必得 实现 Cloneable 接口,示意这个 类 能够被 “复制”,至于这个 复制的效果 则与我们的实现有关,通常 clone()方式知足以下的条件:

  • 对任何的工具x,都有:x.clone()!=x 。换言之,克隆工具与元工具不是一个工具
  • 对任何的工具x,都有:x.clone().getClass==x.getClass(),换言之,克隆工具与元工具的类型一样
  • 对任何的工具x,若是 equals() 方式编写适合的话, 那么x.clone().equals(x)应该是建立的

在正式最先原型模式之前,我们先领会两个观点 浅克隆和深克隆浅克隆和深克隆的主要区别在于是否支持引用类型的成员变量的复制

 

原型模式(浅克隆)

在浅克隆中,若是原型工具的成员变量是值类型,将复制一份给克隆工具;若是原型工具的成员变量是引用类型,则将引用工具的地址 复制 一份给克隆工具,也就是说原型工具和克隆工具的成员变量指向 相同 的内存地址

下面我们以 花园和花 为案例

假设我们有一个花园,我们在花园里莳植上好的牡丹花,有一天突然想照着牡丹园再建一个一模一样的园子,只是在花园中改种玫瑰

/**
 * 花园 
 */
@Data
@AllArgsConstructor
public class Garden implements Cloneable {
	
	//面积
	private double area;
	private Flower flower;
	
	@Override
	protected Garden clone() {
		Garden garden = null;
		try {
			garden = (Garden) super.clone();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return garden;
	}
	
}
@Data
@AllArgsConstructor
public class Flower {
	
	private String name;
	private String color;
	
}

 

下面来测试一下原型模式(浅克隆)

public class Client {
	public static void main(String[] args) {
		// 牡丹花
		Flower peony = new Flower("牡丹", "blue");
		// 牡丹园
		Garden peonyGarden = new Garden(1000, peony);
		System.out.println("初始的牡丹园:" + peonyGarden);
		// 牡丹园的复制制作 然则花改成玫瑰 更名玫瑰园
		Garden roseGarden = peonyGarden.clone();
		//浅复制只会复制引用地址,并没有重新复制一个工具
		System.out.println(peonyGarden.getFlower() == roseGarden.getFlower());
		// 改为莳植玫瑰花
		roseGarden.getFlower().setName("玫瑰");
		roseGarden.getFlower().setColor("red");
		System.out.println("玫瑰园:" + roseGarden);
		System.out.println("牡丹园:" + peonyGarden);
	}
}

 

我们发现,我们想在新开拓的花园中改种玫瑰后,会影响原花园的花卉的品种,这显然不是我们想要的效果

从这里我们也看出来了,浅克隆 在克隆一个工具的 引用类型的成员变量时 只是复制其地址值,并没有复制该工具

 

原型模式(深克隆)

在深克隆中,无论原型工具的成员变量是值类型照样引用类型,都将复制一份给克隆工具,深克隆将原型工具的所有引用工具也复制一份给克隆工具。简朴来说,在深克隆中,除了工具自己被复制外,工具所包罗的所有成员变量也将复制。
 
在 Java 中想实现 深克隆,通常有 两种方式

  • 对于克隆工具的 引用类型,逐层克隆
  • 使用序列化方式

 

逐层克隆

逐层克隆意味着,若是我们要拷贝一个工具,该工具中 若有多个引用类型的成员变量,它们都要实现克隆方式,若嵌套多层引用类型的成员变量,则逐层 实现 Cloneable 接口

**
 * 花园 
 */
@Data
@AllArgsConstructor
public class Garden implements Cloneable {
	
	//面积
	private double area;
	private Flower flower;
	
	@Override
	protected Garden clone() {
		Garden garden = null;
		try {
			garden = (Garden) super.clone();
			garden.flower = garden.flower.clone();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return garden;
	}
	
}
@Data
@AllArgsConstructor
public class Flower implements Cloneable {

	private String name;
	private String color;
	
	@Override
	protected Flower clone() {
		Flower flower = null;
		try {
			flower = (Flower) super.clone();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return flower;
	}
	
}

 

下面我们测试一下,使用逐层实现 Cloneable 接口 而完成的深克隆

public class Client {
	public static void main(String[] args) {
		// 牡丹花
		Flower peony = new Flower("牡丹", "blue");
		// 牡丹园
		Garden peonyGarden = new Garden(1000, peony);
		// 牡丹园的复制制作 然则花改成玫瑰 更名玫瑰园
		Garden roseGarden = peonyGarden.clone();
		// 深克隆 面临引用类型的成员变量 也重新复制了一个工具
		System.out.println(peonyGarden.getFlower() == roseGarden.getFlower());
		// 改为莳植玫瑰花
		roseGarden.getFlower().setName("玫瑰");
		roseGarden.getFlower().setColor("red");
		System.out.println("玫瑰园:" + roseGarden);
		System.out.println("牡丹园:" + peonyGarden);
	}
}

 

序列化

深克隆模式,接纳序列化这种方式可能更简朴一些,以是的引用类型 成员变量,都实现序列化接口,原型工具 自实现 deepClone 方式即可

/**
 * 花园 
 */
@Data
@AllArgsConstructor
public class Garden implements Serializable {
	
	private static final long serialVersionUID = 2231850409918603998L;
	//面积
	private double area;
	private Flower flower;
	
	//深拷贝-方式2 使用序列化方式
	public Garden deepClone(){
		//建立流工具
		ByteArrayOutputStream bos = null;
		ObjectOutputStream oos = null;
		ByteArrayInputStream bis = null;
		ObjectInputStream ois = null;
		Garden garden = null;
		try {
			//序列化
			bos = new ByteArrayOutputStream();
			oos = new ObjectOutputStream(bos);
			oos.writeObject(this); //当前这个工具以工具的方式输出
			
			//反序列化
			bis = new ByteArrayInputStream(bos.toByteArray());
			ois = new ObjectInputStream(bis);
			garden = (Garden) ois.readObject();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return garden;
	}
	
}
@Data
@AllArgsConstructor
public class Flower implements Serializable {

	private static final long serialVersionUID = 126839939664064143L;
	
	private String name;
	private String color;
	
	@Override
	protected Flower clone() {
		Flower flower = null;
		try {
			flower = (Flower) super.clone();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return flower;
	}
	
}

 

下面我们举行序列化深克隆的测试

public class Client {
	public static void main(String[] args) {
		// 牡丹花
		Flower peony = new Flower("牡丹", "blue");
		// 牡丹园
		Garden peonyGarden = new Garden(1000, peony);
		// 牡丹园的复制制作 然则花改成玫瑰 更名玫瑰园
		Garden roseGarden = peonyGarden.deepClone();
		// 深克隆 面临引用类型的成员变量 也重新复制了一个工具
		System.out.println(peonyGarden.getFlower() == roseGarden.getFlower());
		// 改为莳植玫瑰花
		roseGarden.getFlower().setName("玫瑰");
		roseGarden.getFlower().setColor("red");
		System.out.println("玫瑰园:" + roseGarden);
		System.out.println("牡丹园:" + peonyGarden);
	}
}

allbet gaming电脑版下载:原型模式 第1张

 

从上述我们可以看出,深克隆不仅在堆内存上开拓了空间以存储复制出的工具,甚至连工具中的引用类型的属性所指向的工具也得以复制,重新开拓了堆空间存储。

,

欧博官网

欢迎进入欧博官网(Allbet Game):www.aLLbetgame.us,欧博官网是欧博集团的官方网站。欧博官网开放Allbet注册、Allbe代理、Allbet电脑客户端、Allbet手机版下载等业务。

皇冠APP声明:该文看法仅代表作者自己,与本平台无关。转载请注明:allbet gaming电脑版下载:原型模式

网友评论

  • (*)

最新评论

标签列表

    文章归档

    站点信息

    • 文章总数:530
    • 页面总数:0
    • 分类总数:8
    • 标签总数:893
    • 评论总数:151
    • 浏览总数:9270