建造者模式與原型模式
阿新 • • 發佈:2018-11-10
建造者模式與原型模式
一、建造者模式
- 建造者模式概述
- 建造者模式分離了物件子元件。子元件單獨構造(由Builder來負責)然後再裝配(由Director負責)。 從而可以構 造出複雜的物件。這個模式適用於:某個物件的構建過程複雜的情況下使用。
- 由於實現了構建和裝配的解耦。不同的構建器,相同的裝配,也可以做出不同的物件; 相同的構建器,不同的裝配順序也可以做出不同的物件。也就是實現了構建演算法、裝配 演算法的解耦,實現了更好的複用。
- 以建造宇宙飛船為例:
public class AirShip { //要建造的宇宙飛船類,三個元件由不同的builder分別構建,然後裝配 private OrbitalModule orbitalModule; //軌道艙 private Engine engine; //發動機 private EscapeTower escapeTower; //逃逸塔 public void launch(){ System.out.println("發射!"); } 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; } } 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 String getName() { return name; } public void setName(String name) { this.name = name; } public EscapeTower(String name) { super(); this.name = name; } } ---------------------------------------------------------------- public interface AirShipBuilder { //Builder的介面 Engine builderEngine(); OrbitalModule builderOrbitalModule(); EscapeTower builderEscapeTower(); } public class AirShipBuilderImpl implements AirShipBuilder { //Builder的實現類,構建飛船的各個元件 @Override public Engine builderEngine() { System.out.println("構建發動機!"); return new Engine("發動機!"); } @Override public EscapeTower builderEscapeTower() { System.out.println("構建逃逸塔"); return new EscapeTower("逃逸塔"); } @Override public OrbitalModule builderOrbitalModule() { System.out.println("構建軌道艙"); return new OrbitalModule("軌道艙"); } } ------------------------------------------------------------------------ public interface AirShipDirector { /** * 組裝飛船物件的介面 * @return */ AirShip directAirShip(); } public class AirshipDirectorImpl implements AirShipDirector { //組裝飛船物件的實現類 private AirShipBuilder builder; public tAirshipDirectorImpl(AirShipBuilder builder) { this.builder = builder; } @Override public AirShip directAirShip() { Engine e = builder.builderEngine(); OrbitalModule o = builder.builderOrbitalModule(); EscapeTower et = builder.builderEscapeTower(); //裝配成飛船物件 AirShip ship = new AirShip(); ship.setEngine(e); ship.setEscapeTower(et); ship.setOrbitalModule(o); return ship; } } ------------------------------------------------------ public class Client { public static void main(String[] args) { //組裝 AirShipDirector director = new AirshipDirectorImpl(new AirShipBuilderImpl()); AirShip ship = director.directAirShip(); System.out.println(ship.getEngine().getName()); ship.launch(); } }
二、原型模式prototype
- 原型模式概述
- 通過new產生一個物件需要非常繁瑣的資料準備或訪問許可權,則可以使用原型模式。
- 就是java中的克隆技術,以某個物件為原型,複製出新的物件。顯然,新的物件具備原型物件的特點
- 優勢有:效率高(直接克隆,避免了重新執行構造過程步驟) 。
- 克隆類似於new,但是不同於new。new建立新的物件屬性採用的是預設值。克隆出的 物件的屬性值完全和原型物件相同。並且克隆出的新物件改變不會影響原型物件。然後, 再修改克隆物件的值。
- 淺克隆與深克隆
- 淺克隆:被複制的物件的所有變數都含有與原來的物件相同的值,而所有的對其他物件的引用都 仍然指向原來的物件。
- 深克隆:深克隆把引用的變數指向複製過的新物件,而不是原有的被引用的物件。 基本資料型別和String能夠自動實現深度克隆(值的複製)
- 以克隆羊為例
public class Sheep2 implements Cloneable { private String sname; private Date birthday; @Override protected Object clone() throws CloneNotSupportedException { Object obj = super.clone(); //直接呼叫object物件的clone()方法! //新增如下程式碼實現深複製(deep Clone) Sheep2 s = (Sheep2) obj; s.birthday = (Date) this.birthday.clone(); //把屬性也進行克隆! return obj; } public String getSname() { return sname; } public void setSname(String sname) { this.sname = sname; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } public Sheep2(String sname, Date birthday) { super(); this.sname = sname; this.birthday = birthday; } public Sheep2() { } } public class Client2 { public static void main(String[] args) throws CloneNotSupportedException { Date date = new Date(12312321331L); Sheep2 s1 = new Sheep2("少利",date); //實現複製。是否是深複製取決於Sheep2 Sheep2 s2 = (Sheep2) s1.clone(); } }
- 用序列化與反序列化實現深克隆
public class Client3 {
public static void main(String[] args) throws CloneNotSupportedException, Exception {
Date date = new Date(12312321331L);
Sheep s1 = new Sheep("多利",date);
// 使用序列化和反序列化實現深複製
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(s1);
byte[] bytes = bos.toByteArray();
ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
ObjectInputStream ois = new ObjectInputStream(bis);
Sheep s2 = (Sheep) ois.readObject(); //克隆好的物件!
}
}
三、建立型模式總結
- 單例模式
保證一個類只有一個例項,並且提供一個訪問該例項的全域性訪問點。 - 簡單工廠模式
用來生產同一等級結構中的任意產品。(對於增加新的產品,需要修改已有程式碼) - 工廠方法模式
用來生產同一等級結構中的固定產品。(支援增加任意產品) - 抽象工廠模式
用來生產不同產品族的全部產品。(對於增加新的產品,無能為力;支援增加產品族) - 原型模式
通過new產生一個物件需要非常繁瑣的資料準備或訪問許可權,則可以使用原型模式