简介

原型模式是一种对象创建型模式,用原型模式可以用原型实例指定创建对象的种类,它允许通过一个原型对象创建多个同类型的其他对象,而无需知道该对象的创建细节,在Java中可以直接使用Object提供的clone()方法来实现对象的克隆(浅克隆)。

结构

UML

原型模式结构

  • Prototype:抽象原型类,给出所有的具体原型类所需的接口。

  • ConcretePrototype:具体原型类,被复制的对象,此角色需要实现抽象的原型角色所要求的接口。

  • Client:客户类。

应用场景

原型模式,适合于当一个类初始化需要消耗很多资源时,有很多相似对象时,可以设计一个原型,通过对成员变量的些微修改来实现;需要时可以用深克隆的方式保存对象的状态,比如实现撤销操作等。

优缺点

  • 优点

    原型模式简化了创建对象的过程,通过一个已有的实例进行复制提高了创建实例的效率,具有较好的可扩展性。

  • 缺点 部分时候实现克隆可能较为麻烦。

示例讲解

  当汽车生产商批量生产汽车时,可以对于一个汽车型号进行批量生产,原型模式实现该机制,浅克隆时需要对汽车品牌做调整时,无需修改原车型,修改克隆得到的对象即可,深克隆时批量生产汽车时,汽车品牌也批量生产。

应用场景类图

浅克隆UML

浅克隆UML  

深克隆UML

深克隆UML

浅克隆代码实现

1)Brand.java
public class Brand {
    public void install(){
        System.out.println("安装汽车品牌");
    }
}
12345
2)Car.java
public class Car implements Cloneable{
    private Brand brand;
    
    public Car(){
        this.brand = new Brand();
    }
    
    @Override
    protected Object clone() {
        Car clone = null;
        try {
            clone = (Car)super.clone();
        } catch (CloneNotSupportedException e) {
            System.out.println("克隆失败...");
        }
        return clone;
    }
    
    public Brand getBrand(){
        return this.brand;
    }
    
    public void run(){
        System.out.println("小汽车能跑了");
    }
}
3)Client.java
public class Client {
    public static void main(String[] args) {
        Car car,cloneCar;
        car = new Car();
        cloneCar = (Car)car.clone();
        
        System.out.println("car == cloneCar?");
        System.out.println(car == cloneCar);
        
        System.out.println("car.getBrand() == cloneCar.getBrand()?");
        System.out.println(car.getBrand() == cloneCar.getBrand());
    }
}

深克隆代码实现

1)Brand.java
public class Brand implements Serializable{
    private static final long serialVersionUID = 1L;
​
    public void install(){
        System.out.println("安装汽车品牌");
    }
}
2)Car.java
public class Car implements Serializable{
    private static final long serialVersionUID = 1L;
    private Brand brand = null;
    
    public Car(){
        this.brand = new Brand();
    }
    
    public Object deepClone() throws IOException, ClassNotFoundException{
        //将对象写入流中
        ByteArrayOutputStream bao=new ByteArrayOutputStream();
        ObjectOutputStream oos=new ObjectOutputStream(bao);
        oos.writeObject(this);
                
        //将对象从流中取出
        ByteArrayInputStream bis=new ByteArrayInputStream(bao.toByteArray());
        ObjectInputStream ois=new ObjectInputStream(bis);
        return(ois.readObject());
    }
​
    public Brand getBrand(){
        return this.brand;
    }
​
    public void run(){
        System.out.println("小汽车能跑了");
    }
}

3)Client.java

public class Client {
​
    public static void main(String[] args) {
        Car car,cloneCar=null;
        car = new Car();
        try {
            cloneCar = (Car) car.deepClone();
        } catch (Exception e) {
            e.printStackTrace();
        }
        
        System.out.println("car == cloneCar?");
        System.out.println(car == cloneCar);
        
        System.out.println("car.getBrand() == cloneCar.getBrand()?");
        System.out.println(car.getBrand() == cloneCar.getBrand());
    }
}