设计模式(十五):原型模式

  早就发现java父类有个方法clone(),但一直没用过,也不知道怎么用。直到学习了原型设计模式才明白,他就是克隆方法,专门用来复制对象的。虽然到目前为止还没真正在项目中用到,但克隆方法还是挺有用的,它为我们创建相同对象带来了很大的便利,只要克隆一下就可以拥有一个全新的、初始值跟父类一样的对象。

一、概述

  原型模式(Prototype),用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。看这些翻译过来的解释确实好别扭,简单理解就是复制对象,得到全新对象,这个全新对象拥有了跟老对象一样的属性值和方法。

二、结构类图

 

三、应用实例

  没想到更通俗易懂的例子了,就用大话设计模式的例子讲解原型模式吧。大家求职面试都会用到简历,简历书写完毕就很少改动了,应聘不同的公司可以打印一样的简历,我们把打印简历的过程应用到代码层面就是原型模式了。

  1、定义简历抽象类

package com.jet.pattern.prototype;

import com.jet.pattern.prototype.impl.WorkExperience;

/**
 * description:
 * 定义简历抽象类(有成员变量和未实现的方法定义抽象类就好)
 * Created by Administrator on 2017/2/20.
 */
public abstract class Resume {
    // 名字
    private String name;
    // 性别
    private String sex;
    // 工作经历
    private WorkExperience workExperience ;
    // 未实现的克隆方法,抛出不支持克隆异常
    public abstract Resume Clone() throws CloneNotSupportedException;

    public String getName() {
        return name;
    }

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

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public WorkExperience getWorkExperience() {
        return workExperience;
    }

    public void setWorkExperience(WorkExperience workExperience) {
        this.workExperience = workExperience;
    }
}

  2、定义工作经历类

package com.jet.pattern.prototype.impl;

/**
 * description:
 * 工作经历类
 * Created by Administrator on 2017/2/20.
 */
public class WorkExperience {
    // 时间
    private String time;
    // 公司
    private String company;
    // 岗位
    private String position;

    public String getTime() {
        return time;
    }

    public void setTime(String time) {
        this.time = time;
    }

    public String getCompany() {
        return company;
    }

    public void setCompany(String company) {
        this.company = company;
    }

    public String getPosition() {
        return position;
    }

    public void setPosition(String position) {
        this.position = position;
    }
}

  3、实现简历类

package com.jet.pattern.prototype.impl;

import com.jet.pattern.prototype.Resume;

/**
 * description:
 * 我的简历实现类,需要实现java的Cloneable接口和自定义的Resume接口
 * Created by Administrator on 2017/2/20.
 */
public class MyResume  extends Resume implements Cloneable{
    // 实现克隆方法,直接用java父类自带的克隆方法
    @Override
    public Resume Clone() throws CloneNotSupportedException {
        return (Resume)this.clone();
    }
}

  4、测试类

package com.jet.pattern.prototype.test;

import com.jet.pattern.prototype.Resume;
import com.jet.pattern.prototype.impl.MyResume;
import com.jet.pattern.prototype.impl.WorkExperience;

/**
 * description:
 * 测试类
 * Created by Administrator on 2017/2/20.
 */
public class MyTest {
    public static void main(String[] args) throws CloneNotSupportedException {
        // 创建我的简历
        Resume resume = new MyResume();
        resume.setName("张晓明");
        resume.setSex("男");
        WorkExperience workExperience = new WorkExperience();
        workExperience.setTime("2014/08/10-2016/08/20");
        workExperience.setCompany("智信科技有限公司");
        workExperience.setPosition("JAVA开发工程师");
        resume.setWorkExperience(workExperience);

        // 克隆简历
        Resume resume1 = resume.Clone();

        // 打印简历
        System.out.println("----打印简历-----");
        System.out.println(resume1.getName());
        System.out.println(resume1.getSex());
        System.out.println(resume1.getWorkExperience().getTime() + " " +
                resume1.getWorkExperience().getCompany() + " " +
                resume1.getWorkExperience().getPosition());

    }
}

  5、测试结果

四、总结

  原型模式就是为我们创建相同对象带来便利的,只要有了一个原型对象,之后要创建对象就不用每次都new了,也不用给新创建的对象赋值了,直接调用克隆方法就可以拥有无数可用对象。上面例子中,只要在打印简历代码部分来个for循环,无穷无尽的对象就有了,哈哈。

  原型模式中有深度克隆和浅克隆,在浅克隆中需要考虑成员变量对象是否为原生对象(String,Integer等是原生对象),如果是非原生对象还需要层层克隆。而java父类的clone()方法是深度克隆的,我们在例子中也看到了,并没有层层克隆,所以浅克隆就不需过多了解了,java就是那么强大。

  其实在java中,自定义的类只要实现了java自带的Cloneable接口就可以被克隆了,并不需要我们自定义一个Clone()方法,本博文是为了讨论原型模式的原理才如此做,在现实项目中不用这般复杂。

 

posted @ 2017-02-20 22:02 jenkinschan 阅读(...) 评论(...) 编辑 收藏