漫画:什么是 “原型模式” ?

沙海 2021年7月12日06:17:45Java评论36字数 4440阅读14分48秒阅读模式
摘要

智能摘要

智能摘要文章源自JAVA秀-https://www.javaxiu.com/37496.html

小灰的原型被留在现实中,而三个复制体分别提供了吃得好、睡得好、玩得开心三种不同环境,小灰的原型则不受三个复制体的影响。Object类里的,Cloneable是一个标识接口,标识这个类的对象是可被拷贝的,如果没有实现Cloneable接口,却调用了clone()方法,就会报错。浅拷贝是在按位(bit)拷贝对象,这个对象有着原始对象属性值的一份精确拷贝。绝大多数设计模式都是牺牲性能提升开发效率的,原型模式则是为数不多的牺牲开发效率提升性能的设计模式。文章源自JAVA秀-https://www.javaxiu.com/37496.html

原文约 1367 | 图片 43 | 建议阅读 3 分钟 | 评价反馈文章源自JAVA秀-https://www.javaxiu.com/37496.html

漫画:什么是 “原型模式” ?

原创 东风玖哥,小灰 程序员小灰 文章源自JAVA秀-https://www.javaxiu.com/37496.html

收录于话题文章源自JAVA秀-https://www.javaxiu.com/37496.html

#设计模式4文章源自JAVA秀-https://www.javaxiu.com/37496.html

#Java3文章源自JAVA秀-https://www.javaxiu.com/37496.html

#程序员5文章源自JAVA秀-https://www.javaxiu.com/37496.html

#面向对象1文章源自JAVA秀-https://www.javaxiu.com/37496.html

漫画:什么是 “原型模式” ?文章源自JAVA秀-https://www.javaxiu.com/37496.html

漫画:什么是 “原型模式” ?文章源自JAVA秀-https://www.javaxiu.com/37496.html

—————  第二天  —————文章源自JAVA秀-https://www.javaxiu.com/37496.html

漫画:什么是 “原型模式” ?文章源自JAVA秀-https://www.javaxiu.com/37496.html

漫画:什么是 “原型模式” ?文章源自JAVA秀-https://www.javaxiu.com/37496.html

漫画:什么是 “原型模式” ?文章源自JAVA秀-https://www.javaxiu.com/37496.html

漫画:什么是 “原型模式” ?文章源自JAVA秀-https://www.javaxiu.com/37496.html

漫画:什么是 “原型模式” ?文章源自JAVA秀-https://www.javaxiu.com/37496.html

漫画:什么是 “原型模式” ?文章源自JAVA秀-https://www.javaxiu.com/37496.html

漫画:什么是 “原型模式” ?文章源自JAVA秀-https://www.javaxiu.com/37496.html

————————————文章源自JAVA秀-https://www.javaxiu.com/37496.html

漫画:什么是 “原型模式” ?文章源自JAVA秀-https://www.javaxiu.com/37496.html

漫画:什么是 “原型模式” ?文章源自JAVA秀-https://www.javaxiu.com/37496.html

漫画:什么是 “原型模式” ?文章源自JAVA秀-https://www.javaxiu.com/37496.html

漫画:什么是 “原型模式” ?文章源自JAVA秀-https://www.javaxiu.com/37496.html

漫画:什么是 “原型模式” ?文章源自JAVA秀-https://www.javaxiu.com/37496.html

漫画:什么是 “原型模式” ?文章源自JAVA秀-https://www.javaxiu.com/37496.html

漫画:什么是 “原型模式” ?文章源自JAVA秀-https://www.javaxiu.com/37496.html

假如有一天,小灰被外星人抓走了,外星人要拿小灰做实验,想了解小灰在吃得好、睡得好、玩得开心的场景下,与现实中小灰的生存状态有什么区别。文章源自JAVA秀-https://www.javaxiu.com/37496.html

于是,外星人克隆了几个一模一样的小灰:文章源自JAVA秀-https://www.javaxiu.com/37496.html

漫画:什么是 “原型模式” ?文章源自JAVA秀-https://www.javaxiu.com/37496.html

就这样,小灰的原型被留在现实中,而三个复制体分别提供了吃得好、睡得好、玩得开心三种不同环境,小灰的原型则不受三个复制体的影响。文章源自JAVA秀-https://www.javaxiu.com/37496.html

过了一段时间,我们来观察一下本体与分身的生存状态:文章源自JAVA秀-https://www.javaxiu.com/37496.html

漫画:什么是 “原型模式” ?文章源自JAVA秀-https://www.javaxiu.com/37496.html

文章源自JAVA秀-https://www.javaxiu.com/37496.html

漫画:什么是 “原型模式” ?文章源自JAVA秀-https://www.javaxiu.com/37496.html

漫画:什么是 “原型模式” ?文章源自JAVA秀-https://www.javaxiu.com/37496.html

漫画:什么是 “原型模式” ?文章源自JAVA秀-https://www.javaxiu.com/37496.html

漫画:什么是 “原型模式” ?文章源自JAVA秀-https://www.javaxiu.com/37496.html

漫画:什么是 “原型模式” ?文章源自JAVA秀-https://www.javaxiu.com/37496.html

Java语言中,Object类实现了Cloneable接口,个对象可以通过调Clone()方法生成对象,这就是原型模式的典型应用。文章源自JAVA秀-https://www.javaxiu.com/37496.html

但需要注意的是,clone()方法并不是Cloneable接口里的,而是Object类里的,Cloneable是一个标识接口,标识这个类的对象是可被拷贝的,如果没有实现Cloneable接口,却调用了clone()方法,就会报错。文章源自JAVA秀-https://www.javaxiu.com/37496.html

 文章源自JAVA秀-https://www.javaxiu.com/37496.html

// protected native Object clone() throws
 CloneNotSupportedException;protected Object clone() throws
CloneNotSupportedException {    if (!(this instanceof Cloneable)) {        throw new CloneNotSupportedException(
"Class " + getClass().getName() +
" doesn't implement Cloneable");    }    return internalClone();}// Native helper method for cloning.private native Object internalClone();

 文章源自JAVA秀-https://www.javaxiu.com/37496.html

漫画:什么是 “原型模式” ?文章源自JAVA秀-https://www.javaxiu.com/37496.html

 文章源自JAVA秀-https://www.javaxiu.com/37496.html

Java中的数据类型,分为基本类型和引用类型。在一个方法里的变量如果是基本类型的话,变量就直接存储在这个方法的栈帧里,例如int、long等;而引用类型则在栈帧里存储这个变量的指针,指向堆中该实体的地址,例如String、Array等。深拷贝和浅拷贝是只针对引用数据类型的。文章源自JAVA秀-https://www.javaxiu.com/37496.html

 文章源自JAVA秀-https://www.javaxiu.com/37496.html

比如一个方法有一个基本类型参数和一个引用类型参数,在方法体里对参数重新赋值,会影响传入的引用类型参数,而不会影响基本类型参数,因为基本类型参数是值传递,而引用类型参数是引用传递。文章源自JAVA秀-https://www.javaxiu.com/37496.html

先定义一个用户类:文章源自JAVA秀-https://www.javaxiu.com/37496.html

// 这是一个非常简单的用户类public class User {    private String name;    private int age;    public User(String name, int age) {        this.name=name;        this.age=age;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public int getAge() {        return age;    }    public void setAge(int age) {        this.age = age;    }    @Override    public String toString() {        return "User{name='" + name + ", age=" + age +'}';    }}

测试:文章源自JAVA秀-https://www.javaxiu.com/37496.html

private int x=10;public void updateValue(int value){    value = 3 * value;}private User user= new User("大黄",20);public void updateUser(User student){    student.setName("小灰");    student.setAge(18);}public void test(){    System.out.println("调用前x的值:"+x);    updateValue(x);    System.out.println("调用后x的值:"+x);    System.out.println("调用前user的值:"+user.toString());    updateUser(user);    System.out.println("调用后user的值:"+user.toString());}

Log打印结果如下:文章源自JAVA秀-https://www.javaxiu.com/37496.html

调用前x的值:10文章源自JAVA秀-https://www.javaxiu.com/37496.html

调用后x的值:10文章源自JAVA秀-https://www.javaxiu.com/37496.html

调用前user的值:User{name='大黄, age=20}文章源自JAVA秀-https://www.javaxiu.com/37496.html

调用后user的值:User{name='小灰, age=18}文章源自JAVA秀-https://www.javaxiu.com/37496.html

 文章源自JAVA秀-https://www.javaxiu.com/37496.html

传递基本类型的方法(updateValue())流程图:文章源自JAVA秀-https://www.javaxiu.com/37496.html

漫画:什么是 “原型模式” ?文章源自JAVA秀-https://www.javaxiu.com/37496.html

传递引用类型的方法(updateUser())流程图:文章源自JAVA秀-https://www.javaxiu.com/37496.html

漫画:什么是 “原型模式” ?文章源自JAVA秀-https://www.javaxiu.com/37496.html

文章源自JAVA秀-https://www.javaxiu.com/37496.html

这其中也包含着例外,比如String类型和大小不超过127的Long类型,虽然也是引用类型,却像基本类型一样不受影响。这是因为它们会先比较常量池维护的值,这涉及VM的内容,今天不做过多讨论。文章源自JAVA秀-https://www.javaxiu.com/37496.html

浅拷贝是在按位(bit)拷贝对象,这个对象有着原始对象属性值的一份精确拷贝。我们结合应用场景分析一下,还是刚才的User类,我们增加一个存放地址的内部类Address,我们需要用户信息可以被其他module查询,但是不允许它们被其他module修改,新增代码如下:文章源自JAVA秀-https://www.javaxiu.com/37496.html

// 这是一个稍微复杂的、支持拷贝的用户类public class User implements Cloneable {
// ……省略上文代码……    private Address address;    @NonNull    @NotNull    @Override    public User clone() {        try{            return (User)super.clone();        }catch (CloneNotSupportedException e) {            e.printStackTrace();        }        return null;    }    public class Address{        // 地市        public String city;        // 区县        public String county;        // 乡镇街道        public String street;    } }

 文章源自JAVA秀-https://www.javaxiu.com/37496.html

 文章源自JAVA秀-https://www.javaxiu.com/37496.html

 文章源自JAVA秀-https://www.javaxiu.com/37496.html

漫画:什么是 “原型模式” ?文章源自JAVA秀-https://www.javaxiu.com/37496.html

漫画:什么是 “原型模式” ?文章源自JAVA秀-https://www.javaxiu.com/37496.html

漫画:什么是 “原型模式” ?文章源自JAVA秀-https://www.javaxiu.com/37496.html

文章源自JAVA秀-https://www.javaxiu.com/37496.html

// 这是一个更复杂的、支持深拷贝的用户类public class User implements Cloneable {    // ……省略上文代码……    @NonNull    @NotNull    @Override    public User clone() {        try{            User newUser = (User)super.clone();            newUser.setName(this.name);            newUser.setAddress(this.address.clone());            return newUser;        }catch (CloneNotSupportedException e) {            e.printStackTrace();        }        return null;    }    public class Address implements Cloneable{        // ……省略上文代码……        @NonNull        @NotNull        @Override        public Address clone() {            try{                Address newAddress = (Address)super.clone();                newAddress.city = this.city;                newAddress.county = this.county;                newAddress.street = this.street;                return newAddress;            }catch (CloneNotSupportedException e) {                e.printStackTrace();            }            return null;        }    }}

需要注意的是,上面代码的深拷贝其实并不彻底,因为彻底的深拷贝几乎是不可能实现的,那样不但可能存在引用关系非常复杂的情况,也可能存在引用链的某一级上引用了一个没有实现Cloneable接口的第三方对象的情况。文章源自JAVA秀-https://www.javaxiu.com/37496.html

绝大多数设计模式都是牺牲性能提升开发效率的,原型模式则是为数不多的牺牲开发效率提升性能的设计模式。文章源自JAVA秀-https://www.javaxiu.com/37496.html

 文章源自JAVA秀-https://www.javaxiu.com/37496.html

漫画:什么是 “原型模式” ?文章源自JAVA秀-https://www.javaxiu.com/37496.html

文章源自JAVA秀-https://www.javaxiu.com/37496.html

漫画:什么是 “原型模式” ?文章源自JAVA秀-https://www.javaxiu.com/37496.html

漫画:什么是 “原型模式” ?文章源自JAVA秀-https://www.javaxiu.com/37496.html

漫画:什么是 “原型模式” ?文章源自JAVA秀-https://www.javaxiu.com/37496.html

漫画:什么是 “原型模式” ?文章源自JAVA秀-https://www.javaxiu.com/37496.html

文章源自JAVA秀-https://www.javaxiu.com/37496.html

漫画:什么是 “原型模式” ?文章源自JAVA秀-https://www.javaxiu.com/37496.html

文章源自JAVA秀-https://www.javaxiu.com/37496.html

private User user= new User("大黄",20);public void testNew(){    User user1 = new User("小灰",18);}public void testClone(){    User user2 = user.clone();}

 文章源自JAVA秀-https://www.javaxiu.com/37496.html

通过ASM工具查看bytecode,可以看出二者对栈资源的消耗:文章源自JAVA秀-https://www.javaxiu.com/37496.html

// access flags 0x1文章源自JAVA秀-https://www.javaxiu.com/37496.html

  public  testNew()V文章源自JAVA秀-https://www.javaxiu.com/37496.html

   ……省略……文章源自JAVA秀-https://www.javaxiu.com/37496.html

    MAXSTACK  = 4文章源自JAVA秀-https://www.javaxiu.com/37496.html

     MAXLOCALS = 2文章源自JAVA秀-https://www.javaxiu.com/37496.html

 文章源自JAVA秀-https://www.javaxiu.com/37496.html

  // access  flags 0x1文章源自JAVA秀-https://www.javaxiu.com/37496.html

  public  testClone()V文章源自JAVA秀-https://www.javaxiu.com/37496.html

   ……省略……文章源自JAVA秀-https://www.javaxiu.com/37496.html

    MAXSTACK  = 1文章源自JAVA秀-https://www.javaxiu.com/37496.html

     MAXLOCALS = 2文章源自JAVA秀-https://www.javaxiu.com/37496.html

文章源自JAVA秀-https://www.javaxiu.com/37496.html

漫画:什么是 “原型模式” ?文章源自JAVA秀-https://www.javaxiu.com/37496.html

文章源自JAVA秀-https://www.javaxiu.com/37496.html

@Overridepublic Object clone() {    return new Intent(this);}

漫画:什么是 “原型模式” ?文章源自JAVA秀-https://www.javaxiu.com/37496.html

漫画:什么是 “原型模式” ?文章源自JAVA秀-https://www.javaxiu.com/37496.html

最后我们来总结一下原型模式的核心用途:文章源自JAVA秀-https://www.javaxiu.com/37496.html

1.解决构建复杂对象的资源消耗问题,提升创建对象的效率。文章源自JAVA秀-https://www.javaxiu.com/37496.html

2.保护性拷贝,防止外部对只读对象进行需修改。文章源自JAVA秀-https://www.javaxiu.com/37496.html

漫画:什么是 “原型模式” ?文章源自JAVA秀-https://www.javaxiu.com/37496.html

漫画:什么是 “原型模式” ?文章源自JAVA秀-https://www.javaxiu.com/37496.html

文章源自JAVA秀-https://www.javaxiu.com/37496.html

漫画:什么是 “原型模式” ?文章源自JAVA秀-https://www.javaxiu.com/37496.html

文章源自JAVA秀-https://www.javaxiu.com/37496.html

漫画:什么是 “原型模式” ?文章源自JAVA秀-https://www.javaxiu.com/37496.html

漫画:什么是 “原型模式” ?文章源自JAVA秀-https://www.javaxiu.com/37496.html

文章源自JAVA秀-https://www.javaxiu.com/37496.html

文章已于修改 文章源自JAVA秀-https://www.javaxiu.com/37496.html

继续阅读
速蛙云 - 极致体验,强烈推荐!!!购买套餐就免费送各大视频网站会员!快速稳定、独家福利社、流媒体稳定解锁!速度快,全球上网、视频、游戏加速、独立IP均支持!基础套餐性价比很高!这里不多说,我一直正在使用,推荐购买:https://www.javaxiu.com/59919.html
weinxin
资源分享QQ群
本站是JAVA秀团队的技术分享社区, 会经常分享资源和教程; 分享的时代, 请别再沉默!
沙海
匿名

发表评论

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定