原型模式

原型模式

概述

原型模式是一种创建型设计模式, 使你能够复制已有对象, 而又无需使代码依赖它们所属的类。

场景

如果有一个对象,希望生成与其完全相同的一个复制品。最直接的步骤就是创建一个相同的类,然后遍历所有成员变量赋值到新对象中。

问题

有些对象可能拥有私有的成员变量在本身之外不可见,同时还有一个问题:必须知道所属的类才能创建复制品,所以代码必须依赖该类,但于此同时你可能仅知道这个对象所实现的接口,但还并不知道所属具体类。

解决方法

让对象实现克隆的功能。调用这个克隆的功能会生成一个完全一样的对象。

代码实例

// 原型类
public abstract class Shape implements Cloneable {

    public int positionX;

    public int positionY;

    private Ref ref;

    public Ref getRef() {
        return ref;
    }

  	// 测试深浅拷贝
    public void setRef(Ref ref) {
        this.ref = ref;
    }

    public Shape(int positionX, int positionY) {
        this.positionX = positionX;
        this.positionY = positionY;
    }

    public int getPositionX() {
        return positionX;
    }

    public void setPositionX(int positionX) {
        this.positionX = positionX;
    }

    public int getPositionY() {
        return positionY;
    }

    public void setPositionY(int positionY) {
        this.positionY = positionY;
    }

    @Override
    protected Shape clone() throws CloneNotSupportedException {
        System.out.println("原型克隆成功");
        return (Shape) super.clone();
    }
}


public class Rectangle extends Shape {

    public Rectangle(int positionX, int positionY, int width, int length) {
        super(positionX, positionY);
        this.width = width;
        this.length = length;
    }

    public Rectangle(int positionX, int positionY) {
        super(positionX, positionY);
    }

    private int width;

    private int length;



    public void setWidth(int width) {
        this.width = width;
    }

    public void setLength(int length) {
        this.length = length;
    }

    @Override
    public String toString() {
        return "Rectangle{" +
                "width=" + width +
                ", length=" + length +
                ", positionX=" + positionX +
                ", positionY=" + positionY +
                '}';
    }
}

// 测试引用类
public class Ref {

    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

// 测试类
public class Client {
    public static void main(String[] args) throws CloneNotSupportedException {
        // 在x=4,y=5 坐标下创建一个长为4,宽为2的矩形
        Rectangle rectangle = new Rectangle(4, 5, 4, 2);

        Ref ref = new Ref();
        ref.setName("jack");
        rectangle.setRef(ref);

        // 复制一下
        Shape rectangleClone = rectangle.clone();
        // 查看一下位置和大小
        System.out.println(rectangleClone);
        // 查看是否是同一个对象
        System.out.println(rectangle == rectangleClone);

        // 验证clone是浅克隆:结果是浅拷贝
        rectangleClone.getRef().setName("rose");
        System.out.println(rectangle.getRef().getName());
    }
}

总结

  1. clone方法是浅拷贝,如果要实现深拷贝需要用流来处理
  2. 克隆包含循环引用的对象很麻烦
  3. 克隆对象要实现Cloneable接口
posted @ 2021-07-27 23:25  Jimmyhe  阅读(39)  评论(0编辑  收藏  举报