上一篇给大家分享了《设计模式之外观模式》,这篇文章接着给大家分享程序员常用设计模式之原型模型。

原型模型

  • 原型模式其实就是从一个对象基础上再创建另外一个可定制的对象,而且不需要知道任何创建的细节。

  • 原型模型可以大大提高效率。一般在初始化的信息不发生变化的情况下,克隆是最好的办法,即隐藏了创建对象的细节,又对性能有大大的提升。

  • 看代码就知道怎么回事了。以书写简历为例:

      
    public class Resume implements Cloneable{
    String name;
    String sex;
    String age;
    String timearea;
    String company;
    public Resume(String name) {
    super();
    this.name = name;
    }
    public Resume() {
    super();
    }
    //设置个人信息
    public void setPersonInfo(String sex,String age){
    this.sex = sex;
    this.age = age;
    }
    //设置个人信息
    public void setWorkExperience(String timearea,String company){
    this.timearea = timearea;
    this.company = company;
    }
    @Override
    public String toString() {
    return name + " " + sex + " " + age + "\n工作经历:" + timearea + " "
    + company;
    }
    public Object Clone() throws Exception{
    return this.clone();
    }
    }
    public class Test {
    public static void main(String[] args) throws Exception {
    Resume a = new Resume("大鸟");
    a.setPersonInfo("男", "20岁");
    a.setWorkExperience("2013-2017", "东北林业大学");
    Resume b = (Resume)a.Clone();
    b.setWorkExperience("2017-2022", "哈尔滨工业大学");
    Resume c = (Resume)a.Clone();
    c.setWorkExperience("2022-2030", "google");
    System.out.println(a);
    System.out.println(b);
    System.out.println(c);
    }
    }
  • 输出结果:

      大鸟  男  20岁
      工作经历:2013-2017   东北林业大学
      大鸟  男  20岁
      工作经历:2017-2020   哈尔滨工业大学
      大鸟  男  20岁
      工作经历:2020-2022   google
  • 注:上述代码是原型模型的浅复制,只能复制值类型的数据,对于引用类型的对象不能复制。

  • 如果将工作经历也单独做一个类,然后在resume类中应用工作经历,就会输出3条一模一样的结果。

  • 浅复制被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用都任指向原来的对象。

  • 将工作经历也单独做一个类的代码:

      
    public class WorkExperience {
    String timearea;
    String company;
    public String getTimearea() {
    return timearea;
    }
    public void setTimearea(String timearea) {
    this.timearea = timearea;
    }
    public String getCompany() {
    return company;
    }
    public void setCompany(String company) {
    this.company = company;
    }
    @Override
    public String toString() {
    return "\n工作经历" + timearea + " " + company;
    }
    }
    public class Resume implements Cloneable{
    String name;
    String sex;
    String age;
    WorkExperience work;
    public Resume(String name) {
    super();
    this.name = name;
    work = new WorkExperience();
    }
    public Resume() {
    super();
    }
    //设置个人信息
    public void setPersonInfo(String sex,String age){
    this.sex = sex;
    this.age = age;
    }
    public void setWorkExperience(String timearea,String company){
    work.timearea = timearea;
    work.company = company;
    }
    @Override
    public String toString() {
    return name + " " + sex + " " + age + work ;
    }
    public Object Clone() throws Exception{
    return this.clone();
    }

    }
  • 输出结果

      大鸟  男  20岁
      工作经历:2020-2022   google
      大鸟  男  20岁
      工作经历:2020-2022   google
      大鸟  男  20岁
      工作经历:2020-2022   google
  • 深复制:把引用对象的变量指向复制过的新对象,而不是原有的被引用的对象。

  • 二层深复制的代码:

      
    public class WorkExperience implements Cloneable{
    String timearea;
    String company;
    public String getTimearea() {
    return timearea;
    }
    public void setTimearea(String timearea) {
    this.timearea = timearea;
    }
    public String getCompany() {
    return company;
    }
    public void setCompany(String company) {
    this.company = company;
    }
    @Override
    public String toString() {
    return "\n工作经历" + timearea + " " + company;
    }
    public Object Clone() throws Exception{
    return this.clone();
    }
    }
    public class Resume implements Cloneable{
    String name;
    String sex;
    String age;
    WorkExperience work;
    public Resume(String name) {
    super();
    this.name = name;
    work = new WorkExperience();
    }
    public Resume() {
    super();
    }
    private Resume(WorkExperience work) throws Exception {
    super();
    this.work = (WorkExperience)work.Clone();
    }
    //设置个人信息
    public void setPersonInfo(String sex,String age){
    this.sex = sex;
    this.age = age;
    }
    public void setWorkExperience(String timearea,String company){
    work.timearea = timearea;
    work.company = company;
    }
    @Override
    public String toString() {
    return name + " " + sex + " " + age + work ;
    }
    public Object Clone() throws Exception{
    Resume obj = new Resume(this.work);
    obj.name = this.name;
    obj.age = this.age;
    obj.sex = this.sex;
    return obj;
    }
    }
  • 输出结果:

          大鸟  男  29岁
          工作经历2013-2017  东北林业大学
          大鸟  男  29岁
          工作经历2017-2020  腾讯
          大鸟  男  29岁
          工作经历2020-2022  google
  • 代码改动的地方:

    • 让WorkExperience类也实现了Cloneable的接口,并增加了clone()方法。
    • 在resume类中新增了一个私有的构造方法。
    • 修改了resume的clone()的方法。

往期精彩文章