[19/04/24-星期三] GOF23_创建型模式(建造者模式、原型模式)
一、建造者模式
本質(zhì):分離了對(duì)象子組件的單獨(dú)構(gòu)造(由Builder負(fù)責(zé))和裝配的分離(由Director負(fù)責(zé)),從而可以構(gòu)建出復(fù)雜的對(duì)象,這個(gè)模式適用于:某個(gè)對(duì)象的構(gòu)建過(guò)程十分復(fù)雜
好處:由于構(gòu)建和裝配的解耦,不同的構(gòu)建器和相同的裝配可以做出不同的對(duì)象,相同的構(gòu)建器和不同裝配順序也可以組成不同的對(duì)象,實(shí)現(xiàn)了構(gòu)建算法和裝配算法的解耦,
實(shí)現(xiàn)了更好的復(fù)用。
【基本模塊】
/**** "宇宙飛船"類*/ package cn.sxt.builder;public class Airship {private OrbitalModule orbitalModule;//軌道倉(cāng)模塊private Engine engine;//發(fā)動(dòng)機(jī)模塊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()+"點(diǎn)火,5,4,3,2,1,發(fā)射!");} }class OrbitalModule{//"軌道倉(cāng)"類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{//"發(fā)動(dòng)機(jī)"類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;} }?
【建造者和裝配者】接口
/**** "建造類"接口,提供構(gòu)建3個(gè)子類的方法*/ package cn.sxt.builder;public interface AirshipBuilder {OrbitalModule builderOrbitalModule();cn.sxt.builder.Engine builderEngine();EscapeTower builderEscapeTower(); }/**** "裝配類"接口, Director:導(dǎo)演,負(fù)責(zé)人*/ package cn.sxt.builder;public interface AirShipDirector {Airship directorAirship();//組裝飛船對(duì)象 }【建造者和裝配者】具體實(shí)現(xiàn)類
/**** "神7飛船"子組件的建造者*/ package cn.sxt.builder;public class S7AirShipBuilder implements AirshipBuilder { //XML解析中,JDOM庫(kù)中的類:DOMBuilder也是建造者模式public OrbitalModule builderOrbitalModule() { System.out.println("--制造天宮牌軌道倉(cāng)--");return new OrbitalModule("天宮牌軌道倉(cāng) ");}public Engine builderEngine() {System.out.println("--制造盤(pán)古牌發(fā)動(dòng)機(jī)--");return new Engine("盤(pán)古牌發(fā)動(dòng)機(jī) "); }public EscapeTower builderEscapeTower() {System.out.println("--制造曹操牌逃逸塔--");return new EscapeTower("曹操牌逃逸塔");}} /**** "神7飛船"裝配者*/ package cn.sxt.builder;public class S7AirShipDirector implements AirShipDirector{private AirshipBuilder builder;//要裝配的對(duì)象,要裝配什么組件public S7AirShipDirector(AirshipBuilder builder) {this.builder = builder;}public Airship directorAirship() {OrbitalModule oModule=builder.builderOrbitalModule();Engine engine=builder.builderEngine();EscapeTower eTower=builder.builderEscapeTower();//獲得各個(gè)組件 Airship ship=new Airship();//一個(gè)具體的飛船對(duì)象 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:原型、雛形)
? ? 通過(guò)new產(chǎn)生一個(gè)對(duì)象需要非常繁瑣的數(shù)據(jù)準(zhǔn)備或者訪問(wèn)權(quán)限,則可以使用原型模式。JavaScript中的繼承中使用過(guò)。
? ? 就是Java中的克隆技術(shù),以某個(gè)對(duì)象為原型。new創(chuàng)建新的對(duì)象采用默認(rèn)值。克隆出的對(duì)象的屬性值完全和原型相同,并且克隆出的新對(duì)象改變不會(huì)影響原型對(duì)象。
然后,再修改克隆對(duì)象的值。
?實(shí)現(xiàn):通過(guò)Cloneable接口和clone方法,幫我們進(jìn)行內(nèi)存的復(fù)制操作。常常與工廠模式結(jié)合起來(lái)
用途:如果短時(shí)間需要?jiǎng)?chuàng)建大量對(duì)象,并且new的時(shí)候比較耗時(shí)間,可以用原型模式,效率大概是普通方法的100倍
【原型羊】
/**** 原型"羊"類*/ package cn.sxt.prototype; import java.util.Date;public class Sheep implements Cloneable {private String name;private Date birthday;@Override //重寫(xiě)父類中的clone方法protected Object clone() throws CloneNotSupportedException {Object obj=super.clone();//直接調(diào)用Object類對(duì)象的clone方法/* //添加如下代碼2行實(shí)現(xiàn)深克隆Sheep s=(Sheep)obj;s.birthday=(Date)this.birthday.clone();//把屬性(出生日期)也進(jìn)行克隆 */ 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;}}【克隆羊】
/*** 測(cè)試取克隆一只"羊"(淺克隆和深克隆)*/ 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();//新建一個(gè)對(duì)象,但不是通過(guò)new,而是直接調(diào)用原型"羊"的clone方法System.out.println(s2);//輸出結(jié)果顯示s1與s2對(duì)象在內(nèi)存中的值不同,但是屬性信息等一模一樣 System.out.println(s2.getName());System.out.println(s2.getBirthday());s2.setName("羊二代");//修改s2的屬性值,完全不影響s1的值 System.out.println(s2.getName());//修改原型"羊"的出生日期,看看克隆羊的出生日期/** 淺克隆:把原型羊的出生日期改了,但是影響克隆羊的出生日期* 深克隆:把原型羊的出生日期改了,但是不影響克隆羊的出生日期* 原理:* 淺克隆:s1----->data對(duì)象<-----s2(s1和s2的出生日期均執(zhí)行同一時(shí)間對(duì)象data,s1一改動(dòng),s2也受影響)* 深克隆:s1----->data對(duì)象。data對(duì)象的復(fù)制品<-----s2,s1改動(dòng)與s2沒(méi)有關(guān)系,s2的出生日期不會(huì)動(dòng)* */date.setTime(40000000L);System.out.println(s1.getBirthday());System.out.println(s2.getBirthday());} }?【深克隆方式之二】
/**** 用序列化和反序列化實(shí)現(xiàn)深克隆*/ 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();//新建一個(gè)對(duì)象,但不是通過(guò)new,而是直接調(diào)用原型"羊"的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());}}?
轉(zhuǎn)載于:https://www.cnblogs.com/ID-qingxin/p/10749672.html
總結(jié)
以上是生活随笔為你收集整理的[19/04/24-星期三] GOF23_创建型模式(建造者模式、原型模式)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: [19/04/23-星期二] GOF23
- 下一篇: P3865 【模板】ST表