设计模式之原型模式

什么是原型模式

原型模式是一种创建型模式,它允许通过复制现有对象来创建新对象,而无需从头开始创建全新的对象。这种模式在软件系统中应用很广泛,特别是在需要创建大量相似或相同对象的情况下。

这种模式的主要想法是,在某个类(称为"原型类")中定义一个方法,该方法用于创建并返回该类的另一个实例。这个新实例是原型的复制品,通过复制现有的对象来创建,而不是通过使用构造函数来创建新的对象。

原型模式的UML类图

原型对象

在原型模式中,通过复制这个原型对象来创建新的对象。这个原型对象可以是任何类型的对象,包括基本数据类型、自定义对象、集合等。

抽象原型

抽象原型角色定义了原型对象的通用接口和行为

具体原型

具体原型角色实现了抽象原型角色所定义的接口和行为,并提供了具体的实现细节。

在Java中,Cloneable接口是一个标记接口,用于指示一个对象可以被复制。它没有任何方法,只是一个标识符,用于指示实现Cloneable接口的类应该实现自己的复制方法。

要使一个对象可复制,需要实现clone()方法。该方法应该在类中定义为public和protected,并使用super.clone()调用超类的clone()方法来创建并返回一个新对象。新对象应该是原始对象的一个副本,包括所有字段和属性的副本。

原型模式的实际示例

机器狗这种玩意,其实在很早以前就被发明并制造出来了,小米科技也搞了一款,目前在官网上已经迭代到第二代了,你敢信这玩意居然卖到了12999元!可能有什么高科技在里面?

虽然这玩意能后空翻,但还是有点贵,这里咱们就用原型模式把价格打下来!

抽象产品类:Dog.java

java 复制代码
public interface Dog extends Cloneable {
    /**
     * 奔跑
     */
    void run();

    /**
     * 后空翻
     */
    void backflip();
}

具体产品类:RoboticDog.java

java 复制代码
public class RoboticDog implements Dog{

    private String name="铁蛋";

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

    @Override
    public void run() {
        System.out.println(this.name+"在奔跑");
    }

    @Override
    public void backflip() {
        System.out.println(this.name+"在表演后空翻");
    }
}

简单工厂类,用于批量生产机器狗这款产品,DamiFactory.java

java 复制代码
public class DaMiFactory {
    private Dog dog;

    public DaMiFactory(Dog dog) {
        this.dog = dog;
    }

    public Dog batchProduce(){
        if (dog != null&&dog instanceof RoboticDog) {
            try {
                return ((RoboticDog) dog).clone();
            } catch (CloneNotSupportedException e) {
                e.printStackTrace();
            }
        }
        return null;
    }
}

测试类

java 复制代码
public class Test
{
    public static void main(String[] args) {
        Dog roboticDog=new RoboticDog();
        DaMiFactory daMiFactory = new DaMiFactory(roboticDog);
        //开始批量生产
        for (int i = 0; i < 1000; i++) {
            System.out.println("第"+(i+1)+"只:");
            Dog dog = daMiFactory.batchProduce();
            dog.run();
            dog.backflip();
        }

    }
}

原型模式的应用场景

在以下场景中,可以考虑使用原型模式:

  1. 资源优化场景:当一个类初始化时需要消化大量资源,包括数据、硬件资源等,这时就可以使用原型模式来避免资源的浪费。
  2. 性能和安全要求的场景:如果通过"new"产生一个对象需要非常繁琐的数据准备或访问权限,那么可以使用原型模式来提高性能并增强安全性。
  3. 动态指定实例化类:当需要实例化的类在运行时刻动态指定时,可以使用原型模式。通过克隆原型来得到需要的实例,可以避免在运行时指定具体的类。
  4. 处理复杂对象:如果处理的对象比较简单,并且对象之间的区别很小,可能只是很固定的几个属性不同,那么使用原型模式更合适。例如生活中的彩虹的七彩颜色,只需要根据现有的一个颜色对象,克隆一个新的颜色对象,然后修改具体的颜色的值就可以满足要求。
  5. 多线程环境:在多线程环境中,由于线程之间共享数据可能会导致数据的不一致,这时可以使用原型模式。通过在原型对象上进行复制产生新的实例,可以避免线程之间的互相影响。
  6. 网络连接池:当需要频繁实例化并销毁对象时,如多线程的线程池、网络连接池等,使用原型模式可以避免频繁的创建和销毁对象,提高性能。

在实际项目中,原型模式通常会和工厂方法模式一起出现,由工厂方法模式通过"clone"方法创建对象,然后提供给调用者。

总结

总的来说,原型模式是一种非常实用的创建型模式,它可以在很多情况下提高代码的效率和复用性,在使用原型模式的时候需要特别注意使用场景。优点与缺点总是相对而言的,在某些场景下,原来的优点可能就变成缺点了,而在另外一些场景,缺点也有可能会变成优点,因此辩证的去理解,从实际出发做合理选择,这是根本目的。

优点

  1. 原型模式的主要优点是性能和资源利用率,由于对象是在已有实例的基础上创建的,因此不需要为每个新对象分配内存和计算资源,这可以提高应用程序的性能和资源利用率。
  2. 原型模式可以在运行时动态创建对象,无需在编译时确定对象的类型。
  3. 通过复制现有对象来创建新对象,可以避免重新编写相同的代码,提高代码的复用性。
  4. 由于新对象是通过复制现有对象来创建的,因此新对象与原对象具有相同的属性和行为,但它们是相互独立的,可以对其中一个进行修改而不会影响到另一个。

缺点

  1. 原型模式可能会导致内存占用增加,因为每次创建新对象时都需要复制原型对象。
  2. 如果原型对象的结构非常复杂,那么复制原型对象可能会变得非常耗时。
  3. 原型模式可能会违反单一责任原则,因为类可能需要同时实现其应用逻辑和原型创建逻辑。
  4. 由于对象是通过复制现有的实例来创建的,因此修改一个原型可能会影响到所有的副本。
  5. 由于所有的对象都是从一个原型创建的,因此所有的对象可能会有相同的属性和行为,这可能会限制应用程序的灵活性和可扩展性。
相关推荐
声声codeGrandMaster1 小时前
Django之modelform使用
后端·python·django
一一Null1 小时前
Android studio 动态布局
android·java·android studio
假女吖☌1 小时前
Maven 编译指定模版
java·开发语言·maven
体育分享_大眼3 小时前
从零搭建高并发体育直播网站:架构设计、核心技术与性能优化实战
java·性能优化·系统架构
琢磨先生David4 小时前
Java 在人工智能领域的突围:从企业级架构到边缘计算的技术革新
java·人工智能·架构
计算机学姐5 小时前
基于SpringBoo的地方美食分享网站
java·vue.js·mysql·tomcat·mybatis·springboot·美食
Hanson Huang7 小时前
【数据结构】堆排序详细图解
java·数据结构·排序算法·堆排序
慕容静漪8 小时前
如何本地安装Python Flask并结合内网穿透实现远程开发
开发语言·后端·golang
ErizJ8 小时前
Golang|锁相关
开发语言·后端·golang
骊山道童8 小时前
设计模式-外观模式
设计模式·外观模式