美文网首页
设计模式之原型模式

设计模式之原型模式

作者: CRUD_1133 | 来源:发表于2018-12-01 19:23 被阅读0次

一  预备知识

      1. 首先我们要知道 原型模式是设计模式中的创建型

       2.要了解原型模式我们要了解java 中的深拷贝和浅拷贝

       3. 定义:所谓原型模式,就是我们利用一个已有的对象,创建更多的相同类型的对象

疑问:这样创建和我们直接new有什么区别吗?

二 疑难解答

1. Java的浅拷贝

看下面的类(不是在编辑器上复制来的,不规范之处就那么地了)

class Book implements Clonable{

           private int price;

           private Author author;

           public Book clone(){

                   Book book = null;

                    try {

                               book = (Book) super.clone();

                      } catch (CloneNotSupportedException e) {

                          // TODO Auto-generated catch block

                          e.printStackTrace();

                         }

                        return book;

          }

            //一些get set 方法

}

class Author {

    private String name;

    private int age;

    public String getName() {

        return name;

    }

    public void setName(String name) {

        this.name = name;

    }

    public int getAge() {

        return age;

    }

    public void setAge(int age) {

        this.age = age;

    }

}

可以看出Book类可以被克隆  Author 类不能被克隆

现在我们创建一个实例

Book book1 = new Book();

book1.setPrice(1);

Anthor author = new Author();

author.setXXX();

book1.setAuthor(author);

这里我们就把Book的属性的值都初始化完,

接下来我们对这个实例进行克隆

Book book2 = book1.clone();

这时候book2.getPrice() = book1.getPrice();

但是book1==book2 的值为false  因为在虚拟机堆中产生了两个实例,这两个引用指向的不是同一个对象。但是我们确把类Book的类型,属性值都拷贝过来了,这样和我们直接new Book相比,我们少了一些给新创建的对象赋值的操作,

注意我们上述复制称为浅复制,因为Book类有两个属性 price与Author

price是基本数据类型,所以我们的克隆来的对象中的price 也是新产生的int类型

而Author 是引用类型的对象,我们克隆的对象,只会产生一个指向原来的Author对象的引用,而不会重新在堆中创建一个实例(深复制与浅复制的区别就在这)

深复制中 引用类型的属性也就是Author,会在堆中又创建一个实例也就是下面的代码

Book中的浅复制

book1.getPrice() == book2.getPrice();  //结果为true

book1.getAuthor() == book2.getAuthor(); //结果为true

上面的复制过程中

内存中会有两个int大小的空间被占用,只有一个Author类型的空间会被占用

换句话说就是book1 中的 author = new Anthor();

book2 中 author = book1.author;

2. java中的深拷贝

Java中的深拷贝是通过序列化与反序列化来实现的。

还是上面的例子:

Book 与Author 都需要实现serializable接口

class Book implements Serializable{

           private int price;

           private Author author;

            public Book deepClone() throws IOException, ClassNotFoundException{

                    // 写入当前对象的二进制流

                    ByteArrayOutputStream bos = new ByteArrayOutputStream(); 

                        ObjectOutputStream oos = new ObjectOutputStream(bos); 

                         oos.writeObject(this);

                        // 读出二进制流产生的新对象 

                         ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); 

                         ObjectInputStream ois = new ObjectInputStream(bis); 

        return (Book) ois.readObject();

    }

//一些get set 方法

}

Author  仅仅是实现序列化接口 这里不写了

然后Book bk1 = new Book();

Book bk2 = bk1.deepClone();

这就是深复制 这里会复制一个Book的实例,同时Author类也会重现创建一个实例,

3. 原型模式

了解了Java中的深浅拷贝,我们就可以很容易理解原型模式了

换句话说Java中的深浅拷贝就是原型模式

我们回过头来看定义   就是我们利用一个已有的对象,创建更多的相同类型的对象

上述例子中Book 就是一个已知类型,我们通过克隆,创建了许多该对象的实例

同我们直接 new 相比我们省略了给他复制初始化的过程,简化了我们的开发,

4. 原型模式的有点与缺点

优点:1. 可以隐藏创建新对象的复杂性(这句话也说明 原型模式适合那些创建很复杂的对象,也适用与那些创建开销很大的对象)

           2. 在某些环境下,复制比创建高效

           3. 可扩展性好,依赖的是抽象

缺点:1.假设Author类中还有别的许多类,他们都要序列化,这就很麻烦

            2.  要为每一个类实现clone方法,对于已经存在的类,就很烦  违反了开闭原则

5. 原型模式结构

1.0 原型模式需要接口

interface YX{

    public Object clone();

}

2.0  需要复制的类要实现这个接口 方法

class Book implements YX{

public Object clone(){

   //实现

}

}

3.0 可以有多个实现,

4.0 原型模式的创建方式有两种:1简单型  2管理型  简单型  就是上面的例子

管理型就是新建一个类 用map来记录都创建了那些对象:map.set("对象1",book1)

下面是完整的浅克隆的例子

package com.jd.test;

//演示浅克隆

public class Bookimplements Cloneable {

private int price;

private int size;

public Book clone(){

Book bk =null;

try {

bk = (Book)super.clone();

}catch (CloneNotSupportedException e){

}

return bk;

}

public int getPrice() {

return price;

}

public void setPrice(int price) {

this.price = price;

}

public int getSize() {

return size;

}

public void setSize(int size) {

this.size = size;

}

@Override

    public String toString(){

return "Book.price = "+this.getPrice()+"  Book.size = "+this.getSize();

}

}

下面是主函数

package com.jd.test;

public class Main {

public static void main(String[] args) {

//  浅克隆

        Book b =new Book();

b.setPrice(1);

b.setSize(12);

System.out.println(b);

Book a = b.clone();

System.out.println(a);

}

}

下面是结果:

Book.price = 1  Book.size = 12

Book.price = 1  Book.size = 12

Process finished with exit code 0

相关文章

网友评论

      本文标题:设计模式之原型模式

      本文链接:https://www.haomeiwen.com/subject/kdwvqqtx.html