文章目录
什么是原型模式
通常,我们会使用 new something() 的方式去创建实例,但是如下几种情况可能并不支持我们这样创建。例如:
- 对象种类繁多,无法将他们整合到一个类中时
需要处理的对象太多,如果将他们分别作为一个类,需要编写很多个类文件。 - 难以根据类生产实例
类实例的生成过程太复杂,很难根据实例来生成实例。例如在图形编辑器中使用鼠标制作出图形的实例,在想生成一个和之前用户操作所创建出的实例完全一样的实例,会先将所创建的实例保存起来,然后通过复制来生成新的实例 - 想解耦框架与生产的实例
想让生成实例的框架不依赖于具体的类。这时,不能指定类名来生成实例,而要事先注册一个原型,然后通过复制该实例来生成新的实例。
在设计模式中,原型模式是创建型设计模式,是根据实例原型、实例模型来生成新的实例。
Cloneable接口和Clone方法
Cloneable是一个标记接口,这个接口中没有任何的抽象方法,实现该接口,表示该接口的实现类可以去使用Clone
package java.lang;
public interface Cloneable {
}
Clone方法是Object类中的一个方法,它可以在一个实例的基础上复制出一个新的实例,Object类是所有类的父类,故所有类都具有Clone方法,但是如果某个类的实例想使用此方法,该类必须先实现Cloneable接口,不然使用时会抛出CloneNotSupportedException异常。
protected native Object clone() throws CloneNotSupportedException;
Clone方法进行的是浅复制,它知识将被复制的实例的字段值直接复制到新的实例中。例如,如果字段中保存的是数组,使用Clone复制只会复制数组的引用,不会一 一复制数组中的元素。如果Clone无法满足需求可重写Clone
例子
示例是将字符串放入方框中显示出来或加上下划线显示出来
Manager
package CreationPattern.PrototypeMode;
import java.util.HashMap;
/**
* 管理并复制实例
*/
public class Manager {
private HashMap map = new HashMap();
public void register(String name, Product proto) {
map.put(name, proto);
}
public Product create(String protoName) {
Product product = (Product) map.get(protoName);
return product.createClone();
}
}
Product
package CreationPattern.PrototypeMode;
/**
* 产品接口
*/
public interface Product extends Cloneable {
void use(String s);
Product createClone();
}
MessageBox
扫描二维码关注公众号,回复:
16062194 查看本文章
package CreationPattern.PrototypeMode;
/**
* 方框信息
*/
public class MessageBox implements Product {
private char decoChar;
public MessageBox(char decoChar) {
this.decoChar = decoChar;
}
@Override
public void use(String s) {
int len = s.getBytes().length;
for (int i = 0; i < len + 4; i++) {
System.out.print(decoChar);
}
System.out.println();
System.out.println(decoChar + " " + s + " " + decoChar);
for (int i = 0; i < len + 4; i++) {
System.out.print(decoChar);
}
System.out.println();
}
@Override
public Product createClone() {
Product p = null;
try {
p = (Product) clone();
} catch (CloneNotSupportedException e) {
throw new RuntimeException(e);
}
return p;
}
}
UnderlinePen
package CreationPattern.PrototypeMode;
/**
* 下划线信息
*/
public class UnderlinePen implements Product {
private char ulChar;
public UnderlinePen(char ulChar) {
this.ulChar = ulChar;
}
@Override
public void use(String s) {
int len = s.getBytes().length;
System.out.println("\"" + s + "\"");
for (int i = 0; i < len; i++) {
System.out.print(ulChar);
}
System.out.println();
}
@Override
public Product createClone() {
Product p = null;
try {
p = (Product) clone();
} catch (CloneNotSupportedException e) {
throw new RuntimeException(e);
}
return p;
}
}
结果
总结
通常,我们使用 new something() 来创建实例,但是以这种方式创建是必须指定类名的,但有时候也会有在不指定类名的前提下生产实例的需求,或者对象种类繁多,又或者想解耦框架与生成实例,这时候,我们便需要使用原型模式。