【设计模式】(九)–创建型模式–原型模式
原型模式定义
Specify the kinds of objects to create using a prototypical instance, and create new objects by copying this prototype
意思是:用原型实例指定创建对象可以创建指定的种类对象并且通过复制这些原型创建新的对象。
原型模式一般有以下3个角色
- 抽象原型(Prototype) 属于一个抽象类型,可以是Java接口或者抽象类,提供了原型类所需要的的接口。
- 具体原型 抽象原型的实现类及对象,执行者执行时,提供复制对象的功能。
- 执行者 执行具体创建对象的请求。
Java中内置克隆机制,Object类具有一个clone方法,能够实现对象的克隆,
一个类支持克隆需要:
1.实现Cloneable接口
2.覆盖Object的clone方法,为了是外部能够调用clone方法,可以把clone修改为public。
原型模式的优点
- 提高性能。 因为是直接复制,不需要重新创建对象。
- 逃避构造函数的约束。因为直接在内存中复制,构造函数是不会被执行的,减少了约束。
使用场景
- 资源优化场景,= 类初始化需要消化非常多的资源,这个资源包括数据、硬件资源等。
- 性能和安全要求的场景, 通过new 产生一个对象需要非常繁琐的数据准备或访问权限,则可以使用原型模式。
- 一个对象多个修改者的场景。 一个对象需要提供给其他对象访问,而且各个调用者可能都需要修改其值时,可以考虑使用原型模式拷贝多个对象供调用者使用。
在实际项目中,原型模式很少单独出现,一般是和工厂方法模式一起出现,通过 clone的方法创建一个对象,然后由工厂方法提供给调用者。原型模式已经与 Java 融为浑然一体,大家可以随手拿来使用
原型模式的简单实现
类图
实现
public class Broker {
public static void main(String[] args) {
Message originalMessage = getMessageFromCommintLog();
List<String> consumerList = getConsumerList();
for (String consumer : consumerList) {
Message message = originalMessage.clone();
message.setConsumer(consumer);
pushMessage(message);
}
}
public static Message getMessageFromCommintLog() {
return new Message("topicA", "北外三少的一段queue消息", "带有的属性参数");
}
public static List<String> getConsumerList() {
return new ArrayList<String>() {{
add("大少");
add("二少");
add("三少");
}};
}
public static void pushMessage(Message message) {
System.out.println("推送消息至:" + message.getConsumer() + ",内容:" + message.getBody() + ",topic:" + message.getTopic());
}
}
public class Message implements Cloneable {
private String topic;
private String body;
private String properties;
private String consumer;
public Message(String topic, String body, String properties) {
this.topic = topic;
this.body = body;
this.properties = properties;
}
public Message clone() {
Message message = null;
try {
message = (Message) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return message;
}
public String getTopic() {
return topic;
}
public void setTopic(String topic) {
this.topic = topic;
}
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
public String getProperties() {
return properties;
}
public void setProperties(String properties) {
this.properties = properties;
}
public String getConsumer() {
return consumer;
}
public void setConsumer(String consumer) {
this.consumer = consumer;
}
}
执行结果
实现解读,主要是从commitLog中取一条消息,因为要加工发送给多个消费者的示例。