Java原型設計模式(Prototype)
1、定義
原型模式(Prototype)就是通過復制一個已經存在的實例來返回新的實例,而不是新建實例,被復制的實例就是我們所稱的原型對象,這個原型是可定制的。
2、原理
有兩部分組成,抽象原型和具體原型。意圖:用原型實例指定創建對象的種類,并且通過拷貝這些原型創建新的對象。
3、原型模式UML圖
4、實現
1>使用一個原型管理器;
2>實現克隆操作(淺拷貝和深拷貝);
3>初始化克隆對象。
5、示例程序
(1)利用Java中的clone方法深拷貝與淺拷貝
淺拷貝:
public class Professor { private String address; private double salary; public Professor(String address, double salary) { this.address = address; this.salary = salary; } public void setAddress(String address) { this.address = address; } public void setSalary(double salary) { this.salary = salary; } @Override public String toString() { return "Professor [address=" + address + ", salary=" + salary + "]"; } } public class Student implements Cloneable { private String name; private int age; private Professor professor; public Student(String name, int age, Professor professor) { this.name = name; this.age = age; this.professor = professor; } @Override public String toString() { return "Student [name=" + name + ", age=" + age + ", Professor=" + professor.toString() + "]"; } @Override public Object clone() { Student student = null; try { // 在運行時,Object中的clone識別出你要復制的是哪一個對象,Object中的clone() // 然后為此對象分配空間,并進行對象的復制,將原始對象的內容一一復制到新對象的存儲空間中。 student = (Student) super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return student; } |
public static void main(String[] args) { Professor professor = new Professor("beijing", 12.0); Student s1 = new Student("zhangsan", 18, professor); Student s2 = (Student) s1.clone(); System.out.println(s1); System.out.println(s2); System.out.println("**************************************"); s2.name = "lisi"; s2.age = 20; s2.professor.setAddress("shanghai"); s2.professor.setSalary(230.0); System.out.println(s1); System.out.println(s2); } } Student [name=zhangsan, age=18, Professor=Professor [address=beijing, salary=12.0]] Student [name=zhangsan, age=18, Professor=Professor [address=beijing, salary=12.0]] ************************************** Student [name=zhangsan, age=18, Professor=Professor [address=shanghai, salary=230.0]] Student [name=lisi, age=20, Professor=Professor [address=shanghai, salary=230.0]] |
深拷貝:
public class Professor2 implements Cloneable { private String address; private double salary; public Professor2(String address, double salary) { this.address = address; this.salary = salary; } public void setAddress(String address) { this.address = address; } public void setSalary(double salary) { this.salary = salary; } @Override public String toString() { return "Professor2 [address=" + address + ", salary=" + salary + "]"; } @Override public Object clone() { Professor2 o = null; try { o = (Professor2) super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return o; } } |
public class Student2 implements Cloneable { private String name; private int age; private Professor2 professor; public Student2(String name, int age, Professor2 professor) { this.name = name; this.age = age; this.professor = professor; } @Override public String toString() { return "Student2 [name=" + name + ", age=" + age + ", Professor2=" + professor.toString() + "]"; } @Override public Object clone() { Student2 o = null; try { // 在運行時,Object中的clone識別出你要復制的是哪一個對象,Object中的clone() // 然后為此對象分配空間,并進行對象的復制,將原始對象的內容一一復制到新對象的存儲空間中。 o = (Student2) super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } o.professor = (Professor2) professor.clone(); return o; } public static void main(String[] args) { Professor2 professor = new Professor2("beijing", 12.0); Student2 s1 = new Student2("zhangsan", 18, professor); Student2 s2 = (Student2) s1.clone(); System.out.println(s1); System.out.println(s2); System.out.println("**************************************"); s2.name = "lisi"; s2.age = 20; s2.professor.setAddress("shanghai"); s2.professor.setSalary(230.0); System.out.println(s1); System.out.println(s2); } } Student2 [name=zhangsan, age=18, Professor2=Professor2 [address=beijing, salary=12.0]] Student2 [name=zhangsan, age=18, Professor2=Professor2 [address=beijing, salary=12.0]] ************************************** Student2 [name=zhangsan, age=18, Professor2=Professor2 [address=beijing, salary=12.0]] Student2 [name=lisi, age=20, Professor2=Professor2 [address=shanghai, salary=230.0]] |
模擬clone方法進行淺拷貝
public interface Prototype { public Prototype clone(); public void setName(String name); public String getName(); } <span style="font-size:14px;">public class ConcretePrototypeA implements Prototype { private String name; public ConcretePrototypeA() { } public ConcretePrototypeA(String name) { this.name = name; } @Override public void setName(String name) { this.name = name; } @Override public String getName() { return this.name; } @Override public Prototype clone() { ConcretePrototypeA prototype = new ConcretePrototypeA(); prototype.setName(this.name); return prototype; } @Override public String toString() { return "ConcretePrototypeA [name=" + name + "]"; } }</span> public class TestPrototype { public static void main(String[] args) { ConcretePrototypeA prototypeA = new ConcretePrototypeA("jimmy"); ConcretePrototypeA prototypeA2 = (ConcretePrototypeA) prototypeA .clone(); System.out.println(prototypeA); System.out.println(prototypeA2); } } ConcretePrototypeA [name=jimmy] ConcretePrototypeA [name=jimmy] |
6、應用場景
系統需要創建的對象是動態加載的,而且產品具有一定層次時,可以考慮使用原型模式。原型模式多用于創建復雜的或者耗時的實例, 因為這種情況下,復制一個已經存在的實例可以使程序運行更高效,或者創建值相等,只是命名不一樣的同類數據。
1>當要實例化的類是在運行時刻指定時,例如,通過動態裝載;
2>或者為了避免創建一個與產品類層次平行的工廠類層次時;
3>或者當一個類的實例只能有幾個不同狀態組合中的一種時。
4>建立相應數目的原型并克隆它們可能比每次用合適的狀態手工實例化該類更方便一些。
比如有一個對象,在某一時刻該對象中已經包含了一些有效的值,此時可能會需要一個和該對象完全相同的新對象,并且此后對新對象的任何改動都不會影響到原來對象中的值,也就是說新對象與原來的對象是兩個獨立的對象,但新對象的初始值是由原來的對象確定的。
7、賦值創建對象
1>java中賦值創建對象是可以實現對象的重用的,但是新對象和原對象是同一個引用;如果修改其中的一個對象的值,則另外的一個對象也會發生改變。
2>使用clone方法會返回對象的一個拷貝,這樣一來,如果修改一個對象的值,則另外的對象不會發生改變的。
8、拷貝分為"淺拷貝"和"深拷貝"
淺拷貝: 對值類型的成員變量進行值的復制,對引用類型的成員變量只復制引用,不復制引用的對象。換言之,淺復制僅僅復制所考慮的對象,而不復制它所引用的對象。
深拷貝: 對值類型的成員變量進行值的復制,對引用類型的成員變量也進行引用對象的復制(那些引用其他對象的變量將指向被復制過的新對象,而不再是原有的那些被引用的對象)。換言之,深復制把重復的對象所引用的對象都復制一遍,而這種對被引用到的對象的復制叫做間接復制。
<span style="font-size:14px"></span>
posted on 2014-03-21 13:12 順其自然EVO 閱讀(224) 評論(0) 編輯 收藏 所屬分類: 測試學習專欄