JAVA設計模式之 原型模式【Prototype Pattern】,prototypepattern
一、概述:
使用原型執行個體指定建立對象的種類,並且通過拷貝這些原型建立新的對象。簡單的說就是對象的拷貝產生新的對象(對象的複製),原型模式是一種對象建立型模式。
二、使用情境:
建立新的對象可以通過對已有對象進行複製來獲得,如果是相似對象,則只需對其成員變數稍作修改。
三、UML結構圖:
四、參與者
(1) Prototype(抽象原型類):它是聲明複製方法的介面,是所有具體原型類的公用父類,可以是抽象類別也可以是介面,甚至還可以是具體實作類別。
(2) ConcretePrototype(具體原型類):它實現在抽象原型類中聲明的複製方法,在複製方法中返回自己的一個複製對象。
(3) Client(客戶類):讓一個原型對象複製自身從而建立一個全新的對象。
五、用例學習:
1、抽象原型類:Prototype.java
/** * 抽象原型類 * @author lvzb.software@qq.com * */public abstract class Prototype {/** * 提供抽象複製方法 */public abstract Prototype clone();}2、具體原型類:ConcretePrototypeA.java
/** * 具體原型類A * @author lvzb.software@qq.com * */public class ConcretePrototypeA extends Prototype {/** * 淺複製 */@Overridepublic Prototype clone() {Prototype prototype = new ConcretePrototypeA();return prototype;}}3、用戶端測試類別:Client.java
public class Client {public static void main(String[] args) {Prototype prototypeA = new ConcretePrototypeA();Prototype prototypeB = prototypeA.clone();System.out.println(prototypeB.equals(prototypeA)); // return falseSystem.out.println(prototypeB == prototypeA); // return falseSystem.out.println(prototypeB.getClass() == prototypeA.getClass()); // return true}}這裡我們可以看到 prototypeA對象複製了一個對象prototypeB,但是prototypeA != prototypeB, 說明prototypeB是一個全新的Prototype對象。
注意:原型模式通過複製方法所建立的對象是全新的對象,它們在記憶體中擁有新的地址,通常對複製所產生的對象進行修改對原型對象不會造成任何影響,每一個複製對象都是相互獨立的。
六、擴充:
關於淺複製與深複製的簡單介紹:
(1) 在Java語言中,資料類型分為值類型(基礎資料型別 (Elementary Data Type))和參考型別,值類型包括int、double、byte、boolean、char等單一資料型別,參考型別包括類、介面、數組等複雜類型。如下Person對象:
public class Person {// 姓名private String name;// 年齡private int age;// 他的父親private Father father;}
name、age 為基礎資料型別 (Elementary Data Type),father就為參考型別。
淺複製和深複製的主要區別在於是否支援參考型別的成員變數的複製
(2)淺複製:
在Java語言中,通過覆蓋Object類的clone()方法就是實現淺複製,在淺複製中,當對象被複製時只複製它本身和其中包含的值類型的成員變數,而參考型別的成員對象並沒有複製,也就是說原型對象只是將引用對象的地址複製一份給複製對象,複製對象和原型對象的參考型別成員變數還是指向相同的記憶體位址。
注意:能夠實現複製的Java類必須實現一個標識介面Cloneable,表示這個Java類支援被複製。如果一個類沒有實現這個介面但是調用了clone()方法,Java編譯器將拋出一個CloneNotSupportedException異常。
用代碼說話:
1、引用對象:Father.java
public class Father{// 姓名private String name;// 年齡private int age;public Father(String name, int age) {this.name = name;this.age = age;}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;}}2、複製原型類: Person.java
public class Person implements Cloneable{// 姓名private String name;// 年齡private int age;// 他的父親private Father father;/** * 重寫 Object對象的clone方法實現Person對象的複製 */public Person clone(){Object obj = null;try {obj = super.clone();return (Person)obj;} catch (CloneNotSupportedException e) {e.printStackTrace();}return null;}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 Father getFather() {return father;}public void setFather(Father father) {this.father = father;}}3、測試類別:CloneClient.java
public class CloneClient {public static void main(String[] args) {Father father = new Father("老子", 50);Person son = new Person();son.setName("兒子");son.setAge(24);son.setFather(father);// 淺複製出一個兄弟Person對象Person brother = son.clone();System.out.println(brother == son); // return falseSystem.out.println(brother.getFather() == son.getFather()); // return true}}以上 我們可以分析看到son 淺複製出一個"兄弟"對象 brother,但是他們的引用對象"父親"都是同一個對象,所有事實證明淺複製沒有對參考型別對象進行複製。
(3)深複製:
在深複製中,無論原型對象的成員變數是值類型還是參考型別,都將複製一份給複製對象,簡單來說,在深複製中,除了對象本身被複製外,對象所包含的所有成員變數也將複製。
那麼如何?深複製呢?
在Java語言中,如果需要實現深複製,可以通過序列化(Serialization)等方式來實現。序列化就是將對象寫到流的過程,寫到流中的對象是原有對象的一個拷貝,而原對象仍然存在於記憶體中。通過序列化實現的拷貝不僅可以複製對象本身,而且可以複製其引用的成員對象,因此通過序列化將對象寫到一個流中,再從流裡將其讀出來,可以實現深複製。需要注意的是能夠實現序列化的對象其類必須實現Serializable介面,否則無法實現序列化操作。
用代碼說話:
1、引用類:Father.java
import java.io.Serializable;public class Father implements Serializable{// 姓名private String name;// 年齡private int age;public Father(String name, int age) {this.name = name;this.age = age;}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;}}2、複製原型類: Person.java
import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.io.OptionalDataException;import java.io.Serializable;public class Person implements Serializable{// 姓名private String name;// 年齡private int age;// 他的父親private Father father;/** * 深複製 * @return * @throws IOException * @throws ClassNotFoundException * @throws OptionalDataException */public Person deepClone() throws IOException, ClassNotFoundException, OptionalDataException{ //將對象寫入流中 ByteArrayOutputStream bao=new ByteArrayOutputStream(); ObjectOutputStream oos=new ObjectOutputStream(bao); oos.writeObject(this); //將對象從流中取出 ByteArrayInputStream bis=new ByteArrayInputStream(bao.toByteArray()); ObjectInputStream ois=new ObjectInputStream(bis); return (Person) ois.readObject();}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 Father getFather() {return father;}public void setFather(Father father) {this.father = father;}}3、深複製測試類別:DeepCloneClient.java
public class DeepCloneClient {public static void main(String[] args) {Father father = new Father("老子", 50);Person son = new Person();son.setName("兒子");son.setAge(24);son.setFather(father);try {Person brother = son.deepClone();System.out.println(brother == son); // falseSystem.out.println(brother.getFather() == son.getFather()); // false} catch (OptionalDataException e) {e.printStackTrace();} catch (ClassNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}}以上我們可以分析看到通過深複製出來的"兄弟"對象brother 和 son 不僅不等、就連他們的參考型別Father也不等啦。所有證明:通過深複製 複製出了一個完全獨立的全新的對象。
Java中23種設計模式,什是必須瞭解的?
1、簡單原廠模式(Simple Factory Pattern)
2、建造者模式(Builder Pattern)
3、策略(Strategy)模式
4、Factory 方法模式(Factory Method Pattern)
5、抽象原廠模式(Abstract Factory)
6、命令模式(Command Pattern)
7、模版方法(Template Method)
8、單件模式(Single Pattern)
9、原型模式(Prototype Pattern)
java23個設計模式有什
一共23種設計模式!
引用《軟體秘笈-設計模式那點事》書籍:
按照目的來分,設計模式可以分為建立型模式、結構型模式和行為型模式。
建立型模式用來處理對象的建立過程;結構型模式用來處理類或者對象的組合;行為型模式用來對類或對象怎樣互動和怎樣分配職責進行描述。
建立型模式用來處理對象的建立過程,主要包含以下5種設計模式:
Factory 方法模式(Factory Method Pattern)
抽象原廠模式(Abstract Factory Pattern)
建造者模式(Builder Pattern)
原型模式(Prototype Pattern)
單例模式(Singleton Pattern)
結構型模式用來處理類或者對象的組合,主要包含以下7種設計模式:
適配器模式(Adapter Pattern)
橋接模式(Bridge Pattern)
組合模式(Composite Pattern)
裝飾者模式(Decorator Pattern)
面板模式(Facade Pattern)
享元模式(Flyweight Pattern)
代理模式(Proxy Pattern)
行為型模式用來對類或對象怎樣互動和怎樣分配職責進行描述,主要包含以下11種設計模式:
責任鏈模式(Chain of Responsibility Pattern)
命令模式(Command Pattern)
解譯器模式(Interpreter Pattern)
迭代器模式(Iterator Pattern)
中介者模式(Mediator Pattern)
備忘錄模式(Memento Pattern)
觀察者模式(Observer Pattern)
狀態模式(State Pattern)
策略模式(Strategy Pattern)
模板方法模式(Template Method Pattern)
訪問者模式(Visitor Pattern)