Java 23种设计模式 之 原型模式

   日期:2020-09-29     浏览:97    评论:0    
核心提示:原型模式,以一个对象为原型进行复制(克隆)的设计模式,故引申出来深克隆与浅克隆知识。原型模式解决的问题举个例子:比如我们要抄袭某位博主的博客,博客包括 标题,正文,文末的引流链接我们有两个类原型 - Blog类public class Blog { String title = "被抄袭的博客标题"; String text = "被抄袭的博客正文"; ReferenceLink referenceLink = new ReferenceLink();//文末的引流.

原型模式,以一个对象为原型进行复制(克隆)的设计模式,故引申出来深克隆与浅克隆知识。

原型模式解决的问题

举个例子:比如我们要抄袭某位博主的博客,博客包括 标题,正文,文末的引流链接
我们有两个类

原型 - Blog类

public class Blog { 

    String title = "被抄袭的博客标题";
    String text = "被抄袭的博客正文";
    ReferenceLink referenceLink = new ReferenceLink();//文末的引流链接

    public Blog() { 
    }

    public Blog(String title, String text, ReferenceLink referenceLink) { 
        this.title = title;
        this.text = text;
        this.referenceLink = referenceLink;
    }

    public String getTitle() { 
        return title;
    }

    public String getText() { 
        return text;
    }

    public ReferenceLink getReferenceLink() { 
        return referenceLink;
    }
}
@Override
    public String toString() { 
        return "Blog{" +
                "title='" + title + '\'' +
                ", text='" + text + '\'' +
                ", referenceLink=" + referenceLink.QQ + referenceLink.str +
                '}';
    }

引流链接类

public class ReferenceLink { 

   String QQ = "qq466009264";
    String str = "来骚扰我呀";

    public String getQQ() { 
        return QQ;
    }

    public String getStr() { 
        return str;
    }

    public void setQQ(String QQ) { 
        this.QQ = QQ;
    }

    public void setStr(String str) { 
        this.str = str;
    }
}

现在开始抄袭了

		Blog yblog = new Blog();//原博客
        Blog cblog = new Blog(yblog.title,yblog.text,yblog.referenceLink);//将原博客抄袭
        System.out.println("原博客"+yblog);
        System.out.println("抄袭博客"+cblog);
        System.out.println(yblog.hashCode() == cblog.hashCode());


false表示不相等,抄袭成功
思考,这种方式的弊端。

  1. 太累了,不能一次性全部抄袭,要一步一步来,先标题,后正文等等。
  2. 硬编码,博客可能没有正文,只有引流链接,代码就要修改。

那么怎么解决这个问题呢?

利用object的方法,即object.clone。

  • 实现Cloneable
  • 调用clone方法
public class Blog implements Cloneable{ 

    String title = "被抄袭的博客标题";
    String text = "被抄袭的博客正文";
    ReferenceLink referenceLink = new ReferenceLink();

    public Blog() { 
    }

    public Blog(String title, String text, ReferenceLink referenceLink) { 
        this.title = title;
        this.text = text;
        this.referenceLink = referenceLink;
    }

    public String getTitle() { 
        return title;
    }

    public String getText() { 
        return text;
    }

    public ReferenceLink getReferenceLink() { 
        return referenceLink;
    }

    @Override
    public String toString() { 
        return "Blog{" +
                "title='" + title + '\'' +
                ", text='" + text + '\'' +
                ", referenceLink=" + referenceLink.QQ + referenceLink.str +
                '}';
    }

    public static void main(String[] args) throws CloneNotSupportedException { 

        Blog yblog = new Blog();//原博客
        Blog cblog = (Blog)yblog.clone();//将原博客抄袭
        System.out.println("原博客"+yblog);
        System.out.println("抄袭博客"+cblog);
        System.out.println(yblog.hashCode() == cblog.hashCode());
    }
}


结果似乎表明也抄袭成功了。

当抄袭者怕被发现将原博客升级

我们再次运行输出结果

观察可知,其实只是克隆了其基本数据类型,引用数据类型并没有完全克隆,引用数据类型克隆的是引用地址,也就是说当副本改变引用数据类型时,原型也同步改变。

数据类型

深克隆与浅克隆

深克隆: 克隆包括引用类型,开辟新空间,将值填进去
浅克隆: 克隆不包括引用类型,复制的是引用类型的地址

深克隆

ReferenceLink 类

import java.io.Serializable;

public class ReferenceLink implements Cloneable, Serializable { 

    String QQ = "qq466009264";
    String str = "来骚扰我呀";

    public String getQQ() { 
        return QQ;
    }

    public String getStr() { 
        return str;
    }

    public void setQQ(String QQ) { 
        this.QQ = QQ;
    }

    public void setStr(String str) { 
        this.str = str;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException { 
        return super.clone();
    }
}

Blog 类

ublic class Blog implements Cloneable{ 

    String title = "被抄袭的博客标题";
    String text = "被抄袭的博客正文";
    ReferenceLink referenceLink = new ReferenceLink();



    public Blog() { 
    }

    public Blog(String title, String text, ReferenceLink referenceLink) { 
        this.title = title;
        this.text = text;
        this.referenceLink = referenceLink;
    }

    public void setTitle(String title) { 
        this.title = title;
    }

    public void setText(String text) { 
        this.text = text;
    }

    public void setReferenceLink(ReferenceLink referenceLink) { 
        this.referenceLink = referenceLink;
    }

    public String getTitle() { 
        return title;
    }

    public String getText() { 
        return text;
    }

    public ReferenceLink getReferenceLink() { 
        return referenceLink;
    }
    @Override
    protected Object clone() throws CloneNotSupportedException { 
        Blog blog ;
        blog = (Blog) super.clone();

        blog.referenceLink = (ReferenceLink) referenceLink.clone();
        return blog;
    }

    @Override
    public String toString() { 
        return "Blog{" +
                "title='" + title + '\'' +
                ", text='" + text + '\'' +
                ", referenceLink=" + referenceLink.QQ + referenceLink.str +
                '}';
    }

    public static void main(String[] args) throws CloneNotSupportedException { 
        Blog yblog = new Blog();//原博客
        Blog cblog = (Blog)yblog.clone();//将原博客抄袭
        cblog.setTitle("升级版被抄袭的博客标题");
        cblog.setText("升级版被抄袭的博客正文");
        cblog.referenceLink.setQQ("抄袭者的qq");
        cblog.referenceLink.setStr("别来烦我哦");
        System.out.println("原博客"+yblog);
        System.out.println("抄袭博客"+cblog);
        System.out.println(yblog.hashCode() == cblog.hashCode());

    }
}

看结果抄袭完全成功

方式一:分别对引用类型赋值克隆
方式二:序列化和反序列化

 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服