原型模式屬於對象的建立模式。經過給出一個原型對象來指明全部建立的對象的類型,而後用這個原型對象提供的複製辦法建立出更多同類型的對象。java
原型模式要求對象實現一個能夠克隆自身的接口(類型)。這樣一來,經過原型實例建立新的對象,就不須要關心這個實例自己的類型,只須要實現克隆自身的方法,也而無需再去經過new
來建立。編程
Java
接口或者Java
抽象類實現。此角色定義了的具體原型類所需的實現的方法。Prototype.java後端
/** * 抽象原型角色 */
public abstract class Prototype {
private String id;
public Prototype(String id) {
this.id = id;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
/** * 克隆自身的方法 * @return 一個從自身克隆出來的對象。 */
public abstract Prototype clone();
}
複製代碼
ConcretePrototype1.java緩存
public class ConcretePrototype1 extends Prototype {
public ConcretePrototype1(String id) {
super(id);
}
public Prototype clone() {
Prototype prototype = new ConcretePrototype1(this.getId());
return prototype;
}
}
複製代碼
ConcretePrototype2.java多線程
public class ConcretePrototype2 extends Prototype {
public ConcretePrototype2(String id) {
super(id);
}
public Prototype clone() {
Prototype prototype = new ConcretePrototype2(this.getId());
return prototype;
}
}
複製代碼
Java
接口或者Java
抽象類實現。此角色定義了的具體原型類所需的實現的方法。除了原型管理器Prototype Manager
之外,登記模式和簡單模式並沒有其餘差別。架構
Prototype.java W框架
public interface Prototype {
public Prototype clone();
public String getName();
public void setName(String name);
}
複製代碼
ConcretePrototype1.java異步
public class ConcretePrototype1 implements Prototype {
private String name;
@Override
public String getName() {
return this.name;
}
@Override
public void setName(String name) {
this.name = name;
}
@Override
public Prototype clone() {
Prototype prototype = new ConcretePrototype1();
prototype.setName(this.name);
return prototype;
}
@Override
public String toString() {
return "ConcretePrototype1 [name=" + name + "]";
}
}
複製代碼
ConcretePrototype2.java分佈式
public class ConcretePrototype2 implements Prototype {
private String name;
@Override
public String getName() {
return this.name;
}
@Override
public void setName(String name) {
this.name = name;
}
@Override
public Prototype clone() {
Prototype prototype = new ConcretePrototype2();
prototype.setName(this.name);
return prototype;
}
@Override
public String toString() {
return "ConcretePrototype2 [name=" + name + "]";
}
}
複製代碼
PrototypeManager.javaide
public class PrototypeManager {
/** * 用來記錄原型的編號同原型實例的對象關係 */
private static Map<String, Prototype> map = new HashMap<>();
/** * 私有化構造方法,避免從外部建立實例 */
private PrototypeManager() {
}
/** * 向原型管理器裏面添加或者修改原型實例 * * @param prototypeId 原型編號 * @param prototype 原型實例 */
public static void setProtoType(String prototypeId, Prototype prototype) {
map.put(prototypeId, prototype);
}
/** * 根據原型編號從原型管理器裏面移除原型實例 * * @param prototypeId 原型編號 */
public static void removePrototype(String prototypeId) {
map.remove(prototypeId);
}
/** * 根據原型編號獲取原型實例 * * @param prototypeId 原型編號 * @return 原型實例對象 * @throws Exception 若是根據原型編號沒法獲取對應實例,則提示異常「您但願獲取的原型尚未註冊或已被銷燬」 */
public static Prototype getPrototype(String prototypeId) throws Exception {
Prototype prototype = map.get(prototypeId);
if (prototype == null) {
throw new Exception("您但願獲取的原型尚未註冊或已被銷燬");
}
return prototype;
}
}
複製代碼
Client.java
public class Client {
public static void main(String[] args) {
try {
// 建立第一個實例
Prototype p1 = new ConcretePrototype1();
// 註冊第一個實例
PrototypeManager.setProtoType("p1", p1);
// 克隆第一個實例的原型
Prototype p3 = PrototypeManager.getPrototype("p1").clone();
p3.setName("張三");
System.out.println("第一個實例的副本:" + p3);
// 建立第二個實例
Prototype p2 = new ConcretePrototype2();
// 註冊第二個實例
PrototypeManager.setProtoType("p2", p2);
// 克隆第二個實例的原型
Prototype p4 = PrototypeManager.getPrototype("p2").clone();
p4.setName("李四");
System.out.println("第二個實例的副本:" + p4);
// 註銷第一個實例
PrototypeManager.removePrototype("p1");
// 再次克隆第一個實例的原型
Prototype p5 = PrototypeManager.getPrototype("p1").clone();
p5.setName("王五");
System.out.println("第一個實例的副本:" + p5);
} catch (Exception e) {
e.printStackTrace();
}
}
}
複製代碼
簡單形式和登記形式的原型模式各有其長處和短處。
原型模式容許在運行時動態改變具體的實現類型。原型模式能夠在運行期間,有客戶來註冊符合原型接口的實現類型,也能夠動態的改變具體的實現類型,看起來接口沒有任何變化,可是其實運行的已是另一個類實體了。由於克隆一個原型對象就相似於實例化一個類。
原型模式最主要的缺點是每個類都必需要配備一個克隆方法。配備克隆方法須要對類的功能進行通盤考慮,這對於全新的類來講並非很難,可是對於已有的類來講並不容易。
歡迎關注技術公衆號: 零壹技術棧
本賬號將持續分享後端技術乾貨,包括虛擬機基礎,多線程編程,高性能框架,異步、緩存和消息中間件,分佈式和微服務,架構學習和進階等學習資料和文章。