My logo
Published on

prototype 原型模式

原型模式

顾名思义,其实说白了,就是让一个对象可以自己拷贝自己,对象把自己当成一个原型,然后提供一个方法出去,外部要一个对象的克隆和拷贝,直接就copy一份就可以了,但是这里要记住深拷贝和浅拷贝的区别。

因为一个对象可能还持有别的对象的引用,浅拷贝就是不管引用的其他对象了;深拷贝就是将引用的对象也一起拷贝一份;一般原型模式都是要支持深拷贝的。且其实一般实现原型模式的时候,直接是通过覆盖Object类的clone()方法即可,在里面实现自己的拷贝逻辑就可以了。

使用原型模式比较好的一点,就是如果别人要拷贝你的对象,不需要调用方自己实现拷贝逻辑,将拷贝逻辑放在对象自己身体里就可以了,对外面调用都是透明的。

这个模式其实在我们的电商系统中,完全有场景可以使用,可以想象一下,比如我们的这个订单、发货单、销售出库单、财务结算单,这些单子之间,可能就是有大量的属性是要互相拷贝的。我们手上有一个订单之后,想将订单中的数据拷贝到一个发货单中,将发货单中的属性拷贝到一个销售出库单中,再将销售出库单中的属性拷贝到财务结算单中。

这种大量的属性拷贝的业务场景,我们就可以对原型模式进行改造,我们可以实现一个适合自己系统的通用的对象属性拷贝工具类,然后对那些需要互相之间支持属性拷贝的类,我们可以重写其clone()方法,这个我们后面再讲解,发货单的clone()方法,调用之后,克隆出来的是一个销售出库单。

一般模式

package wang.jinggo.basics.zhss.prototype;

/**
 * @author: wangyj
 * @create: 2021-10-22
 * @version: 1.0.0
 **/
public class WithoutPrototypePatternDemo {

    public static void main(String[] args) {
        // 手头有这么一个对象,需要进行拷贝
        Product product = new Product("测试产品", new Component("测试组件"));
        // 手动来拷贝
        Product copyProduct = new Product(product.getName(), product.getComponent());
        System.out.println(copyProduct);

        // 问题是什么?
        // 代码的拷贝逻辑,是每个要拷贝的调用方自己来实现的
        // 相同的拷贝逻辑会分散在很多不同的地方,如果拷贝逻辑改变了,多个调用的地方都要修改代码
        // 可维护性、可扩展性,很差
    }

    public static class  Component {

        private String name;

        public Component(String name) {
            super();
            this.name = name;
        }

        public String getName() {
            return name;
        }

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

        @Override
        public String toString() {
            return "Component [name=" + name + "]";
        }

    }

    public static class Product {

        private String name;
        private Component component;

        public Product(String name, Component component) {
            super();
            this.name = name;
            this.component = component;
        }

        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public Component getComponent() {
            return component;
        }
        public void setComponent(Component component) {
            this.component = component;
        }

        @Override
        public String toString() {
            return "Product [name=" + name + ", component=" + component + "]";
        }

    }
}

设计模式

package wang.jinggo.basics.zhss.prototype;

/**
 * @author: wangyj
 * @create: 2021-10-22
 * @version: 1.0.0
 **/
public class PrototypePatternDemo {

    public static void main(String[] args) {
        try {
            Product product = new Product("测试产品", new Component("测试组件"));
            Product copyProduct = (Product) product.clone();
            System.out.println(copyProduct);
        } catch (Exception e) {
            e.printStackTrace();
        }

        // 原型模式,就是在要拷贝的类里实现一个clone()方法,自己拷贝自己
        // 拷贝的时候,就两个概念,浅拷贝,深拷贝

        // 很多地方要克隆这个对象,不要自己维护克隆的逻辑,即使克隆逻辑修改了,只要在clone()方法里面修改
    }

    public static class  Component {

        private String name;

        public Component(String name) {
            super();
            this.name = name;
        }

        public String getName() {
            return name;
        }

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

        @Override
        public String toString() {
            return "Component [name=" + name + "]";
        }

        @Override
        protected Object clone() throws CloneNotSupportedException {
            return new Component(getName());
        }

    }

    public static class Product {

        private String name;
        private Component component;

        public Product(String name, Component component) {
            super();
            this.name = name;
            this.component = component;
        }

        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public Component getComponent() {
            return component;
        }
        public void setComponent(Component component) {
            this.component = component;
        }

        @Override
        public String toString() {
            return "Product [name=" + name + ", component=" + component + "]";
        }

        @Override
        protected Object clone() throws CloneNotSupportedException {
            // 浅拷贝,就是我们现在的一个实现
            // 就是仅仅简单的对当前所有的变量进行一个拷贝
//			return new Product(getName(), getComponent());

            // 深考别,递归对自己引用的对象也进行拷贝
            return new Product(getName(), (Component)getComponent().clone());
        }

    }
}