设计模式之原型模式(Prototype)

2021-11-27  本文已影响0人  ZHG

设计模式中有六大原则和二十三设计模式。
其中六大原则分别为:单一职责原则、开闭原则、里氏替换原则、依赖倒置原则、接口隔离原则、迪米特原则。
二十三设计模式:单例模式、Builder 模式、原型模式、工厂方法模式、抽象工厂模式、策略模式、状态模式、责任链模式、解释器模式、命令模式、观察者模式、备忘录模式、迭代器模式、模版方法模式、访问者模式、中介模式、代理模式、组合模式、适配器模式、装饰模式、享元模式、外观模式、桥接模式。

定义

使用场景

说到拷贝,我们再说下深拷贝和浅拷贝。

深拷贝和浅拷贝

需要注意的是:对于我们常用【=】它不属于浅拷贝,属于赋值,是同一个对象。如果是基本类型我们拷贝的是它的值;如果是对象则是拷贝的是对象内存地址的引用,其实他们还是同一个对象。

示例

/**
 * 元素类
 */
public class Children implements Cloneable {
    private String content;

    @Override
    protected Children clone() throws CloneNotSupportedException {
        return (Children)super.clone();
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }
}
/**
 * 原型类
 */
public class Prototype implements Cloneable {

    private String message;
    private String title;
    private Children children;
    // ...

    @Override
    protected Prototype clone() throws CloneNotSupportedException {
        // 浅拷贝
        return (Prototype)super.clone();
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public Children getChildren() {
        return children;
    }

    public void setChildren(Children children) {
        this.children = children;
    }
}
    public static void main(String[] args) throws CloneNotSupportedException {
        Prototype prototype1 = new Prototype();
        prototype1.setTitle("Title1");
        prototype1.setMessage("Message1");
        Children children = new Children();
        children.setContent("Content1");
        prototype1.setChildren(children);
        System.out.println("prototype1------\n    hashCode = "+prototype1.hashCode()+"\n    title ="+prototype1.getTitle()+"\n    message="+prototype1.getMessage());
        System.out.println("Children1-------\n    hashCode = "+prototype1.getChildren().hashCode()+"\n    content="+prototype1.getChildren().getContent());
        Prototype prototype2 = prototype1.clone();
        System.out.println("prototype2------\n    hashCode = "+prototype2.hashCode()+"\n    title ="+prototype2.getTitle()+"\n    message="+prototype2.getMessage());
        System.out.println("Children2-------\n    hashCode = "+prototype2.getChildren().hashCode()+"\n    content="+prototype2.getChildren().getContent());
        prototype2.getChildren().setContent("Content2");
        System.out.println("prototype11------\n    hashCode = "+prototype1.hashCode()+"\n    title ="+prototype1.getTitle()+"\n   message="+prototype1.getMessage());
        System.out.println("Children11-------\n    hashCode = "+prototype1.getChildren().hashCode()+"\n    content="+prototype1.getChildren().getContent());
        System.out.println("prototype22------\n    hashCode = "+prototype2.hashCode()+"\n    title ="+prototype2.getTitle()+"\n   message="+prototype2.getMessage());
        System.out.println("Children22-------\n    hashCode = "+prototype2.getChildren().hashCode()+"\n    content="+prototype2.getChildren().getContent());
    }
prototype1------
    hashCode = 531885035
    title =Title1
    message=Message1
Children1-------
    hashCode = 1418481495
    content=Content1
prototype2------
    hashCode = 303563356
    title =Title1
    message=Message1
Children2-------
    hashCode = 1418481495
    content=Content1
prototype11------
    hashCode = 531885035
    title =Title1
   message=Message1
Children11-------
    hashCode = 1418481495
    content=Content2
prototype22------
    hashCode = 303563356
    title =Title1
   message=Message1
Children22-------
    hashCode = 1418481495
    content=Content2

从上边的例子我们可以看出 Prototype 的 clone() 方法只是创建它自己本身新对象,而它的元素 Children 还是指向了原有的地址,这就是浅拷贝。要是想实现深拷贝,只需要重写 Prototype 的 clone() 方法。

    @Override
    protected Prototype2 clone() throws CloneNotSupportedException {
        // 浅拷贝
        Prototype2 prototype2 = (Prototype2)super.clone();
        prototype2.children = this.children.clone();
        return prototype2;
    }
prototype1------
    hashCode = 531885035
    title =Title1
    message=Message1
Children1-------
    hashCode = 1418481495
    content=Content1
prototype2------
    hashCode = 303563356
    title =Title1
    message=Message1
Children2-------
    hashCode = 135721597
    content=Content1
prototype11------
    hashCode = 531885035
    title =Title1
   message=Message1
Children11-------
    hashCode = 1418481495
    content=Content1
prototype22------
    hashCode = 303563356
    title =Title1
   message=Message1
Children22-------
    hashCode = 135721597
    content=Content2

以上对原型模式(深拷贝、浅拷贝)进行了举例。接下来我们再说下它的优缺点。

优缺点

优点

缺点

总结

浅拷贝和深拷贝有多种实现方法,这里只用一种方法举例,其他的方法可以参照深拷贝浅拷贝
原型模式的宗旨就是对象的拷贝,节省创建多次创建新对象带来的消耗,提高性能。但是也需要注意深浅拷贝带来的问题。

DEMO

参考

上一篇下一篇

猜你喜欢

热点阅读