设计模式之原型模式

什么是原型模式

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

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

原型模式的UML类图

原型对象

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

抽象原型

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

具体原型

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

设计模式之原型模式_第1张图片

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

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

原型模式的实际示例

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

设计模式之原型模式_第2张图片

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

设计模式之原型模式_第3张图片

抽象产品类:Dog.java

public interface Dog extends Cloneable {
    /**
     * 奔跑
     */
    void run();

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

具体产品类:RoboticDog.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

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;
    }
}

测试类

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();
        }

    }
}

设计模式之原型模式_第4张图片

原型模式的应用场景

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

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

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

总结

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

优点

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

缺点

  1. 原型模式可能会导致内存占用增加,因为每次创建新对象时都需要复制原型对象。
  2. 如果原型对象的结构非常复杂,那么复制原型对象可能会变得非常耗时。
  3. 原型模式可能会违反单一责任原则,因为类可能需要同时实现其应用逻辑和原型创建逻辑。
  4. 由于对象是通过复制现有的实例来创建的,因此修改一个原型可能会影响到所有的副本。
  5. 由于所有的对象都是从一个原型创建的,因此所有的对象可能会有相同的属性和行为,这可能会限制应用程序的灵活性和可扩展性。

你可能感兴趣的:(设计模式,java,设计模式,原型模式,UML,后端)