原型(Prototype)模式的定义如下:用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型相同或相似的新对象。在这里,原型实例指定了要创建的对象的种类。用这种方式创建对象非常高效,根本无须知道对象创建的细节。
在 Java
中有 Clone
,因此这个原型模式用起来就很舒服。
我们先看一个案例,我们现在来模拟一个邮件的发送。
现在有一个邮件类:
1 2 3 4 5
| public class Mail { private String name; private String emailAddress; private String content; }
|
里面的一些基本方法啥的被省略了。
再看一个工具类,这个工具类主要就是发送邮件的:
1 2 3 4 5 6 7 8 9 10
| public class MailUtil { public static void sendMail(Mail mail){ String output = "向{0}同学,邮件地址{1},邮件内容{2}" ; System.out.println(MessageFormat.format(output , mail.getName() , mail.getEmailAddress(),mail.getContent())); }
public static void save(Mail mail){ System.out.println("存储邮件记录: " + mail.getContent()); } }
|
现在来看这个一般的邮件发送是怎么发送的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public class ProtoTypeTest { public static void main(String[] args) { Mail mail = new Mail(); mail.setContent("初始化模板");
for (int i = 0; i < 20; i++) { mail.setName("姓名-" + i); mail.setEmailAddress("name-"+ i + "@imooc.com"); mail.setContent("Content-: " + i); MailUtil.sendMail(mail); } MailUtil.save(mail); } }
|
根据上面的呢,我们最后的结果一定不是我们所期待的结果,如果说我们将 mail 的构想构建放在 for 里面,那就会造成很多的 mail 的无用对像,浪费资源。这时候,原型模式就有了他的作用了。我们来看原型模式的一个修改.
我们需要修改的是, Mail 实现 Cloneable ,重写 clone 方法。
1 2 3 4 5
| @Override protected Object clone() throws CloneNotSupportedException { System.out.println("clone mail"); return super.clone(); }
|
然后我们在主类中做修改:
1 2 3 4 5 6 7 8
| for (int i = 0; i < 20; i++) { Mail clone = (Mail) mail.clone(); clone.setName("姓名-" + i); clone.setEmailAddress("name-"+ i + "@imooc.com"); clone.setContent("Content-: " + i); MailUtil.sendMail(mail); } MailUtil.save(mail);
|
这样就好了。这就是最简单的原型了,这里的原型模式里面的克隆是由深克隆和浅克隆的,需要注意一下。