Author:Gorit
Date:2021/1/13
Refer:《图解设计模式》
2021年发表博文: 15/50
在 java 中,我们可以通过 new 关键字来生成实例。我们通常这样生成的实例都是要指定类名的。
但是有时候,我们在开放的过程中,也有不指定类名来生成实例的需求。
在以下情况中,我们不能根据类来生成实例,而要根据已有的实例来生成新的实例。
不根据类来生成实例,而是根据实例来生成实例的设计模式叫 Prototype 模式
Prototype 有原型,**模型 **的意思。在设计模式中,它是根据实例原型,实例模型来生成新的实例。
现在来回答标题提出的问题:
我们可以通过 clone 创建出实例的副本。我们还会用刀拍 clone 方法与 Cloneable 接口的使用方法。
我们要实现的程序功能是:将字符串放入方框,显示出来 或者 加上下划线显示出来
包 | 名字 | 说明 |
---|---|---|
framework | Product | 声明了抽象方法 use 和 createClone 接口 |
framework | Manager | 调用 createClone 方法复制实例类 |
无 | MessageBox | 将字符串放入方框,并显示出来,实现 use 方法 和 createClone 方法 |
无 | UnderlinePen | 给字符串加上上下划线并显示出来的类,实现了 use 和 createClone 方法 |
无 | Main | 测试程序行为的类 |
Product 接口和 Message 类属于 framework包,负责复制实例。
Manager 类虽然会调用 createClone 方法,但是对于具体要复制哪个。并不知道。
但是只要实现了 Product 接口的类,调用它的 createClone 方法就可以复制出新的实例。
MessageBox 类 和 UnderlinePen 类是两个实现了 Product 接口的类。只用实现将这两个类“注册”到 Manager 类中,就可以随时复制新的实例。
Product
package Prototype.framework;
// 继承复制的接口, Cloneable 通过调用 clone 实现对象的调用
public interface Product extends Cloneable{
public abstract void use(String s); // 具体是如何使用,交给子类去实现
public abstract Product createClone();
}
Manager
package Prototype.framework;
import java.util.*;
/** * 使用 product 接口复制实例 */
public class Manager {
// 保存名字和实例之间的对应关系
private HashMap showcase = new HashMap();
public void register(String name, Product proto) {
showcase.put(name,proto);
}
public Product create(String protoname) {
Product p = (Product) showcase.get(protoname);
return p.createClone();
}
}
MessageBox
package Prototype;
import Prototype.framework.Product;
public class MessageBox implements Product {
private char decochar;
public MessageBox(char decochar) {
this.decochar = decochar;
}
public void use(String s) {
int length = s.getBytes().length;
for (int i=0;i<length+4;i++) {
System.out.print(decochar);
}
System.out.println("");
System.out.println(decochar + " " + s + " " + decochar);
for (int i=0;i<length+4;i++) {
System.out.print(decochar);
}
System.out.println("");
}
public Product createClone() {
Product p = null;
try {
p = (Product) clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return p;
}
}
UnderlinePen
package Prototype;
import Prototype.framework.Product;
public class UnderlinePen implements Product {
private char ulchar;
public UnderlinePen(char ulchar) {
this.ulchar = ulchar;
}
public void use(String s) {
int length = s.getBytes().length;
System.out.println("\"" + s + "\"");
System.out.println(" ");
for (int i=0;i< length;i++) {
System.out.print(ulchar);
}
System.out.println("");
}
public Product createClone() {
Product p = null;
try {
p = (Product) clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return p;
}
}
Main
package Prototype;
import Prototype.framework.Manager;
import Prototype.framework.Product;
public class Main {
public static void main(String[] args) {
// 准备
Manager manager = new Manager();
UnderlinePen upen = new UnderlinePen('~');
MessageBox mbox = new MessageBox('*');
MessageBox sbox = new MessageBox('/');
manager.register("strong msg",upen);
manager.register("warning box",mbox);
manager.register("slash box",sbox);
// 生成
Product p1 = manager.create("strong msg");
p1.use("Hello World");
Product p2 = manager.create("warning box");
p2.use("Hello World");
Product p3 = manager.create("slash box");
p3.use("Hello World");
}
}
执行效果
Product 角色负责定义用于复制现有实例来生成新实例的方法。 Product 接口扮演此角色
ConcretePrototype 角色负责实现复制现有的实例并生成新实例的方法。在上述程序中, MessageBox类 和 UnderlinePen 类扮演此角色
Client 角色负责使用复制实例的方法生成新的实例。在示例中,由 Message类 扮演此角色。
要使用 clone 方法进行复制实例,就要实现 Cloneable 接口,否则就会出现 CloneNotSupportedException
java.lang 包是默认引入的。因此不必显示引入 java.lang 包调用 clone() 方法
clone() 方法定义在 java.lang.Object 中,因为 Object 类是所有 java 类的父类。因此所有类都默认继承了 Object 类。
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://codinggorit.blog.csdn.net/article/details/114046583
内容来源于网络,如有侵权,请联系作者删除!