设计模式-原型模式

Posted by YaPi on May 10, 2018

基础定义

  • 指原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象
  • 不需要知道任何创建的细节,不调用构造函数
  • 类型:创建型
  • 可以通过克隆的方式破坏单例模式

使用场景

  1. 类初始化消耗较多资源
  2. new产生的一个对象需要非常繁琐的过程
  3. 构造函数比较复杂
  4. 循环体中产生大量对象

优点:

  1. 简化过程

缺点:

  1. 必须配置克隆方法(重写Object的clone方法)
  2. 对克隆复杂对象进行改造时,容易引入风险

克隆程度:

  1. 深克隆
  2. 浅克隆

在实体有另外的引用属性的时候,需要注意复写该属性的clone方法,不然克隆出来的实体是浅克隆的,所有的属性都是一个对象,对其中一个做修改的时候,其他的也会变

源码实例
  1. ArrayList 的 Clone方法
  2. HashMap 的 Clone方法
  3. jdk中找实现类CloneAble接口的就是
  4. redission、mybatis等等里面都有实现
代码实例
public class Mail implements Cloneable{
    private String name;
    private String emailAddress;
    private String content;
    public Mail(){
        System.out.println("Mail Class Constructor");
    }
    public String getName() {
        return name;
    }

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

    public String getEmailAddress() {
        return emailAddress;
    }

    public void setEmailAddress(String emailAddress) {
        this.emailAddress = emailAddress;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        // 这样是浅克隆方法
        System.out.println("克隆方法");
        return super.clone();
    }
}


public class MailUtil {
    public static void sendMail(Mail mail){
        String outputContent = "向{0}同学,邮件地址{1},邮件内容{2}发送邮件";

        System.out.println(MessageFormat.format(outputContent,mail.getContent(),mail.getEmailAddress(),mail.getEmailAddress()));
    }

    public static void saveOriginMailRecord(Mail mail){
        System.out.println("存储记录:"+mail.getContent());
    }
}

// 使用
public class Test {
    public static void main(String[] args) throws CloneNotSupportedException {
//        Mail mail = new Mail();
//        mail.setContent("初始化");
//
//        for (int i=0;i < 10; i++){
//            mail.setName("姓名:"+i);
//            mail.setEmailAddress(i+"@imooc");
//            mail.setContent("你中奖了");
//            MailUtil.sendMail(mail);
//        }
//        MailUtil.saveOriginMailRecord(mail);

        Mail mail = new Mail();
        mail.setContent("初始化");

        for (int i=0;i < 10; i++){
            // 克隆的时候不调用构造器
            Mail mail1 = (Mail) mail.clone();
            mail1.setName("姓名:"+i);
            mail1.setEmailAddress(i+"@imooc");
            mail1.setContent("你中奖了");
            MailUtil.sendMail(mail1);
        }
        MailUtil.saveOriginMailRecord(mail);
    }

}

克隆问题

public class Pig implements Cloneable {
    private String name;
    private Date birthDay;

    public String getName() {
        return name;
    }

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

    public Date getBirthDay() {
        return birthDay;
    }

    public void setBirthDay(Date birthDay) {
        this.birthDay = birthDay;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        Pig pig = (Pig) super.clone();
        // 深克隆
        pig.birthDay = (Date) pig.birthDay.clone();
        return pig;
    }
}