java设计模式之原型模式

一、原型模式的定义
原型模式:用原型实例指定建立对象的种类,并经过拷贝这些原型建立新的对象。
原型模式的核心是一个clone方法,被拷贝对象须要实现cloneable接口并重写clone()方法。数据库

二、代码示例数组

 

 

/**
 * 广告信模板代码
 *
 */
public class AdvTemplate {
    
    //广告信名称
    private String advSubject = "XX银行国庆信用卡抽奖活动";
    //广告信内容
    private String advContext = "国庆抽奖活动通知: 只要刷卡就送你一百万! ...";
    //取得广告信的名称
    public String getAdvSubject(){
        return this.advSubject;
    }
    //取得广告信的内容
    public String getAdvContext(){
        return this.advContext;
    }
}
/**
 * 邮件类代码
 *
 */
public class Mail implements Cloneable {

    //收件人
    private String receiver;
    //邮件名称
    private String subject;
    //称谓
    private String appellation;
    //邮件内容
    private String contxt;
    //邮件的尾部, 通常都是加上"XXX版权全部"等信息
    private String tail;
    //构造函数
    public Mail(AdvTemplate advTemplate){
        this.contxt = advTemplate.getAdvContext();
        this.subject = advTemplate.getAdvSubject();
    }
    
    @Override
    protected Mail clone() {
        Mail mail = null;
        try {
            mail = (Mail) super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return mail;
    }

    public String getReceiver() {
        return receiver;
    }
    public void setReceiver(String receiver) {
        this.receiver = receiver;
    }
    public String getSubject() {
        return subject;
    }
    public void setSubject(String subject) {
        this.subject = subject;
    }
    public String getAppellation() {
        return appellation;
    }
    public void setAppellation(String appellation) {
        this.appellation = appellation;
    }
    public String getContxt() {
        return contxt;
    }
    public void setContxt(String contxt) {
        this.contxt = contxt;
    }
    public String getTail() {
        return tail;
    }
    public void setTail(String tail) {
        this.tail = tail;
    }
}
/**
 * 场景类
 *
 */
public class Client {

    //发送帐单的数量, 这个值是从数据库中得到
    private static int MAX_COUNT = 6;
    public static void main(String[] args) {
        //模拟发送邮件
        int i=0;
        //把模板定义出来, 这个是从数据库中得到
        Mail mail = new Mail(new AdvTemplate());
        mail.setTail("XX银行版权全部");
        while(i < MAX_COUNT){
            //如下是每封邮件不一样的地方
            /*mail.setAppellation(getRandString(5) + " 先生( 女士) ");
            mail.setReceiver(getRandString(5) + "@" + getRandString(8) + ".com");*/
            Mail cloneMail = mail.clone();
            cloneMail.setAppellation(getRandString(5) + " 先生( 女士) ");
            cloneMail.setReceiver(getRandString(5) + "@" + getRandString(8) + ".com");
            //而后发送邮件
            sendMail(cloneMail);
            i++;
        }
    }
    //发送邮件
    public static void sendMail(Mail mail){
        System.out.println("标题: " + mail.getSubject() + "\t收件人:" + 
                mail.getReceiver() + "\t...发送成功! ");
    }
    //得到指定长度的随机字符串
    public static String getRandString(int maxLength){
        String source ="abcdefghijklmnopqrskuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
        StringBuffer sb = new StringBuffer();
        Random rand = new Random();
        for(int i = 0; i < maxLength; i++){
            sb.append(source.charAt(rand.nextInt(source.length())));
        }
        return sb.toString();
    }
}

三、原型模式优势安全

性能优良
原型模式是在内存二进制流的拷贝,要比直接new一个对象性能好不少,特别是要在一个循环体内产生大量的对象时,原型模式能够更好地体现其优势。
逃避构造函数的约束
这既是它的优势也是缺点,直接在内存中拷贝,构造函数是不会执行的。优势就是减小了约束,缺点也是减小了约束,须要你们在实际应用时考虑。
四、原型模式的使用场景
资源优化场景
类初始化须要消化很是多的资源,这个资源包括数据、硬件资源等。
性能和安全要求的场景
经过new产生一个对象须要很是繁琐的数据准备或访问权限,则可使用原型模式。
一个对象多个修改者的场景
一个对象须要提供给其余对象访问,并且各个调用者可能都须要修改其值时,能够考虑使用原型模式拷贝多个对象供调用者使用。
在实际项目中,原型模式不多单独出现,通常是和工厂方法模式一块儿出现,经过clone的方法建立一个对象,而后由工厂方法提供给调用者。
五、原型模式的注意事项
构造函数不会被执行
执行clone()方法时,原型对象的构造函数不会被执行。
浅拷贝和深拷贝
浅拷贝:clone()方法只拷贝对象自己,对象内部的数组、引用对象等都不拷贝(基本类型和string类型会被拷贝),仍是指向原生对象的内部元素地址。
深拷贝:原生对象全部内容全拷贝,互不影响。
clone与final两个冤家
要使用clone方法, 类的成员变量上不要增长final关键字。app

相关文章
相关标签/搜索