原型(Prototype Pattern)是一个简单的设计模式。原型模式的英文原话是:Specify the kind of objects to create using a prototypical instance,and create new objects by copying this prototype.意思是:用原型实例指定创建对象的种类,并且通过复制这些原型创建新的对象。
原型模式有三种角色:
1.客户(Client)角色:该角色提出创建对象的请求。
2.抽象原型(Prototype):该角色是一个抽象角色,通常由一个java接口或抽象类实现,给出所有的具体原型类所需要的接口。
3.具体原型(Concrete Prototype)角色:该角色是被复制的对象,必须实现抽象原型接口。
java中内置了克隆机制。object类具有一个clone()方法,能够实现对对象的克隆,是一个类支持克隆只需要两步:
1.实现Cloneable接口。
2.覆盖Object的clone()方法,完成对象的克隆操作,通常只需要调用Object的clone()方法即可。为了使外部能够调用此类的clone()方法,可以将访问修饰符改为public。
- /**
- * 抽象原型角色(Prototype)
- * 给出具体原型类复制所需要的接口
- */
- public interface Prototype {
- //克隆方法
- Prototype clone();
- }
- /**
- * 具体原型工厂类
- *
- */
- public class ConcretePrototype implements Prototype {@Override public Prototype clone() {
- try {
- return (Prototype) super.clone();
- } catch(CloneNotSupportedException e) {
- e.printStackTrace();
- return null;
- }
- }
- }
- public class Client {
- public void operation(Prototype example) {
- //得到example
- Prototype prototype = example.clone();
- }
- }
1.性能优良:原型模式是对内存中二进制流的拷贝,要比直接new一个对象性能好,特别是当一个循环体内产生大量的对象时,原型模式可以更好地体现其优点。
2.逃避构造函数的约束。这既是优点也是缺点,直接在内存中拷贝对象,构造函数是不会执行的,因此减少了约束,不过这一点需要在实际应用时进行权衡考虑。
1.资源优化场景,类初始化时需要消化非常多的资源,这个资源包括数据、硬件资源等。
2.性能和安全要求的场景,如果通过new产生一个对象需要非常繁琐的数据准备和访问权限,则可以使用原型模式。
3.一个对象多个修改者的场景,一个对象需要提供给其他对象访问,而且各个调用者可能都需要修改其值,可以考虑使用原型模式拷贝多个对象供调用者使用。
在实际项目中,原型模式很少单独出现,一般是和工厂方法模式一起出现。原型模式通过clone()方法创建一个对象,然后由工厂方法提供给调用者。
例子
- /**
- * 实现clone接口,实现了clone方法,是实现克隆的关键
- */
- public class Mail implements Cloneable {
- //收件人
- private String receiver;
- //邮件标题
- private String subject;
- //称谓
- private String appellation;
- //邮件内容
- private String contxt;
- //尾部
- private String tail;
- //构造函数
- public Mail(String subject, String contxt) {
- this.subject = subject;
- this.contxt = contxt;
- }
- //克隆方法
- public Mail clone() {
- Mail mail = null;
- try {
- mail = (Mail) super.clone();
- System.out.println(super.toString()); //super指的是被调用的那个对象
- } catch(CloneNotSupportedException e) {
- e.printStackTrace();
- }
- return mail;
- }
- }
- /**
- * 调用
- */
- public class SendMailDemo {
- Map students = new LinkedHashMap();
- public static void main(String[] args) {
- //创建一个原型mail
- Mail mail = new Mail("邮件标题", "邮件内容");
- mail.setTail("2017-11-20");
- SendMailDemo sendMailDemo = new SendMailDemo();
- //获取所有学生
- Map students = sendMailDemo.getStudent();
- for (Object name: students.keySet()) {
- //克隆邮件
- Mail cloneMail = mail.clone();
- cloneMail.setAppellation(name.toString());
- cloneMail.setReceiver(students.get(name).toString());
- sendMailDemo.sendMail(cloneMail);
- }
- }
- public Map getStudent() {
- students.put("studentone", "1@foxmail.com");
- students.put("studenttwo", "2@foxmail.com");
- students.put("studentthree", "3@foxmail.com");
- students.put("studentfour", "4@foxmail.com");
- students.put("studentfive", "5@foxmail.com");
- students.put("studentsix", "6@foxmail.com");
- students.put("studentseven", "7@foxmail.com");
- return students;
- }
- public void sendMail(Mail mail) {
- System.out.println("标题:" + mail.getSubject() + "\t收件人邮箱:" + mail.getReceiver() + "\t正文:" + mail.getAppellation() + mail.getContxt() + "\t...已发送");
- }
- }
源码
来源: http://www.cnblogs.com/aeolian/p/7853477.html