1. 程式人生 > 其它 >原型模式_設計模式_java

原型模式_設計模式_java

技術標籤:設計模式

複製貼上功能我們都用過,我們可以把一個檔案從一個地方複製到另外一個地方,複製完成之後這個檔案和之前的檔案也沒有一點差別,這就是原型模式的思想:首先建立一個例項,然後通過這個例項去拷貝建立新的例項。這篇文章就好好地分析一下原型模式。

文章目錄

1.認識原型模式

1、概念

就比如克隆羊,用原型例項指定建立物件的種類,並通過拷貝這些原型建立新的物件。

java上分析:

在這裡插入圖片描述

首先我們可以看到一共有三個角色:

(1)客戶(Client)角色:客戶類提出建立物件的請求;也就是我們使用者使用複製貼上的功能。

(2)抽象原型(Prototype)角色:此角色定義了的具體原型類所需的實現的方法。也就是定義一個檔案,說明一下它有被克隆複製的功能。

(3)具體原型(Concrete Prototype)角色:實現抽象原型角色的克隆介面。就是我們的檔案實現了可以被複制的功能。

我們會發現其實原型模式的核心就是Prototype(抽象原型),他需要繼承Cloneable介面,並且重寫Object類中的clone方法才能有複製貼上的功能。

2.、分類

既然我們知道原型模式的核心就是拷貝物件,那麼我們能拷貝一個物件例項的什麼內容呢?這就要區分深拷貝和淺拷貝之分了。

(1)淺拷貝:我們只拷貝物件中的基本資料型別(8種),對於陣列、容器、引用物件等都不會拷貝

(2)深拷貝:不僅能拷貝基本資料型別,還能拷貝那些陣列、容器、引用物件等,

下面我們就使用程式碼去實現一下原型模式。這裡實現的是不僅有基本資料型別,還有陣列和容器,所以實現的是深拷貝。

2.程式碼實現原型模式

1.淺拷貝:

public class Sheep implements Cloneable{
	private String name;
	private int age;
	private String color;
	public Sheep friend;
	public Sheep(String name, int age, String color) {
		this.age = age;
		this.name = name;
		this.color = color;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getColor() {
		return color;
	}
	public void setColor(String color) {
		this.color = color;
	}
	@Override
	public String toString() {
		return "Sheep [name=" + name + ", age=" + age + ", color=" + color + "]";
	}
	@Override
	protected Object clone() {
		// TODO 自動生成的方法存根
		Sheep sheep = null;
		try {
			sheep = (Sheep)super.clone();
		}catch(Exception e){
			System.out.println(e.getMessage());
		}
		return sheep;
	}

}
public class ClientDemo02 {
	@Test
	public void test1() {
		
		Sheep sheep = new Sheep("tom", 1, "白色");
		Sheep sheep2 = (Sheep)sheep.clone();
		System.out.println(sheep == sheep2);
	}
	

}

false

public class Client {
	public static void main(String[] args) {
		Sheep sheep = new Sheep("tom", 1, "白色");
		
		sheep.friend = new Sheep("jacy", 2, "黑色");
		
		Sheep sheep2 = (Sheep)sheep.clone();
		Sheep sheep3 = (Sheep)sheep.clone();
		
		
		System.out.println(sheep.friend.hashCode());
		System.out.println(sheep2.friend.hashCode());
		System.out.println(sheep.friend == sheep2.friend);
		
	}

}

在這裡插入圖片描述

2.深拷貝:

import java.io.Serializable;

public class DeepCloneableTarget implements Serializable,Cloneable{
	
	private String className;
	private String classClass;
	private static final long serialVersionUID = 1L;
	
	public DeepCloneableTarget(String className, String classClass) {
		this.classClass = classClass;
		this.className = className;
		
	}
	@Override
	protected Object clone() throws CloneNotSupportedException {
		// TODO 自動生成的方法存根
		return super.clone();
	}

}
import java.io.Serializable;

public class DeepProtoType implements Serializable,Cloneable{
	public String name;
	public DeepCloneableTarget deepCloneableTarget;
	public DeepProtoType() {
		
	}
	//深拷貝實現
	//1.重寫克隆方法
	@Override
	protected Object clone() throws CloneNotSupportedException {
		Object deep = null;
		deep = super.clone();
		DeepProtoType deepProtoType = (DeepProtoType)deep;
		deepProtoType.deepCloneableTarget = (DeepCloneableTarget)deepCloneableTarget.clone();
		
		// TODO 自動生成的方法存根
		return deepProtoType;
	}
	//2.

}
public class Client {
	public static void main(String[] args) throws Exception {
		DeepProtoType deepProtoType = new DeepProtoType();
		deepProtoType.name = "松江";
		deepProtoType.deepCloneableTarget = new DeepCloneableTarget("大牛", "類");
		
		//方式1.深拷貝
		DeepProtoType p1 = (DeepProtoType)deepProtoType.clone();
		System.out.println(deepProtoType.deepCloneableTarget == p1.deepCloneableTarget);
		
	}

}

false

3.分析原型模式

對於原型模式有幾個問題需要我們去注意一下

1、克隆物件不會呼叫構造方法

從上面的輸出其實我們也可以發現,構造方法只在一開始我們建立原型的時候輸出了,fileB和fileC都沒有呼叫構造方法,這是因為執行clone方法的時候是直接從記憶體中去獲取資料的,在第一次建立物件的時候就會把資料在記憶體保留一份,克隆的時候直接呼叫就好了

2、訪問許可權對原型模式無效

原理也很簡單,我們是從記憶體中直接複製的,所以克隆起來也會直接無視,複製相應的內容就好了。

3、使用場景

(1)當我們的類初始化需要消耗很多的資源時,就可以使用原型模式,因為我們的克隆不會執行構造方法,避免了初始化佔有的時間和空間。

(2)一個物件被其她物件訪問,並且能夠修改時,訪問許可權都無效了,什麼都能修改。

OK,對於設計模式其實主要是理解其思想,然後根據自己的需求去靈活的使用。對於其他設計模式的相關文章也在持續更新當中。