原型模式


原型模式

概述

原型模式是一种对象创建型设计模式,主要用于创建重复使用的对象,由已有的原型对象创建出新的对象,不需要再经过重复的复制实现过程。通过克隆已经存在的实例来开辟新的实例,而不是重复创建相同的对象,具有较好的性能优势。

结构

原型模式结构包括原型接口、具体原型类、原型管理器三个部分。

  • 原型接口:定义一个克隆自己的接口方法,能够返回一个克隆出来的对象。
  • 具体原型类:实现原型接口,实现克隆自己的接口方法。
  • 原型管理器:用于存储和管理原型对象。提供获取对象和新建对象方法。

示例

interface Animal extends Cloneable {
    Animal cloneAnimal();
}

class Cat implements Animal {
    @Override
    public Animal cloneAnimal() {
        try {
            return (Cat) super.clone();
        } catch (CloneNotSupportedException e) {
            return null;
        }
    }
}

class Dog implements Animal {
    @Override
    public Animal cloneAnimal() {
        try {
            return (Dog) super.clone();
        } catch (CloneNotSupportedException e) {
            return null;
        }
    }
}

class AnimalCache {
    private final HashMap<String, Animal> animalMap = new HashMap<>();

    public void loadCache() {
        animalMap.put("cat", new Cat());
        animalMap.put("dog", new Dog());
    }

    public Animal getAnimal(String animalName) {
        Animal cachedAnimal = animalMap.get(animalName);
        if (cachedAnimal != null) {
            return cachedAnimal.cloneAnimal();
        }
        return null;
    }
}

public class PrototypePatternDemo {
    public static void main(String[] args) {
        AnimalCache.loadCache();

        Animal clonedCat = AnimalCache.getAnimal("cat");
        System.out.println(clonedCat.getClass().getSimpleName()); // Cat

        Animal clonedDog = AnimalCache.getAnimal("dog");
        System.out.println(clonedDog.getClass().getSimpleName()); // Dog
    }
}

应用场景

适用于以下场景:

  • 对象创建过程消耗资源较大(例如读取文件、数据库中的 数据或网络请求),希望通过复制现有对象达到节省资源的目的。
  • 需要保护对象安全时,避免因原始对象被操作而导致后续所有引用被影响的情况,可以采用原型模式创建克隆对象,避免修改原始对象对其他代码产生负面影响。
  • 动态获取实例, 让用户根据需要产生几个对象,而又不需要知道产生的是哪些具体类。
  • 用于解决开销大的对象创建问题。

优缺点

优点:

  • 可以使用克隆避免重复的初始化处理,降低时间和资源的消耗。
  • 可以在不需要与客户紧耦合的情况下生成复杂的对象。
  • 可以通过改变值来初始化不同的对象。

缺点:

  • 需要为每一个类配置一个克隆方法。
  • 由于克隆对象与原型之间没有父子关系,对克隆对象的修改不会影响原型对象,如果需要同时修改原型对象,需要另外实现。

总结

原型模式是一种对象创建型设计模式,通过克隆已经存在的实例来开辟新的实例,而不是重复创建相同的对象,提供更好的性能和资源利用。适用于需要动态获取实例或避免重复初始化处理的场景。