原型模式

89 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第28天,点击查看活动详情

本文系作者 不太自律的程序猿原创,转载请私信并在文章开头附带作者和原文地址链接。

建造者模式

建造者模式是设计模式的一种,将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

使用场景

1、资源优化场景。

2、类初始化需要消化非常多的资源,这个资源包括数据、硬件资源等。

3、性能和安全要求的场景。

4、通过 new 产生一个对象需要非常繁琐的数据准备或访问权限,则可以使用原型模式。

5、一个对象多个修改者的场景。

6、一个对象需要提供给其他对象访问,而且各个调用者可能都需要修改其值时,可以考虑使用原型模式拷贝多个对象供调用者使用。

7、在实际项目中,原型模式很少单独出现,一般是和工厂方法模式一起出现,通过 clone 的方法创建一个对象,然后由工厂方法提供给调用者。原型模式已经与 Java 融为浑然一体,大家可以随手拿来使用。

代码演示

原型类代码 重点是实现Cloneable接口以及重写clone方法


public class Prototype implements Cloneable, Serializable {
 
    private String name;
    private int age;
    private RefObject refObject;
 
    public Prototype(String name, int age) {
        this.name = name;
        this.age = age;
    }
 
    public RefObject getRefObject() {
        return refObject;
    }
 
    public void setRefObject(RefObject refObject) {
        this.refObject = refObject;
    }
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public int getAge() {
        return age;
    }
 
    public void setAge(int age) {
        this.age = age;
    }
 
    //重写克隆方法 默认浅拷贝
    @Override
    protected Object clone() throws CloneNotSupportedException {
        Prototype clone = (Prototype) super.clone();
        return clone;
    }
   
 
    @Override
    public String toString() {
        return "Prototype{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", refObject=" + refObject +
                '}';
    }
}

客户端 main方法 使用


 public static void main(String[] args) throws CloneNotSupportedException {
        Prototype prototype = new Prototype("原型模板",10);
        prototype.setRefObject(new RefObject());
        Prototype clone1 = (Prototype) prototype.clone();
        Prototype clone2 = (Prototype) prototype.clone();
        System.out.println(clone1);
        System.out.println(clone2);
        System.out.println("原型 hashCode"+prototype.getRefObject().hashCode());
        System.out.println("浅克隆  hashCode"+clone1.getRefObject().hashCode());
        System.out.println("浅克隆  hashCode"+clone2.getRefObject().hashCode());
        System.out.println(prototype.getRefObject()==clone1.getRefObject());
        System.out.println(prototype.getRefObject()==clone2.getRefObject());
    }
    

image.png 上面使用的是浅克隆模式,下面使用深克隆模式,修改Prototype的clone方法

 //深拷贝 利用反序列 和序列化
    @Override
    protected Object clone() {
        //序列化 将当前对象序列化到内存中
        ByteArrayOutputStream byteArrayOutputStream;
        ObjectOutputStream oos = null;
        ObjectInputStream ois = null;
        try {
            byteArrayOutputStream = new ByteArrayOutputStream();
            oos = new ObjectOutputStream(byteArrayOutputStream);
            oos.writeObject(this);
            //反序列化
            byte[] bytes = byteArrayOutputStream.toByteArray();
            ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
            ois = new ObjectInputStream(bis);
            return ois.readObject();
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        } finally {
            if (oos != null) {
                try {
                    oos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (ois != null) {
                try {
                    ois.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
 
        return null;
    }

image.png

优缺点

优点:

1、Prototype模式允许动态增加或减少产品类。由于创建产品类实例的方法是产批类内部具有的,因此增加新产品对整个结构没有影响。

2、Prototype模式提供了简化的创建结构。工厂方法模式常常需要有一个与产品类等级结构相同的等级结构,而Prototype模式就不需要这样。

3、Portotype模式具有给一个应用软件动态加载新功能的能力。由于Prototype的独立性较高,可以很容易动态加载新功能而不影响老系统。

4、产品类不需要非得有任何事先确定的等级结构,因为Prototype模式适用于任何的等级结构。

缺点:

每一个类必须配备一个克隆方法。而且这个克隆方法需要对类的功能进行通盘考虑,这对全新的类来说不是很难,但对已有的类进行改造时,不一定是件容易的事。

JDK源码中的应用:

1 org.springframework.web.servlet.mvc.method.RequestMappingInfo

2 org.springframework.beans.factory.support.BeanDefinitionBuilder

感谢诸君的观看,文中如有纰漏,欢迎在评论区来交流。如果这篇文章帮助到了你,欢迎点赞👍关注。