裴大头-秦可爱

裴大头-秦可爱

Java 23种设计模式——原型模式(Prototype)

发表于 2023-11-03
裴大头
阅读量 450
更新于 2023-11-03

原型模式(Prototype)

一、问题

在某些情况下,需要创建对象的副本,但复制一个对象的成本可能很高,或者希望避免与对象的具体类耦合。例如,当创建对象的过程较为复杂,或者对象包含大量共享的状态时,使用常规的创建方法可能会导致性能下降。

二、解决方案

原型模式的解决方案是通过复制现有对象来创建新对象,而不是从头开始构建。这允许我们以更高效的方式创建新对象,同时避免了与对象类的直接耦合。核心概念是在原型对象的基础上进行克隆,使得新对象具有与原型相同的初始状态。 在原型模式中,通常会有以下几个角色:

  • 抽象原型(Prototype):声明克隆方法,作为所有具体原型的基类或接口。
  • 具体原型(Concrete Prototype):实现克隆方法,从自身创建一个副本。
  • 客户端(Client):使用原型对象的客户端代码,在需要新对象时通过克隆现有对象来创建新实例。

三、效果

原型模式的应用可以带来以下效果:

  • 减少对象创建的成本:避免了复杂对象的重复初始化过程,提高了创建对象的效率。
  • 避免与具体类耦合:客户端可以通过克隆方法创建新对象,而无需知道具体类的细节,降低了耦合度。
  • 灵活性增加:可以在运行时动态地添加或删除原型,适应不同的对象创建需求。
  • 支持动态配置:可以通过克隆来定制对象的不同配置,而无需修改其代码。

然而,也需要注意一些限制,如:

  • 深克隆问题:原型模式默认进行浅克隆,即复制对象本身和其引用。如果对象内部包含其他对象的引用,可能需要实现深克隆来复制整个对象结构。
  • 克隆方法的实现:某些对象可能不容易进行克隆,特别是涉及到文件、网络连接等资源的情况。

总之,原型模式是一种在需要创建对象副本时非常有用的设计模式,它提供了一种灵活且高效的方法来处理对象的复制需求。

四、代码

image.png

1.Person.java

/**
 * Person
 *
 * @author 裴浩宇
 * @version 1.0
 * @date 2023/11/3 17:13
 * @description 人
 */
public class Person implements Cloneable{
    // 姓名
    private String name;
    // 年龄
    private Integer age;
    // 住址
    private Address address;

    @Override
    public Person clone() {
        Person clone = null;
        try {
            clone = (Person) super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return clone;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", address=" + address +
                '}';
    }

    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }
}
java

2.Address.java

/**
 * Address
 *
 * @author 裴浩宇
 * @version 1.0
 * @date 2023/11/3 17:14
 * @description 地址
 */
public class Address {
    // 省
    private String province;
    // 市
    private String city;
    // 区
    private String area;

    @Override
    public String toString() {
        return "Address{" +
                "province='" + province + '\'' +
                ", city='" + city + '\'' +
                ", area='" + area + '\'' +
                '}';
    }

    public String getProvince() {
        return province;
    }

    public void setProvince(String province) {
        this.province = province;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public String getArea() {
        return area;
    }

    public void setArea(String area) {
        this.area = area;
    }
}
java

3.Main.java

/**
 * Main
 *
 * @author 裴浩宇
 * @version 1.0
 * @date 2023/11/3 17:18
 * @description 客户端
 */
public class Main {

    public static void main(String[] args) {
        Person p = new Person();
        p.setName("Pei你看雪");
        p.setAge(18);
        Address address = new Address();
        address.setProvince("山东省");
        address.setCity("济南市");
        address.setArea("历区城");
        p.setAddress(address);
        Person q = p;
        Person z = p.clone();
        p.setAge(19);
        p.getAddress().setArea("高新区");
        System.out.println("q" + q);
        System.out.println("z" + z.toString());
    }
}
java

4.打印结果

image.png

从输出结果可以看到,使用 = 赋值方式创建对象时,两个对象共享相同的引用类型字段;而使用原型模式创建对象时,新对象是独立于原对象的,不会共享引用类型字段。 因此,在需要创建新对象并避免共享引用类型字段的情况下,建议使用原型模式。 当然,对于对象中的引用类型字段,只会复制引用,新对象与原对象将共享同一个引用类型对象。

源码

源码下载

Java 23种设计模式(含源码)

评论
来发一针见血的评论吧!
表情
  • 裴大头

    男博主

    IP:济南市

    2023-11-06 09:41

    以下是几种场景可以使用原型模式:

    1.对象的创建成本较高
    如果一个对象的创建成本非常高昂,比如需要进行大量的数据库查询或网络请求,那么我们可以使用原型模式来复制一个已有的对象,避免重复创建对象并提高系统性能。

    2.对象需要频繁创建和销毁
    当一个对象需要频繁地创建和销毁时,使用原型模式可以避免频繁的对象创建和销毁操作,提高系统性能和效率。

    3.避免构造函数复杂化
    如果某个类的构造函数非常复杂,很难直接进行创建,此时可以使用原型模式,通过克隆已有的对象来创建新的对象,避免构造函数的复杂化。

    4.保留对象的状态
    在某些情况下,我们需要保留一个对象的状态,并在后续操作中对其进行修改和使用。这时,我们可以使用原型模式来复制一个对象,在后续操作中对其进行修改和使用,而不会影响原有对象的状态。例如,在游戏开发中,我们可以使用原型模式来保留游戏角色的状态。

    总之,当我们需要创建新对象,并且创建成本较高、需要频繁创建和销毁、构造函数复杂或需要保留对象状态等时,可以考虑使用原型模式。但需要注意的是,如果对象的复制过程涉及到深拷贝和浅拷贝,需要特别注意其实现方式及影响。

    0
    回复
      共0条回复,点击查看
推荐文章
  • Vue项目代码规范

    1点赞1评论

  • JavaScript 的事件循环机制

    1点赞1评论

  • 聊一聊我的文本编辑器

    1点赞11评论

  • JavaScript的常用遍历方法整理

    1点赞8评论

  • 前端面试精选-基础篇

    1点赞0评论

Crafted with by Pei你看雪

小破站居然运行了 865 天访客 23357

© 2023 Pei你看雪鲁ICP备19037910号-2