原型模式 落日映苍穹つ 2021-12-05 01:03 215阅读 0赞 **原型模式(Prototype Pattern):**通过原型实例指定创建对象的种类,并且通过克隆这些原型来创建新的对象。原型模式是一种创建型模式 完成原型模式一般需要3个角色,抽象原型类、具体原型类、客户类 抽象原型类:声明克隆方法的接口、抽象类或具体实现类。是所有具体原型类的公共父类 具体原型类:实现抽象原型类,实现抽象原型类中的克隆方法,并在克隆方法中返回自己的一个克隆对象 客户类:通过原型对象克隆自己创建新的对象 实例代码如下 定义抽象原型类,声明克隆方法 package com.design.prototype; /** * 抽象原型类 */ public interface Prototype { //声明克隆方法 Prototype clone(); } 定义具体原型类,实现抽象原型类,实现克隆方法 package com.design.prototype; /** * 具体原型类 */ public class ConcretePrototype implements Prototype{ private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public Prototype clone() { Prototype prototype = new ConcretePrototype(); ((ConcretePrototype) prototype).setName(this.name); return prototype; } @Override public String toString() { return "ConcretePrototype{" + "name='" + name + '\'' + '}' + super.toString(); } } 定义客户类,调用测试 package com.design.prototype; public class TestMain { public static void main(String[] args) { Prototype prototype = new ConcretePrototype(); System.out.println(prototype); //克隆 prototype1 对象 Prototype prototype1 = prototype.clone(); System.out.println(prototype1); } } 上述示例代码可以作为原型模式的通用实现,与编程语言特性无关 下边来谈 java 语言实现原型模式 **java 语言实现原型模式** 使用 java 语言实现原型模式很简单。了解 java 语言的人都知道,在 java 语言中所有的类都继承自 java.lang.Object 类,而 Object 类提供了一个 clone()方法,可以将 java 对象进行克隆。因此,使用 java 语言实现原型模式可以不定义抽象原型类,直接使用 Object 类提供的 clone()方法实现对 java 对象的克隆 示例代码如下 定义书籍类 注意:要实现克隆的 java 类必须实现 Cloneable 接口,表示这个 java 类支持复制 这里的 clone() 方法直接使用了父类 Object 的 clone()方法 package com.design.prototype.javaprototype; import java.util.Date; public class Book implements Cloneable{ public Book(String bookName, String bookAuthor, Date date){ this.bookName = bookName; this.bookAuthor = bookAuthor; this.date = date; } private String bookName; private String bookAuthor; private Date date; public String getBookName() { return bookName; } public void setBookName(String bookName) { this.bookName = bookName; } public String getBookAuthor() { return bookAuthor; } public void setBookAuthor(String bookAuthor) { this.bookAuthor = bookAuthor; } public Date getDate() { return date; } public void setDate(Date date) { this.date = date; } @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); //浅克隆 } @Override public String toString() { return "Book{" + "bookName='" + bookName + '\'' + ", bookAuthor='" + bookAuthor + '\'' + ", date=" + date + '}'+ super.toString(); } } 测试调用 package com.design.prototype.javaprototype; import java.util.Date; public class TestMain { public static void main(String[] args) throws CloneNotSupportedException { Book book = new Book("红楼梦", "曹雪芹", new Date()); Book book1 = (Book) book.clone(); System.out.println(book); System.out.println(book1); System.out.println(book == book1); System.out.println(book.getBookName() == book1.getBookName()); } } 测试结果如下图 ![20190717164006791.png][] 通过打印出的结果可以看出,使用原型模式成功克隆出来 book1 对象 但是,如果仔细观察会发现 book 对象和 book1 对象的 bookName 属性的内存地址值完全相等,通过 debug 进一步分析 ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dzanp6Y2Jx_size_16_color_FFFFFF_t_70][] 发现 book 对象和 book1 对象的属性确实指向了相同的内存地址,这里我们引入两个概念,浅克隆和深克隆 **浅克隆:**若原型对象的成员变量是值类型,则复制一份给克隆对象;若原型对象的成员变量是引用类型,则将引用对象的内存地址复制一份给克隆对象,即原型对象和克隆对象的成员变量都指向相同的内存地址。简单的讲,浅克隆只复制对象本身及其中包含的值类型的成员变量,引用类型的成员对象并没有被复制 ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dzanp6Y2Jx_size_16_color_FFFFFF_t_70 1][] **深克隆:**无论原型对象的成员变量是值类型还是引用类型,都复制一份给克隆对象 了解了浅克隆和深克隆的概念后,就知道上边的代码其实实现的是浅克隆的原型模式 下边代码演示深克隆的原型模式 这里自定义克隆方法 package com.design.prototype.javaprototype; import java.io.*; import java.util.Date; public class DeepBook implements Serializable { public DeepBook(String bookName, String bookAuthor, Date date){ this.bookName = bookName; this.bookAuthor = bookAuthor; this.date = date; } private String bookName; private String bookAuthor; private Date date; public String getBookName() { return bookName; } public void setBookName(String bookName) { this.bookName = bookName; } public String getBookAuthor() { return bookAuthor; } public void setBookAuthor(String bookAuthor) { this.bookAuthor = bookAuthor; } public Date getDate() { return date; } public void setDate(Date date) { this.date = date; } /** * 自定义深克隆方法 * @return */ public DeepBook clone(){ DeepBook deepBook = null; try { ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream); objectOutputStream.writeObject(this); ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray()); ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream); try { deepBook = (DeepBook) objectInputStream.readObject(); } catch (ClassNotFoundException e) { e.printStackTrace(); } } catch (IOException e) { e.printStackTrace(); } return deepBook; } } 测试调用 package com.design.prototype.javaprototype; import java.util.Date; public class TestMain { public static void main(String[] args) throws CloneNotSupportedException { DeepBook deepBook = new DeepBook("三国演义","罗贯中", new Date()); DeepBook deepBook1 = deepBook.clone(); System.out.println(deepBook.getBookName() == deepBook1.getBookName()); } } ![20190717174510700.png][] 控制台打印 false,说明实现了深克隆 **原型模式总结** 优点:创建新的较为复杂的对象时,使用原型模式可以简化创建过程;扩展性好;深克隆方式可以保存对象状态 缺点:因为每个类配备一个克隆方法,所以对已有的类进行改造时,违背了开闭原则;深克隆编写较为复杂的代码比较麻烦 适用场景:创建新的对象成本较大,通过原型模式复制得到可以减少资源占用;构造函数比较复杂;循环体中创建大量对象 [20190717164006791.png]: /images/20211205/4d4f607fc02f43bf97388b505ca3865f.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dzanp6Y2Jx_size_16_color_FFFFFF_t_70]: /images/20211205/3a3fa00826dd48d59bd3059551d9f685.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dzanp6Y2Jx_size_16_color_FFFFFF_t_70 1]: /images/20211205/1f5e6e2b9bc440228e19fd92fc80a9af.png [20190717174510700.png]: /images/20211205/e74af43d79334df5ae485646a937d482.png
相关 原型模式 public class Phone implements Cloneable { private String toPhoneNumber; 柔情只为你懂/ 2022年03月31日 08:16/ 0 赞/ 188 阅读
相关 原型模式 一. 原型模式简介 原型模式(Prototype Pattern)也是一种创建型模式,它关注的是大量相似对象的创建问题。我们经常会遇到这样的情况:在系统中要创建大量的 超、凢脫俗/ 2022年02月21日 12:16/ 0 赞/ 218 阅读
相关 原型模式 对象浅拷贝 实现Clonable接口,重写clone方法,jvm的本地方法实现拷贝 Object protected native Object clone() 女爷i/ 2021年12月12日 11:39/ 0 赞/ 254 阅读
相关 原型模式 原型模式(Prototype Pattern):通过原型实例指定创建对象的种类,并且通过克隆这些原型来创建新的对象。原型模式是一种创建型模式 完成原型模式一般需要3个角 落日映苍穹つ/ 2021年12月05日 01:03/ 0 赞/ 216 阅读
相关 原型模式 原型模式 原型模式(Prototype Pattern)是用于创建重复的对象,同时又能保证性能。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。 这种 「爱情、让人受尽委屈。」/ 2021年09月29日 16:10/ 0 赞/ 307 阅读
相关 原型模式 原型模式:用原型实例指定创建指定对象的种类,并且通过复制这些原型创建新的对象,同时又能保证性能。这种模式是实现了一个原型接口,该接口用于创建当前对象的克隆。当直接创建对象的代价 骑猪看日落/ 2021年09月17日 01:08/ 0 赞/ 301 阅读
相关 原型模式 5.原型模式 ![70][] class Program { static void Main(string[] arg 痛定思痛。/ 2021年09月16日 23:52/ 0 赞/ 334 阅读
相关 原型模式 原型模式 定义 在软件系统中,有时需要多次创建某一类型的对象,为了简化创建过程,可以只创建一个对象,然后通过对象克隆的方式复制出多个相同的对象,这就是原型设计模 野性酷女/ 2021年07月24日 20:41/ 0 赞/ 473 阅读
相关 原型模式 型模式(Prototype Pattern)是用于创建重复的对象,同时又能保证性能。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。 这种模式是实现了... 小灰灰/ 2020年06月13日 05:37/ 0 赞/ 719 阅读
还没有评论,来说两句吧...