[19/04/24-星期三] GOF23_創建型模式(建造者模式、原型模式)

一、建造者模式

本質:分離了對象子組件的單獨構造(由Builder負責)和裝配的分離(由Director負責),從而可以構建出復雜的對象,這個模式適用于:某個對象的構建過程十分復雜

好處:由于構建和裝配的解耦,不同的構建器和相同的裝配可以做出不同的對象,相同的構建器和不同裝配順序也可以組成不同的對象,實現了構建算法和裝配算法的解耦,

實現了更好的復用。

【基本模塊】

/**** "宇宙飛船"類*/
package cn.sxt.builder;public class Airship {private OrbitalModule orbitalModule;//軌道倉模塊private Engine engine;//發動機模塊private EscapeTower escapeTower;//逃逸塔模塊public OrbitalModule getOrbitalModule() {return orbitalModule;}public void setOrbitalModule(OrbitalModule orbitalModule) {this.orbitalModule = orbitalModule;}public Engine getEngine() {return engine;}public void setEngine(Engine engine) {this.engine = engine;}public EscapeTower getEscapeTower() {return escapeTower;}public void setEscapeTower(EscapeTower escapeTower) {this.escapeTower = escapeTower;}public String toString() {String msg="配置:["+orbitalModule.getName()+engine.getName()+escapeTower.getName()+"]";return msg;}public void launch() {System.out.println(engine.getName()+"點火,5,4,3,2,1,發射!");}
}class OrbitalModule{//"軌道倉"類private String name;public OrbitalModule(String name) {this.name=name;}public String getName() {return name;}public void setName(String name) {this.name = name;}
}class Engine{//"發動機"類private String name;public Engine(String name) {this.name=name;}public String getName() {return name;}public void setName(String name) {this.name = name;}
}class EscapeTower{//"逃逸塔"類private String name;public EscapeTower(String name) {this.name = name;}public String getName() {return name;}public void setName(String name) {this.name = name;}    
}

?

【建造者和裝配者】接口

/**** "建造類"接口,提供構建3個子類的方法*/
package cn.sxt.builder;public interface AirshipBuilder {OrbitalModule builderOrbitalModule();cn.sxt.builder.Engine builderEngine();EscapeTower builderEscapeTower();
}/**** "裝配類"接口, Director:導演,負責人*/
package cn.sxt.builder;public interface AirShipDirector {Airship directorAirship();//組裝飛船對象

}

【建造者和裝配者】具體實現類

/**** "神7飛船"子組件的建造者*/
package cn.sxt.builder;public class S7AirShipBuilder implements AirshipBuilder { //XML解析中,JDOM庫中的類:DOMBuilder也是建造者模式public OrbitalModule builderOrbitalModule() {    System.out.println("--制造天宮牌軌道倉--");return new OrbitalModule("天宮牌軌道倉 ");}public Engine  builderEngine() {System.out.println("--制造盤古牌發動機--");return new Engine("盤古牌發動機 ");    }public EscapeTower builderEscapeTower() {System.out.println("--制造曹操牌逃逸塔--");return new EscapeTower("曹操牌逃逸塔");}}
/**** "神7飛船"裝配者*/
package cn.sxt.builder;public class S7AirShipDirector implements AirShipDirector{private AirshipBuilder builder;//要裝配的對象,要裝配什么組件public S7AirShipDirector(AirshipBuilder builder) {this.builder = builder;}public Airship directorAirship() {OrbitalModule oModule=builder.builderOrbitalModule();Engine engine=builder.builderEngine();EscapeTower eTower=builder.builderEscapeTower();//獲得各個組件
        Airship ship=new Airship();//一個具體的飛船對象
        ship.setOrbitalModule(oModule);ship.setEngine(engine);ship.setEscapeTower(eTower);return ship;}}

【客戶端】

/**** 客戶端*/
package cn.sxt.builder;public class Test_0424_Client {public static void main(String[] args) {AirshipBuilder builder=new S7AirShipBuilder();//飛船建造者AirShipDirector director=new S7AirShipDirector(builder);//飛船裝配者
        Airship s7ship=director.directorAirship();System.out.println(s7ship);s7ship.launch();}}

?

二、原型模式(克隆模式、原型模式。prototype:原型、雛形)

? ? 通過new產生一個對象需要非常繁瑣的數據準備或者訪問權限,則可以使用原型模式。JavaScript中的繼承中使用過。

? ? 就是Java中的克隆技術,以某個對象為原型。new創建新的對象采用默認值。克隆出的對象的屬性值完全和原型相同,并且克隆出的新對象改變不會影響原型對象。

然后,再修改克隆對象的值。

?實現:通過Cloneable接口和clone方法,幫我們進行內存的復制操作。常常與工廠模式結合起來

用途:如果短時間需要創建大量對象,并且new的時候比較耗時間,可以用原型模式,效率大概是普通方法的100倍

【原型羊】

/**** 原型"羊"類*/
package cn.sxt.prototype;
import java.util.Date;public class Sheep implements Cloneable {private String name;private Date birthday;@Override //重寫父類中的clone方法protected Object clone() throws CloneNotSupportedException {Object obj=super.clone();//直接調用Object類對象的clone方法/*    //添加如下代碼2行實現深克隆Sheep s=(Sheep)obj;s.birthday=(Date)this.birthday.clone();//把屬性(出生日期)也進行克隆
*/        return obj;}public Sheep() {super();}public Sheep(String name, Date birthday) {super();this.name = name;this.birthday = birthday;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Date getBirthday() {return birthday;}public void setBirthday(Date birthday) {this.birthday = birthday;}}

【克隆羊】

/*** 測試取克隆一只"羊"(淺克隆和深克隆)*/
package cn.sxt.prototype;import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;public class Test_0424_Client01 {public static void main(String[] args) throws Exception {Date date=new Date(1000000L);Sheep s1=new Sheep("羊一代",date);//要克隆出新羊,需要原型"羊",這就是原型"羊"
        System.out.println(s1);System.out.println(s1.getName());System.out.println(s1.getBirthday());Sheep s2=(Sheep)s1.clone();//新建一個對象,但不是通過new,而是直接調用原型"羊"的clone方法System.out.println(s2);//輸出結果顯示s1與s2對象在內存中的值不同,但是屬性信息等一模一樣
        System.out.println(s2.getName());System.out.println(s2.getBirthday());s2.setName("羊二代");//修改s2的屬性值,完全不影響s1的值
        System.out.println(s2.getName());//修改原型"羊"的出生日期,看看克隆羊的出生日期/**    淺克隆:把原型羊的出生日期改了,但是影響克隆羊的出生日期*  深克隆:把原型羊的出生日期改了,但是不影響克隆羊的出生日期* 原理:* 淺克隆:s1----->data對象<-----s2(s1和s2的出生日期均執行同一時間對象data,s1一改動,s2也受影響)* 深克隆:s1----->data對象。data對象的復制品<-----s2,s1改動與s2沒有關系,s2的出生日期不會動* */date.setTime(40000000L);System.out.println(s1.getBirthday());System.out.println(s2.getBirthday());}
}

?【深克隆方式之二】

/**** 用序列化和反序列化實現深克隆*/
package cn.sxt.prototype;import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Date;public class Test_0424_Client02 {public static void main(String[] args) throws Exception {Date date=new Date(1000000L);Sheep s1=new Sheep("羊一代",date);//要克隆出新羊,需要原型"羊",這就是原型"羊"
        System.out.println(s1);System.out.println("原型羊:"+s1.getBirthday());//Sheep s2=(Sheep)s1.clone();//新建一個對象,但不是通過new,而是直接調用原型"羊"的clone方法//深克隆方法之二:使用序列化和反序列化克隆一只羊ByteArrayOutputStream bos=new ByteArrayOutputStream();ObjectOutputStream oos=new ObjectOutputStream(bos);oos.writeObject(s1);byte[] buf=bos.toByteArray();ByteArrayInputStream bis=new ByteArrayInputStream(buf);ObjectInputStream ois=new ObjectInputStream(bis);Sheep s2=(Sheep)ois.readObject();System.out.println(s2);System.out.println("克隆羊:"+s2.getBirthday());//修改原型"羊"的出生日期,看看克隆羊的出生日期date.setTime(40000000L);System.out.println("修改原型羊的出生日期后:");System.out.println("原型羊:"+s1.getBirthday());System.out.println("克隆羊:"+s2.getBirthday());}}

?

轉載于:https://www.cnblogs.com/ID-qingxin/p/10749672.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/249091.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/249091.shtml
英文地址,請注明出處:http://en.pswp.cn/news/249091.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

深入理解vue中的slot與slot-scope

寫在前面 vue中關于插槽的文檔說明很短&#xff0c;語言又寫的很凝練&#xff0c;再加上其和methods&#xff0c;data&#xff0c;computed等常用選項在使用頻率、使用先后上的差別&#xff0c;這就有可能造成初次接觸插槽的開發者容易產生“算了吧&#xff0c;回頭再學&#…

js 轉義

1. JavaScript 特殊字符 2. 正反斜杠互相替換 a/b/c.replace(/\//g,\\) // "a\b\c" $0.value.replace(/\\/g,\/) // a/b/c 獲取到 而不提取出 某個值后進行直接處理 \ 有轉義功能&#xff0c;所以一旦解析必然轉義&#xff0c;通常是直接獲取到數據源…

關于Java抽象類,接口與實現接口及派生類繼承基類

1. 抽象類 抽象類就是有一個或多個方法只被聲明而未被實現。 抽象方法的聲明以分號結束&#xff0c;并且用關鍵字abstract來說明它以標識它為抽象方法。 格式&#xff1a; public abstract class 類名{ 定義變量// 抽象方法// } 2. 接口是抽象類的一種&#xff0c;之包含常量…

ie兼容響應式布局的實現總結

雖然說響應式設計的理想狀態是&#xff0c;需對pc/移動各種終端進行響應&#xff1b;但是現實是高分辨率的pc端與手機終端屏幕相差太大&#xff0c;像電商這樣有大量圖片和文字 信息的同時排版要求精準的頁面&#xff0c;設計一個同時適應高分辨率pc又適合小尺寸的手機終端是挑…

Luogu P1471 方差

題目傳送門 開了十倍空間才過是什么鬼&#xff1f;該不會我線段樹炸了吧……細思極恐 平均數都會求&#xff0c;維護區間和&#xff0c;到時候除一下就好了。 方差的求法如下(用的Luogu的圖片) 因為要維護一個平方&#xff0c;我們可以考慮使用van♂完全平方公式將它拆開&#…

python學習day17 遞歸函數

遞歸函數 http://www.cnblogs.com/Eva-J/articles/7205734.html def age(n):if n 4:return 40elif n >0 and n < 4:return age(n1) 2print(age(1)) # 46 只要寫遞歸函數&#xff0c;必須要有結束條件。 二分法查找 l [2,3,5,10,15,16,18,22,26,30,32,35,41,42,43,55,5…

2018年最好用的20個Bootstrap網站模板

Bootstrap是目前最受歡迎也是最簡潔的建站方式之一&#xff0c;尤其是伴隨移動端的發展&#xff0c;響應式設計已經毫無疑問成為了網頁設計的趨勢&#xff0c;網站建設要求兼容手機端已經是一種剛需&#xff0c;也成為提升用戶體驗的一種必要方式。但這無疑會加大設計師和前端人…

bit、byte、位、字節、漢字、字符之間的區別

package com.suypower.chengyu.test; public class ByteTest { /** * byte 8 bits -128 - 127 * 1 bit 1 二進制數據 * 1 byte 8 bit * 1 字母 1 byte 8 bit(位) * 1 漢字 2 byte 16 bit */ public static void main(String[] args) { // TODO Auto-generated method st…

Android SDK 2.3/3.0/4.0/4.2 下載與安裝教程

Eclipse下搭建Android開發環境教程&#xff1a;http://dev.son1c.com/show/1253.html Google已經發布了Android SDK 4.2版本.下面給朋友們介紹一下安裝 Android 模擬器 Emulator模擬器的方法: 1、首先確定安裝了Java JDK&#xff0c;如果沒有&#xff0c;可以去http://www.ora…

PMP:4.項目整合管理

內容中包含 base64string 圖片造成字符過多&#xff0c;拒絕顯示轉載于:https://www.cnblogs.com/mapanguan/p/9916902.html

瀏覽器渲染原理與過程

一、瀏覽器如何渲染網頁 要了解瀏覽器渲染頁面的過程&#xff0c;首先得知道一個名詞——關鍵路徑渲染。關鍵渲染路徑&#xff08;Critical Rendering Path&#xff09;是指與當前用戶操作有關的內容。例如用戶在瀏覽器中打開一個頁面&#xff0c;其中頁面所顯示的東西就是當前…

css框架:五大css流行框架的總結-css教程-PHP中文網

本篇文章給大家帶來的內容是關于css框架&#xff1a;五大css流行框架的總結&#xff0c;有一定的參考價值&#xff0c;有需要的朋友可以參考一下&#xff0c;希望對你有所幫助。 如今&#xff0c;CSS框架越來越受歡迎&#xff0c;可以說已經應用到每一個網站上了。作為開發工具…

第十四天

###數組&#xff1a;面向對象的方式創建&#xff1a;var arr01 new Array(1,2,3,"abc");直接創建&#xff1a;var arr02 [1,2,3,"abc"]alert (arr02.length);alert(arr02[3]);var arr03 [[1,2,3],["a","b","c","d&q…

【English Email】CIP payouts now in Workday

simplification簡化的[?s?mpl?f??ke??n] quota配額[?kwo?t?] regional區域的[?ri?d??nl] mechanics技工[m??kn?ks] annual年度的 [?nju?l] mid-year年中 [m?d j?r] bridge橋接[br?d?] Incentive激勵 [?n?sent?v] Due to the simplification of …

爬取網頁的通用代碼框架

import requests def getHTMLText(url)try:r requests.get(url,timeout30)r.raise_for_status()r.encoding r.apparent_encodingreturn r.textexcept:return "產生異常"if__name__ "__main__"url "http://www.baidu.com"print(getHTMLText(ur…

深入理解CSS盒模型 - 程序猿的程 - 博客園

深入理解CSS盒模型 本文是學習中傳思客在慕課網開的課程《前端跳槽面試必備技巧》的學習筆記。課程地址&#xff1a;https://coding.imooc.com/class/evaluation/129.html#Anchor。 如果你在面試的時候面試官讓你談談對盒模型的理解&#xff0c;你是不是不知從何談起。這種看似…

藍橋杯——機器人行走

某少年宮引進了一批機器人小車。可以接受預先輸入的指令&#xff0c;按指令行動。小車的基本動作很簡單&#xff0c;只有3種&#xff1a;左轉&#xff08;記為L&#xff09;&#xff0c;右轉&#xff08;記為R&#xff09;&#xff0c;向前走若干厘米&#xff08;直接記數字&am…

JavaWeb:腳本標識

腳本標識 一、JSP表達式 1、介紹 用于向頁面中輸出信息 2、語法格式 <% 表達式%>3、注意 在"<%"和""之間不允許有空格&#xff0c;但是在""后面的表達式之間可以有空格不僅可以插入到網頁中&#xff0c;還可以插入到HTML標記中&#xf…

線程死鎖問題

1 package com.demo.bingfa;2 3 /**4 * java并發編程中&#xff0c;死鎖的概念5 *6 * 我們啟用了兩個線程&#xff0c;分別搶占2個資源&#xff0c;但這兩個資源又分別被不同的對象&#xff08;字符串&#xff09;鎖住了。7 * 當第一個線程調用 resource1 方法&#xff0c;…

CSS的4個簡寫

CSS的4個簡寫 2010-12-13 18:50 聶微東 閱讀(1547) 評論(3) 編輯 收藏 1.background 簡寫屬性在一個聲明中設置所有的背景屬性: background-colorbackground-imagebackground-repeatbackground-attachmentbackground-position 例如: background: #444444 url(image.png…