IDEA2023.1.3破解,IDEA破解,IDEA 2023.1破解,最新IDEA激活码

设计模式(一)-创建型之原型模式

IDEA2023.1.3破解,IDEA破解,IDEA 2023.1破解,最新IDEA激活码

定义

  • 指原型实例指定创建对象的种类,并且通过拷贝这些原型创建新对象
  • 不需要知道任何创建细节,不调用构造函数

适用场景

  • 创建对象麻烦或困难时。1.对象种类繁多,无法整合到一个类时 2.要创建一个类,初始化时需要使用较多资源。
  • 想解耦框架和生成实例时,生成的框架不依赖于具体的类。

优点

  • 创建过程简单
  • 原型模式性能比直接new一个对象性能高

缺点

  • 必须配备克隆方法
  • 对克隆复杂对象或对克隆出的对象进行复杂改造时,容易引入代码BUG
  • 必须清楚了解深拷贝与浅拷贝

原型模式中的角色

角色说明

  • Prototype(原型)
    • Product角色负责定义用于复制现有实例来生成新实例的方法。在实例程序中,由Cloneable接口来扮演此角色。
  • ConcreteProrotype(具体原型)
    • ConcretePrototype角色负责实现复制现有实例并生成新实例方法。在实例程序中,由User类扮演此角色。
  • Client(使用者)
    • Client角色负责使用复制实例的方法生成新的实例。在实例程序中,由单元测试类扮演此角色。

类图

79_1.png

代码实现

原型模式代码

写法一

1、用java实现原型模式比较简单,只需要将目标类实现Cloneable接口即可

@Getter
@Setter
@AllArgsConstructor
public class User implements Cloneable {
    private String name;
    private Date birthday;

    public User() {
        System.out.println("User constructor被调用");
    }

    @Override
    public Object clone() throws CloneNotSupportedException {
        System.out.println("User clone被调用");
        // 浅克隆写法
        return super.clone();
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", birthday=" + birthday +
                '}'+super.toString();
    }
}

写法二

1、 抽象父类实现Cloneable接口

public abstract class AbstractUser implements Cloneable {
    @Override
    protected Object clone() throws CloneNotSupportedException {
        System.out.println("抽象父类clone方法被调用");
        return super.clone();
    }
}

1、 目标类继承抽象父类接口

@Getter
@Setter
public class User extends AbstractUser {
    private String name;
    private Date birthday;

    public User() {
        System.out.println("User constructor被调用");
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", birthday=" + birthday +
                '}'+super.toString();
    }
}

单元测试(写法一)

测试代码

    @Test
    public void testClone() throws CloneNotSupportedException {
        Date birthday = new Date(0L);
        // 1. 创建用户对象
        User user1 = new User();
        user1.setName("小林");
        user1.setBirthday(birthday);

        // 2. 克隆用户对象
        User user2 = (User) user1.clone();
        // 3. user1,user2对比
        System.out.println(user1);
        System.out.println(user2);
        System.out.println(user1 == user2);

        System.out.println("<==============我是分割线============>");

        // 4. 赋值新的birthday并打印
        user1.getBirthday().setTime(666666666666L);
        System.out.println(user1);
        System.out.println(user2);
        System.out.println(user1 == user2);
    }

执行结果

根据user1和user2的hash值不同可以看出是不同的类,但user1的birthday修改后,user2的birthday也同样被修改,说明user1和user2指向了同一个birthday,这里就引发深拷贝与浅拷贝的问题。

79_2.png

深拷贝 VS 浅拷贝

使用clone(),之后,由于birthday是一个引用对象,由于是浅拷贝,user中的引用成员变量依然指向的是同一个。

79_3.png

什么是深拷贝,我们cloneuser对象的同时,也将其内部引用的对象进行拷贝,使得每个引用对象无关联,都是单独的对象。

79_4.png

深拷贝代码改造

重新改造user中clone()方法的实现

@Getter
@Setter
public class User implements Cloneable {
    private String name;
    private Date birthday;

    public User() {
        System.out.println("User constructor被调用");
    }

    @Override
    public Object clone() throws CloneNotSupportedException {
        System.out.println("User clone被调用");
        // 浅拷贝写法
        // return super.clone();

        // 深拷贝写法
        User user = (User) super.clone();
        user.birthday=(Date) user.getBirthday().clone();
        return user;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", birthday=" + birthday +
                '}'+super.toString();
    }
}

执行结果

可以看到改造完成之后user1的birthday与user2的birthday指向不是同一个birthday了。

79_5.png

总结

使用原型模式时要十分注意深拷贝、浅拷贝的问题,即使了解了深拷贝和浅拷贝,在写代码的过程中一个疏忽就可能产生BUG,如果对深拷贝和浅拷贝不了解同学,需要慎用原型模式。

文章永久链接:https://tech.souyunku.com/?p=26511


Warning: A non-numeric value encountered in /data/wangzhan/tech.souyunku.com.wp/wp-content/themes/dux/functions-theme.php on line 1154
赞(81) 打赏



未经允许不得转载:搜云库技术团队 » 设计模式(一)-创建型之原型模式

IDEA2023.1.3破解,IDEA破解,IDEA 2023.1破解,最新IDEA激活码
IDEA2023.1.3破解,IDEA破解,IDEA 2023.1破解,最新IDEA激活码

评论 抢沙发

大前端WP主题 更专业 更方便

联系我们联系我们

觉得文章有用就打赏一下文章作者

微信扫一扫打赏

微信扫一扫打赏


Fatal error: Uncaught Exception: Cache directory not writable. Comet Cache needs this directory please: `/data/wangzhan/tech.souyunku.com.wp/wp-content/cache/comet-cache/cache/https/tech-souyunku-com/index.q`. Set permissions to `755` or higher; `777` might be needed in some cases. in /data/wangzhan/tech.souyunku.com.wp/wp-content/plugins/comet-cache/src/includes/traits/Ac/ObUtils.php:367 Stack trace: #0 [internal function]: WebSharks\CometCache\Classes\AdvancedCache->outputBufferCallbackHandler() #1 /data/wangzhan/tech.souyunku.com.wp/wp-includes/functions.php(5109): ob_end_flush() #2 /data/wangzhan/tech.souyunku.com.wp/wp-includes/class-wp-hook.php(303): wp_ob_end_flush_all() #3 /data/wangzhan/tech.souyunku.com.wp/wp-includes/class-wp-hook.php(327): WP_Hook->apply_filters() #4 /data/wangzhan/tech.souyunku.com.wp/wp-includes/plugin.php(470): WP_Hook->do_action() #5 /data/wangzhan/tech.souyunku.com.wp/wp-includes/load.php(1097): do_action() #6 [internal function]: shutdown_action_hook() #7 {main} thrown in /data/wangzhan/tech.souyunku.com.wp/wp-content/plugins/comet-cache/src/includes/traits/Ac/ObUtils.php on line 367