美文网首页
设计模式:6-原型模式:Prototype

设计模式:6-原型模式:Prototype

作者: 大栗几 | 来源:发表于2020-05-21 13:00 被阅读0次

文章来源本人的博客:http://codelifeliwan.github.io/ 转载请注明出处
查看[设计模式]系列内容请点击:https://www.jianshu.com/nb/45937362

定义:(Prototype)

用原型实例制定创建对象的种类,并且通过复制这些原型对象创建新的对象

理解:

就是根据一个对象复制出来另一个对象

方法:

在Object类中有一个clone()方法,但是是protected的,可以选择覆写Object类中的clone()方法,不使用Object的clone()方法,如果需要使用Object的clone()方法则必须实现Cloneable接口。

实现Cloneable接口并覆写Object的clone()方法,在覆写的方法中调用super.clone()复制,需要注意的是,Object中的clone()是按位复制,就是复制的是完全一样的对象。

代码说明:

package com.codelifeliwan.prototype1;
 
public class ClassA {
    private int a;
 
    public int getA() {
        return a;
    }
 
    public void setA(int a) {
        this.a = a;
    }
 
    @Override
    public ClassA clone() {
        ClassA a = new ClassA(); // 自己创建对象
        a.setA(this.getA()); // 设置对象参数
        return a;
    }
}
 
 
package com.codelifeliwan.prototype1;
 
public class ClassB implements Cloneable{
    private int a;
 
    public int getA() {
        return a;
    }
 
    public void setA(int a) {
        this.a = a;
    }
 
    @Override
    public ClassB clone() {
        try {
            // 在没有实现Cloneable接口的情况下调用super.clone()会造成异常
            return (ClassB) super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return null;
    }
}
 
 
package com.codelifeliwan.prototype1;
 
public class Main {
    public static void main(String args[]) {
        ClassA a1 = new ClassA();
        a1.setA(10);
        ClassA a2 = a1.clone();
 
        System.out.println("a1:" + a1.getA());
        System.out.println("a2:" + a2.getA());
 
        a2.setA(20);
        System.out.println("a1:" + a1.getA());
        System.out.println("a2:" + a2.getA());
 
        System.out.println("\n==============美丽的分割线=================\n");
 
        ClassB b1 = new ClassB();
        b1.setA(10);
        // System.out.println(b1.clone().toString());
        ClassB b2 = b1.clone();
 
        System.out.println("b1:" + b1.getA());
        System.out.println("b2:" + b2.getA());
 
        b2.setA(20);
        System.out.println("b1:" + b1.getA());
        System.out.println("b2:" + b2.getA());
    }
}
package com.codelifeliwan.prototype2;
 
public interface IClassA extends Cloneable {
}
 
 
package com.codelifeliwan.prototype2;
 
public class ClassA implements IClassA {
    private String str1;
    private String str2;
 
    public String getStr1() {
        return str1;
    }
 
    public void setStr1(String str1) {
        this.str1 = str1;
    }
 
    public String getStr2() {
        return str2;
    }
 
    public void setStr2(String str2) {
        this.str2 = str2;
    }
 
    public ClassA clone() {
        ClassA a = null;
        try {
            a = (ClassA) super.clone();
            a.setStr1("jascgudc");
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return a;
    }
}
 
 
package com.codelifeliwan.prototype2;
 
public class Client {
    public static void main(String args[]) {
        ClassA a1 = new ClassA();
        a1.setStr1("hello");
        a1.setStr2("world");
 
        ClassA a2 = a1.clone();
 
        System.out.println("a1:" + a1.getStr1() + " " + a1.getStr2());
        System.out.println("a2:" + a2.getStr1() + " " + a2.getStr2());
 
        System.out.println("\n=================美丽的分割线=============\n");
 
        a2.setStr2("wanli");
        System.out.println("a1:" + a1.getStr1() + " " + a1.getStr2());
        System.out.println("a2:" + a2.getStr1() + " " + a2.getStr2());
    }
}

适用场景:

  • 性能和安全要求场景:通过new一个对象需要繁琐的数据准备或者访问权限等,可以直接克隆一个对象
  • 资源优化场景:对象初始化的时候需要消耗非常多的资源,可以考虑直接克隆一个对象
  • 一个对象有多个修改者场景:一个对象可能有多个访问者访问,且访问者可能修改对象,则可以为每个访问者克隆一个对象

在Spring框架中,我们使用@Repository注解等方式默认是单例模式,只创建一个对象全局共用,但是可以加上@Scope(“prototype”)使其为原型模式,每次使用都会创建新的实例

相关文章

网友评论

      本文标题:设计模式:6-原型模式:Prototype

      本文链接:https://www.haomeiwen.com/subject/mmezohtx.html