Java中的设计模式-六(原型模式)

89 阅读2分钟

释义

  原型模式是一种创建型设计模式,该模式允许一个对象再创建另外一个可定制的对象,根本无需知道任何如何创建的细节,工作原理是通过将一个原型对象传给那个要发动创建的对象,这个要发动创建的对象通过请求原型对象拷贝它们自己来实施创建。
  原型模式需要先有一个原型,在Java开发中,原型就可以是一个普通的类对象。

案例

public class Person implements Cloneable {  
    private String name;  
    private Integer age;  
    private Car car;  

    public Person(String name, Integer age, Car car) {  
        this.name = name;  
        this.age = age;  
        this.car = car;  
    }  

    public String getName() {  
        return name;  
    }  

    public Integer getAge() {  
        return age;  
    }  

    public Car getCar() {  
        return car;  
    }  

    @Override  
    protected Person clone() {  
        Person person;  
        try {  
            person = (Person)super.clone();  
            person.car = car.clone();  
        } catch (CloneNotSupportedException e) {  
            throw new RuntimeException(e);  
        }  
        return person;  
    }  
}
public class Car implements Cloneable{  
    private String brand;  
    private String type;  

    public Car(String brand, String type) {  
        this.brand = brand;  
        this.type = type;  
    }  

    public String getBrand() {  
        return brand;  
    }  

    public void setBrand(String brand) {  
        this.brand = brand;  
    }  

    public String getType() {  
        return type;  
    }  

    public void setType(String type) {  
        this.type = type;  
    }  

    @Override  
    protected Car clone(){  
        Car car;  
        try {  
            car = (Car)super.clone();  
        } catch (CloneNotSupportedException e) {  
            throw new RuntimeException(e);  
        }  
        return car;  
    }  
}

  这里创建了一个普通的Person类和Car类,当我们使用这两个类的时候,就可以用new的方式来进行创建,并进行复制。这里这两个类就可以称之为一种原型。通过示例代码看出,这两个类分别实现了Cloneable接口,并且重写了clone方法。这里实现Cloneable接口是一个标记接口,源码中该接口没有任何方法,类似于Spring中的注解标记。只是为了表明该类可以被克隆,也就是重写的clone方法可以完整的执行下来。

public static void main(String[] args) {  
    Car car = new Car("奔驰", "S500");  
    Person prototype = new Person("我",18,car);  
    System.out.println(prototype.getName());  
    Person clone = prototype.clone();  
    System.out.println(clone.getName());  
    car.setType("S600");  
    System.out.println(clone.getCar().getBrand());  
}

  这里列出调用方式,创建了一个Car对象并创建了一个Person对象,将Car复制给Person,然后到这里,Person可以当作原型来进行克隆操作。复制出一个一模一样的Person来。

深拷贝和浅拷贝

  这里是原型复制中会产生的一个问题,当上面的代码的Car对象中不实现Cloneable的时候,我们直接clone整个Person对象的话,由于复制的是引用地址,导致Car被两个不同的Person对象使用,尽管两个Person是一样的信息。这样对其中一个Person修改的时候,另一个Person的Car对象也会被修改。所以需要对Car也进行一次复制。这种对引用类型只复制引用地址的行为就叫做浅拷贝,而整体全部复制过来的情况就是一种深拷贝。 image.png