0
点赞
收藏
分享

微信扫一扫

【设计模式】从蓝图到复制:深入探究原型模式在设计模式中的价值


目录

一、前言

二、原型模式定义

三、原型模式的实现方式

1、浅拷贝(Shallow Copy)

2、深拷贝(Deep Copy)

2.1、重写clone方法来实现深拷贝

2.2、通过对象序列化实现深拷贝

2.3、方式 1 和方式 2 对比

四、原型模式应用场景

1、对象创建成本高昂

2、动态配置

3、保护对象状态

五、原型模式优点

1、简化对象创建

2、减少资源消耗

3、保护对象

六、注意事项

1、深拷贝的复杂性

2、克隆方法的实现

七、代码示例

八、总结

一、前言

设计模式作为软件开发的指导原则,其中原型模式是一种独特而有价值的模式。本文将深入探究原型模式在设计模式中的价值,解析其创新思想和应用场景,带您领略原型模式的精髓。

二、原型模式定义

原型模式是一种创建型设计模式,它允许对象通过复制自身来创建新的对象,而无需使用构造函数。原型模式通过将对象的复制与客户端代码解耦,提供了更灵活和可扩展的对象创建方式。

【设计模式】从蓝图到复制:深入探究原型模式在设计模式中的价值_设计模式

这种模式是实现了一个原型接口,该接口用于创建当前对象的克隆。当直接创建对象的代价比较大时,则采用这种模式。

三、原型模式的实现方式

1、浅拷贝(Shallow Copy)

浅拷贝创建一个新对象,将原始对象的属性值复制到新对象中。如果属性值是基本类型,复制的是值本身;如果属性是引用类型,复制的是引用。因此,两个对象的引用类型属性仍然指向同一内存地址。

【设计模式】从蓝图到复制:深入探究原型模式在设计模式中的价值_System_02

 

2、深拷贝(Deep Copy)

深拷贝创建一个全新的对象,同时递归地复制所有嵌套对象及其属性。这样,新对象和原始对象完全独立,不会共享任何引用类型属性。

2.1、重写clone方法来实现深拷贝

public class DeepClonableTarget implements Serializable, Cloneable {

    private String cloneName;
    private String cloneClass;

    public DeepClonableTarget(String cloneName, String cloneClass) {
        this.cloneName = cloneName;
        this.cloneClass = cloneClass;
    }

    public String getCloneName() {
        return cloneName;
    }

    public void setCloneName(String cloneName) {
        this.cloneName = cloneName;
    }

    public String getCloneClass() {
        return cloneClass;
    }

    public void setCloneClass(String cloneClass) {
        this.cloneClass = cloneClass;
    }

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

public class DeepPrototype implements Serializable, Cloneable {
    private String name;
    private DeepClonableTarget deepClonableTarget;

    public DeepPrototype() {
    }

    public String getName() {
        return name;
    }

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

    public DeepClonableTarget getDeepClonableTarget() {
        return deepClonableTarget;
    }

    public void setDeepClonableTarget(DeepClonableTarget deepClonableTarget) {
        this.deepClonableTarget = deepClonableTarget;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        //基本数据类型拷贝
        Object object = super.clone();
        //引用类型拷贝
        DeepPrototype deepPrototype = (DeepPrototype) object;
        deepPrototype.deepClonableTarget = (DeepClonableTarget) deepClonableTarget.clone();
        return object;
    }
}

public class DeepTest {
    public static void main(String[] args) throws CloneNotSupportedException {
        DeepPrototype prototype = new DeepPrototype();
        prototype.setName("宋江");
        prototype.setDeepClonableTarget(new DeepClonableTarget("及时雨", "及时雨的类"));

        DeepPrototype clone1 = (DeepPrototype) prototype.clone();
        DeepPrototype clone2 = (DeepPrototype) prototype.clone();
        DeepPrototype clone3 = (DeepPrototype) prototype.clone();
        DeepPrototype clone4 = (DeepPrototype) prototype.clone();
        DeepPrototype clone5 = (DeepPrototype) prototype.clone();
        
        System.out.println(prototype.getName() + ", " + prototype.getDeepClonableTarget().hashCode()); // 宋江, 1554874502
        System.out.println(clone1.getName() + ", " + clone1.getDeepClonableTarget().hashCode()); // 宋江, 1846274136
        System.out.println(clone2.getName() + ", " + clone2.getDeepClonableTarget().hashCode()); // 宋江, 1639705018
        System.out.println(clone3.getName() + ", " + clone3.getDeepClonableTarget().hashCode()); // 宋江, 1627674070
        System.out.println(clone4.getName() + ", " + clone4.getDeepClonableTarget().hashCode()); // 宋江, 1360875712
        System.out.println(clone5.getName() + ", " + clone5.getDeepClonableTarget().hashCode()); // 宋江, 1625635731
    }
}

2.2、通过对象序列化实现深拷贝

 

public class DeepClonableTarget implements Serializable, Cloneable {
    private String cloneName;
    private String cloneClass;

    public DeepClonableTarget(String cloneName, String cloneClass) {
        this.cloneName = cloneName;
        this.cloneClass = cloneClass;
    }

    public String getCloneName() {
        return cloneName;
    }

    public void setCloneName(String cloneName) {
        this.cloneName = cloneName;
    }

    public String getCloneClass() {
        return cloneClass;
    }

    public void setCloneClass(String cloneClass) {
        this.cloneClass = cloneClass;
    }
}

public class DeepPrototype implements Serializable, Cloneable {
    private String name;
    private DeepClonableTarget deepClonableTarget;

    public DeepPrototype() {
    }

    public String getName() {
        return name;
    }

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

    public DeepClonableTarget getDeepClonableTarget() {
        return deepClonableTarget;
    }

    public void setDeepClonableTarget(DeepClonableTarget deepClonableTarget) {
        this.deepClonableTarget = deepClonableTarget;
    }

    public DeepPrototype deepClone() {
        ByteArrayOutputStream bos = null;
        ObjectOutputStream oos = null;
        ByteArrayInputStream bis = null;
        ObjectInputStream ois = null;
        try {
            // 序列化
            bos = new ByteArrayOutputStream();
            oos = new ObjectOutputStream(bos);
            oos.writeObject(this);
            // 反序列化
            bis = new ByteArrayInputStream(bos.toByteArray());
            ois = new ObjectInputStream(bis);
            return (DeepPrototype) ois.readObject();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            try {
                if (ois != null) {
                    ois.close();
                }
                if (bis != null) {
                    bis.close();
                }
                if (oos != null) {
                    oos.close();
                }
                if (bos != null) {
                    bos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

public class DeepTest {
    public static void main(String[] args) throws CloneNotSupportedException {
        DeepPrototype prototype = new DeepPrototype();
        prototype.setName("宋江");
        prototype.setDeepClonableTarget(new DeepClonableTarget("及时雨", "及时雨的类"));

        DeepPrototype clone1 = prototype.deepClone();
        DeepPrototype clone2 = prototype.deepClone();
        DeepPrototype clone3 = prototype.deepClone();
        DeepPrototype clone4 = prototype.deepClone();
        DeepPrototype clone5 = prototype.deepClone();

        System.out.println(prototype.getName() + ", " + prototype.getDeepClonableTarget().hashCode()); // 宋江, 644117698
        System.out.println(clone1.getName() + ", " + clone1.getDeepClonableTarget().hashCode()); // 宋江, 317574433
        System.out.println(clone2.getName() + ", " + clone2.getDeepClonableTarget().hashCode()); // 宋江, 885284298
        System.out.println(clone3.getName() + ", " + clone3.getDeepClonableTarget().hashCode()); // 宋江, 1389133897
        System.out.println(clone4.getName() + ", " + clone4.getDeepClonableTarget().hashCode()); // 宋江, 1534030866
        System.out.println(clone5.getName() + ", " + clone5.getDeepClonableTarget().hashCode()); // 宋江, 664223387
    }
}

2.3、方式 1 和方式 2 对比

● 在对象引用类型的成员属性较少时,方式 1 简单;在对象引用类型的成员属性较多时,方式 2 简单

● 在对象引用类型的成员属性经常发生变化时,方式 1 需要同步修改,方式 2 不用修改

● 推荐使用方式 2:耦合性低、可维护性强、扩展性高

 

四、原型模式应用场景

1、对象创建成本高昂

如果创建对象的过程很复杂或耗费资源,原型模式可以提高性能,通过复制已有对象来创建新对象。

2、动态配置

当需要根据运行时的配置创建对象时,原型模式可以用于在不修改代码的情况下创建新对象。

3、保护对象状态

如果对象的某些属性需要保护,不希望在外部进行修改,可以使用原型模式来创建新对象。

五、原型模式优点

1、简化对象创建

原型模式提供了一种简单的方式来复制对象,避免了重复的初始化过程。

2、减少资源消耗

原型模式避免了重复创建大量相似对象,减少了资源的消耗

3、保护对象

原型模式可以用于保护对象状态,防止外部修改敏感属性。

六、注意事项

1、深拷贝的复杂性

深拷贝可能会引入循环引用和递归复制的问题,需要谨慎处理。

2、克隆方法的实现

对象的克隆方法需要正确地复制所有属性,包括引用类型属性。

七、代码示例

abstract class Shape implements Cloneable {
    private String type;
    
    public String getType() {
        return type;
    }
    
    public void setType(String type) {
        this.type = type;
    }
    
    public abstract void draw();
    
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

class Circle extends Shape {
    public Circle() {
        setType("Circle");
    }
    
    @Override
    public void draw() {
        System.out.println("Drawing a Circle");
    }
}

class Rectangle extends Shape {
    public Rectangle() {
        setType("Rectangle");
    }
    
    @Override
    public void draw() {
        System.out.println("Drawing a Rectangle");
    }
}

八、总结

原型模式是一种有力的设计模式,它通过对象的复制和创建来提供更灵活和可扩展的方式。无论是浅拷贝还是深拷贝,原型模式都可以在需要复制对象的情况下发挥重要作用。

举报

相关推荐

0 条评论