1. 程式人生 > >GOF23設計模式之原型模式之實現

GOF23設計模式之原型模式之實現


/**
 * Sheep類,測試原型模式之淺拷貝
 * 時間:2015年4月1日09:44:29
 */
package com.bjsxt.cn.prototype;
import java.io.Serializable;
import java.util.Date;
public class Sheep implements Cloneable, Serializable {
 private String name;
 private Date date;
 
 public Sheep() {
 }
 
 public Sheep(String name, Date date) {
  super();
  this.name = name;
  this.date = date;
 }
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 public Date getDate() {
  return date;
 }
 public void setDate(Date date) {
  this.date = date;
 }
 
 @Override
 protected Object clone() throws CloneNotSupportedException {//通過這個方法的兩行程式碼實現淺克隆
  Object object = super.clone();
  return object;
 }
 
}
/**
 * Sheep類,測試原型模式之淺拷貝
 * 時間:2015年4月1日09:44:29
 */
package com.bjsxt.cn.prototype;
import java.util.Date;
public class Sheep2 implements Cloneable {
 private String name;
 private Date date;
 
 public Sheep2() {
 }
 
 public Sheep2(String name, Date date) {
  super();
  this.name = name;
  this.date = date;
 }
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 public Date getDate() {
  return date;
 }
 public void setDate(Date date) {
  this.date = date;
 }
 
 @Override
 protected Object clone() throws CloneNotSupportedException {
  Object object = super.clone();
  
  //通過增加的這幾行實現深複製
  Sheep2 sheep = (Sheep2) object;
  sheep.date = (Date) this.date.clone();
  return object;
 }
 
}
/**
 * 測試淺克隆
 * 時間:2015年4月1日09:48:21
 * 程式理解:該小程式測試了圓形模式淺克隆的相關問題。對比程式和執行結果,我們可以看出以下幾點:
 *   1, 在修改之後,確實實現了複製,並且s1和s2的作為物件,所指向的屬性值完全相同
 *   2, s1和s2作為區域性變數,值並不一樣。並且根據列印的結果,它們都屬於Sheep型別
 *   3, s1和s2為Sheep物件,該類具有Date屬性,但是s1和s2的date屬性指向了同樣的記憶體空間。這可以通過
 *    我們修改了date的值以後,s1和s2的屬性date都跟著改變了。顯然,在某些情況下,這不符合我們的要求,因為
 *    s1和s2還有粘連。我們希望它們能彼此獨立。修改一個物件,與另一個物件無關。當然這就是淺拷貝的問題所在了
 *
 */
package com.bjsxt.cn.prototype;
import java.util.Date;
public class Client1 {
 public static void main(String[] args) throws CloneNotSupportedException {
  Date date = new Date(3234324435L);
  Sheep s1 = new Sheep("少莉", date);
  Sheep s2 = (Sheep) s1.clone();
  System.out.println("----------修改之前------------");
  System.out.println(s1.getClass());
  System.out.println(s1);
  System.out.println(s1.getName());
  System.out.println(s1.getDate());
  
  System.out.println(s2.getClass());
  System.out.println(s2);
  System.out.println(s2.getName());
  System.out.println(s2.getDate());
  
  System.out.println("----------修改-----------");
  
  date.setTime(4323423423L);
  System.out.println("----------修改之後-------------");
  
  System.out.println(s1);
  System.out.println(s1.getName());
  System.out.println(s1.getDate());
  
  System.out.println(s2);
  System.out.println(s2.getName());
  System.out.println(s2.getDate());
 }
}
/*
 * ----------修改之前------------
 [email protected]
 少莉
 Sat Feb 07 18:25:24 CST 1970
 [email protected]
 少莉
 Sat Feb 07 18:25:24 CST 1970
 ----------修改-----------
 ----------修改之後-------------
 [email protected]
 少莉
 Fri Feb 20 08:57:03 CST 1970
 [email protected]
 少莉
 Fri Feb 20 08:57:03 CST 1970
 * 
 * */
/**
 * 測試深拷貝
 * 時間:2015年4月1日09:48:21
 * 程式理解:該小程式測試了原型模式深克隆的相關問題。對比程式和執行結果,我們可以看出以下幾點:
 *   通過程式,我們可以看出,在Sheep2類中的clone方法中增加了幾行語句
 *    @Override
 protected Object clone() throws CloneNotSupportedException {
  Object object = super.clone();
  
  //通過增加的這幾行實現深複製
  Sheep2 sheep = (Sheep2) object;
  sheep.date = (Date) this.date.clone();
  return object;
 }
 
 就實現了深拷貝,這是通過我們對屬性也進行了深拷貝實現的。
 */
package com.bjsxt.cn.prototype;
import java.util.Date;
public class Client2 {
 public static void main(String[] args) throws CloneNotSupportedException {
  Date date = new Date(3234324435L);
  String name = new String("少莉");
  Sheep2 s1 = new Sheep2(name, date);
  Sheep2 s2 = (Sheep2) s1.clone();
  System.out.println("----------修改之前------------");
  
  System.out.println("s1-------------");
  System.out.println(s1.getClass());
  System.out.println(s1);
  System.out.println(s1.getName());
  System.out.println(s1.getDate());
  System.out.println();
  
  System.out.println("s2-------------");
  System.out.println(s2.getClass());
  System.out.println(s2);
  System.out.println(s2.getName());
  System.out.println(s2.getDate());
  
  System.out.println("----------修改-----------");
  
  date.setTime(43234234238989L);
  s1.setName("周杰倫");
  System.out.println("----------修改之後-------------");
  System.out.println("s1-------------");
  System.out.println(s1);
  System.out.println(s1.getName());
  System.out.println(s1.getDate());
  System.out.println();
  
  System.out.println("s2-------------");
  System.out.println(s2);
  System.out.println(s2.getName());
  System.out.println(s2.getDate());
 }
}
/*
 ----------修改之前------------
s1-------------
class com.bjsxt.cn.prototype.Sheep2
[email protected]
少莉
Sat Feb 07 18:25:24 CST 1970
s2-------------
class com.bjsxt.cn.prototype.Sheep2
[email protected]
少莉
Sat Feb 07 18:25:24 CST 1970
----------修改-----------
----------修改之後-------------
s1-------------
[email protected]
周杰倫
Fri Jan 15 13:30:38 CST 3340
 * 
 * */
/**
 * 測試使用序列化和反序列化實現深拷貝。
 * 時間:2015年4月1日10:27:57
 * 注意:記住序列化的過程。
 */
package com.bjsxt.cn.prototype;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Date;
public class Client3 {
 public static void main(String[] args) throws IOException, ClassNotFoundException {
  Date date = new Date(3234324435L);
  Sheep s1 = new Sheep("少莉", date);
  
  //把這個物件寫入到記憶體中的陣列。通過使用位元組陣列輸出流baos獲取記憶體中的一塊記憶體
  //外加一個處理流,方便操作,多型的存在,因此必須使用ObjectOutputStream類來宣告。
  ByteArrayOutputStream baos = new ByteArrayOutputStream();
  ObjectOutputStream oos = new ObjectOutputStream(baos);
  oos.writeObject(s1);
  byte[] bytes = baos.toByteArray();
  
  ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
  ObjectInputStream ois = new ObjectInputStream(bais);
  Sheep s2 = (Sheep) ois.readObject();
  
  
 System.out.println("----------修改之前------------");
  
  System.out.println("s1-------------");
  System.out.println(s1.getClass());
  System.out.println(s1);
  System.out.println(s1.getName());
  System.out.println(s1.getDate());
  System.out.println();
  
  System.out.println("s2-------------");
  System.out.println(s2.getClass());
  System.out.println(s2);
  System.out.println(s2.getName());
  System.out.println(s2.getDate());
  
  System.out.println("----------修改-----------");
  
  date.setTime(43234234238989L);
  s1.setName("周杰倫");
  System.out.println("----------修改之後-------------");
  System.out.println("s1-------------");
  System.out.println(s1);
  System.out.println(s1.getName());
  System.out.println(s1.getDate());
  System.out.println();
  
  System.out.println("s2-------------");
  System.out.println(s2);
  System.out.println(s2.getName());
  System.out.println(s2.getDate());
 }
}
/**
 *
 * ----------修改之前------------
s1-------------
class com.bjsxt.cn.prototype.Sheep
[email protected]
少莉
Sat Feb 07 18:25:24 CST 1970
s2-------------
class com.bjsxt.cn.prototype.Sheep
[email protected]
少莉
Sat Feb 07 18:25:24 CST 1970
----------修改-----------
----------修改之後-------------
s1-------------
[email protected]
周杰倫
Fri Jan 15 13:30:38 CST 3340
/**
 * 測試new方法和clone方法的效率比較
 * 通過執行結果我們可以看出,clone極大的提高了建立物件的效率。
 * 
 */
package com.bjsxt.cn.prototype;
import java.util.Date;
public class Client4 {
 public static void testNew(int size) {
  long start = System.currentTimeMillis();
  
  for (int i=0; i<size; i++) {
   Laptop tempLaptop = new Laptop();
  }
  
  long end = System.currentTimeMillis();
  
  System.out.println("New耗時: " + (end-start));
  
 }
 
 public static void testClone(int size) throws CloneNotSupportedException {
  long start = System.currentTimeMillis();
  Laptop t = new Laptop();
  for (int i=0; i<size-1; i++) {
   Laptop temp = (Laptop) t.clone();
  }
  
  long end = System.currentTimeMillis();
  System.out.println("Clone耗時: " + (end-start));
  
 }
 public static void main(String[] args) throws CloneNotSupportedException {
  testNew(1000);
  testClone(1000);
 }
}
class Laptop implements Cloneable{
 public Laptop() {
  try {
   Thread.sleep(10);
  } catch (InterruptedException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
 }
 
 @Override
 protected Object clone() throws CloneNotSupportedException {
    //通過增加的這幾行實現淺複製
   Object object = super.clone();
   return object;
  }
  
}
/*
 * New耗時: 10550
 Clone耗時: 10
 * 
 */

相關推薦

GOF23設計模式原型模式實現

 /**  * Sheep類,測試原型模式之淺拷貝  * 時間:2015年4月1日09:44:29  */ package com.bjsxt.cn.prototype; import java.io.Serializable; import java.util.D

設計模式原型模式(java實現

原型模式(Prototype Pattern):就是從一個物件再建立另一個可定製物件的,而且不需要知道任何建立的細節。所謂原型模式,就是 Java 中的克隆技術,以某個物件為原型。複製出新的物件。顯然新的物件具備原 型物件的特點,效率高(避免了重新執行構造過程步驟)。 所以當直接建立物件代價

設計模式 原型模式(prototype)(C++實現 深拷貝 + 淺拷貝版本[bug])

本文介紹設計模式中的原型模式。 本質上其實就是克隆。 下面以個人簡歷為例進行舉例說明: 深拷貝版本: #include <iostream> #include <string> #include <memory> using n

通過例子學設計模式--原型模式以及使用場景說明(C++實現)

           想必很多人都玩過魔獸爭霸3。裡面有一個非常厲害的英雄叫做劍聖。這個英雄攻擊力算是最高的,而且有個聽起來很叼的魔法,“劍刃風暴”,這個魔法其實效果一般,不大實用。            劍聖有一個分身的功能。這個分身各個方面和劍聖都一模一樣,但是沒有攻擊

GOF23設計模式原型模式與建立型模式總結

 原型模式prototype 原型模式又稱做克隆模式,拷貝模式。實際上是一個記憶體的操作 原型模式 --通過new產生一個物件需要非常繁瑣的資料準備或訪問許可權,則可以使用原型

Head First設計模式原型模式

webkit ble -1 否則 type sof 異常 構圖 etc 用原型實例指定創建對象的種類,並且通過拷貝這些原型創建新的對象。 原型模式是一種比較簡單的模式,也非常容易理解,實現一個接口,重寫一個方法即完成了原型模式。在實際應用中,原型模式很少單獨出現。經常與其

一天學習一個設計模式原型模式

拷貝 pre des prot transient ret 哈哈 his 耗時 原型模式(Prototype),用原型實例指定創建對象的種類,並且通過拷貝這些原型創建新的對象。   原型模式其實就是從一個對象再創建另外一個可定制的對象,而且不需要知道任何創建的細節。例

go設計模式原型模式

tin ros oge soft 高效 errors %d light 相等   原型模式是創建型模式的一種,其特點在於通過“復制”一個已經存在的實例來返回新的實例,而不是新建實例。被復制的實例就是我們所稱的“原型”,這個原型是可定制的。原型模式多用於創建復雜的或者耗時的實

設計模式原型模式

name 原形 ace pre 我們 指定 通過 值類型 常常 原型模式(Prototype Pattern):用原型實例指定創建對象的種類,並且通過復制這些原型創建新的對象。 作用(解決的問題):簡化對象的創建過程。 優點: 1、當創建對象的實例較為復雜的時候,使用原型模

設計模式---對象創建模式原型模式(prototype)

col 具體類 不同 new mark out 初始化 isp clas 一:概念 原型模式(Prototype Pattern) 實際上就是動態抽取當前對象運行時的狀態 Prototype模式是一種對象創建型模式,它采取復制原型對象的方法來創建對象的實例

java設計模式原型模式

ria sets 對象 ace ner 方法 .get chang lose 原型模式:通過原型實例創建新的對象,就不再需要關心這個實例本身的類型,只要實現了克隆自身的方法,就可以通過這個方法來獲取新的對象,而無須再去通過new來創建。 原型模式有以下幾種方式:簡單形式(

Java設計模式(五)建立型模式原型模式

一、定義: 用原型例項指定建立物件的種類,並通過拷貝這些原型建立新的物件。 UML類圖: 原型模式主要用於物件的複製,它的核心是就是類圖中的原型類Prototype。Prototype類需要具備以下兩個條件: (1)實現Cloneable介面:在java語言有一個Cloneab

Java設計模式 原型模式

Java設計模式 - 原型模式   原型模式應用場景: 原型模式是指用原型例項指定建立物件的種類,並且通過複製這些原型建立新的物件.適合原型模式的情景如下:程式需要從一個物件出發,得到i若干個和其狀態相同,並可獨立變化其狀態的物件時;物件建立需要獨立於它的構造方法和表示時,以原

趣味設計模式原型模式

    有一天,八戒問悟空,“大師兄,你怎麼可以拔一搓猴毛就可以生成無數個一摸一樣的你,怎麼那麼神奇?師兄既然是齊天大聖,我老豬有個問題向請教下,在程式設計的世界中,我怎麼可以實現呢?我想在下次的時候也玩一把,這樣我就可以躺著吃喝,不用幹活了,哈哈”   &nb

淺談設計模式原型模式

背景知識: 我們常說的設計模式其實是一種程式碼規範,遵從設計模式所編寫的程式碼並不是最高效的,但是是可維護的。 設計模式主要有三類:建立型設計模式,結構型設計模式以及行為型設計模式。 設計模式遵循的幾個原則:開閉原則,里氏代換原則,依賴倒轉原則,單一職責原則,合成複用原則,介面

設計模式原型模式(十三)

原型模式是設計模式中算是簡單的一種設計模式了,因為它有語言實現的支撐,只需要呼叫定義好了的方法即可使用,在寫這篇設計模式之前,我看過很多資料,有幾點比較疑惑的點,在這篇文章中驗證,也順便描述一下什麼是原型模式。  定義:用原型例項指定建立物件的種類,並且通過拷貝這些原型建立新的物件。

java設計模式(建立型模式)原型模式prototype

原型模式: 通過產生一個物件需要非常複雜的資料準備或訪問許可權.則可以使用原型模式 java中的克隆技術,以某個物件為原型,複製出新的物件, 優勢:效率高(直接克隆,避免了重複執行構造過程) 克隆類似於new,但是不同於new.new建

java設計模式——建造者模式原型模式(建立性)【讀書筆記】

一、建造者模式(生成器模式)                 定義:將一個複雜物件的構建和它的表示分離開,使得同樣的構建過程可以得到不同的表示。                 效果:採用建造者模式,使用者只需要選擇建造的型別就可以得到它們,而具體的建造過程和細節就不需要

四、Python 設計模式原型模式

原型模式的目的是克隆物件 或者 副本 類似於淺拷貝和深拷貝 淺拷貝就是 副本依賴引用 深拷貝就是 完全克隆一份 以下是簡單的例子 import copy class A: def __init__(self): self.x = 18

建立型設計模式原型模式

原型模式的介紹 原型二字代表該模式應該有一個樣板例項,使用者從這個樣板中複製出一個內部屬性一致的物件,這個過程也就是我們俗稱的“克隆”。被複制的例項就是我們所稱的“原型”。原型模式多用於建立複雜的或者構造耗時的例項,因為這種情況下,複製一個已經存在的例項可以使程式執行更高效