推荐语
本文深入浅出地介绍了原型模式,一种常用的设计模式,帮助读者全面了解其工作原理和实际应用。通过实例演示,读者将学到如何使用原型模式来高效地复用代码、简化对象创建过程,并提升产品质量和可维护性。如果您正在寻找一种能够优化软件开发的方法,不妨一试原型模式。阅读本文,一定会让您受益匪浅!
什么是原型模式
原型模式是一种创建型模式,它允许通过复制现有对象来创建新对象,而无需从头开始创建全新的对象。这种模式在软件系统中应用很广泛,特别是在需要创建大量相似或相同对象的情况下。
这种模式的主要想法是,在某个类(称为"原型类")中定义一个方法,该方法用于创建并返回该类的另一个实例。这个新实例是原型的复制品,通过复制现有的对象来创建,而不是通过使用构造函数来创建新的对象。
原型模式的核心原理
原型模式的核心原理是通过复制现有对象来创建新对象,而无需依赖具体的类实例化过程。它允许在运行时动态创建对象,并通过克隆来生成新的实例。
具体而言,原型模式通过定义一个原型对象作为创建其他对象的基础。原型对象是通过克隆(浅克隆或深克隆)来生成新对象的模板,新对象将具备与原型对象相同或部分相同的属性和方法。这种方式避免了显式地依赖于特定类的实例化过程,使得系统更加灵活、可扩展。
核心原理可以总结为:通过克隆现有对象来创建新对象,以实现对象的复用和动态创建。原型模式的核心角色:
原型对象
在原型模式中,通过复制这个原型对象来创建新的对象。这个原型对象可以是任何类型的对象,包括基本数据类型、自定义对象、集合等。
抽象原型
抽象原型角色定义了原型对象的通用接口和行为
具体原型
具体原型角色实现了抽象原型角色所定义的接口和行为,并提供了具体的实现细节。
在Java中,Cloneable接口是一个标记接口,用于指示一个对象可以被复制。它没有任何方法,只是一个标识符,用于指示实现Cloneable接口的类应该实现自己的复制方法。
要使一个对象可复制,需要实现clone()方法。该方法应该在类中定义为public和protected,并使用super.clone()调用超类的clone()方法来创建并返回一个新对象。新对象应该是原始对象的一个副本,包括所有字段和属性的副本。
原型模式的实际示例
机器狗这种玩意,其实在很早以前就被发明并制造出来了,小米科技也搞了一款,目前在官网上已经迭代到第二代了,你敢信这玩意居然卖到了12999元!可能有什么高科技在里面?
虽然这玩意能后空翻,但还是有点贵,这里咱们就用原型模式把价格打下来!
- 抽象产品类:Dog.java
csharp
public interface Dog extends Cloneable {
/**
* 奔跑
*/
void run();
/**
* 后空翻
*/
void backflip();
}
- 具体产品类:RoboticDog.java
typescript
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
kotlin
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;
}
}
- 测试类
ini
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();
}
}
}
原型模式的应用场景
在以下场景中,可以考虑使用原型模式:
- 资源优化场景:当一个类初始化时需要消化大量资源,包括数据、硬件资源等,这时就可以使用原型模式来避免资源的浪费。
- 性能和安全要求的场景:如果通过"new"产生一个对象需要非常繁琐的数据准备或访问权限,那么可以使用原型模式来提高性能并增强安全性。
- 动态指定实例化类:当需要实例化的类在运行时刻动态指定时,可以使用原型模式。通过克隆原型来得到需要的实例,可以避免在运行时指定具体的类。
- 处理复杂对象:如果处理的对象比较简单,并且对象之间的区别很小,可能只是很固定的几个属性不同,那么使用原型模式更合适。例如生活中的彩虹的七彩颜色,只需要根据现有的一个颜色对象,克隆一个新的颜色对象,然后修改具体的颜色的值就可以满足要求。
- 多线程环境:在多线程环境中,由于线程之间共享数据可能会导致数据的不一致,这时可以使用原型模式。通过在原型对象上进行复制产生新的实例,可以避免线程之间的互相影响。
- 网络连接池:当需要频繁实例化并销毁对象时,如多线程的线程池、网络连接池等,使用原型模式可以避免频繁的创建和销毁对象,提高性能。
在实际项目中,原型模式通常会和工厂方法模式一起出现,由工厂方法模式通过"clone"方法创建对象,然后提供给调用者。
总结
总的来说,原型模式是一种非常实用的创建型模式,它可以在很多情况下提高代码的效率和复用性,在使用原型模式的时候需要特别注意使用场景。优点与缺点总是相对而言的,在某些场景下,原来的优点可能就变成缺点了,而在另外一些场景,缺点也有可能会变成优点,因此辩证的去理解,从实际出发做合理选择,这是根本目的。
优点
- 原型模式的主要优点是性能和资源利用率,由于对象是在已有实例的基础上创建的,因此不需要为每个新对象分配内存和计算资源,这可以提高应用程序的性能和资源利用率。
- 原型模式可以在运行时动态创建对象,无需在编译时确定对象的类型。
- 通过复制现有对象来创建新对象,可以避免重新编写相同的代码,提高代码的复用性。
- 由于新对象是通过复制现有对象来创建的,因此新对象与原对象具有相同的属性和行为,但它们是相互独立的,可以对其中一个进行修改而不会影响到另一个。
缺点
- 原型模式可能会导致内存占用增加,因为每次创建新对象时都需要复制原型对象。
- 如果原型对象的结构非常复杂,那么复制原型对象可能会变得非常耗时。
- 原型模式可能会违反单一责任原则,因为类可能需要同时实现其应用逻辑和原型创建逻辑。
- 由于对象是通过复制现有的实例来创建的,因此修改一个原型可能会影响到所有的副本。
- 由于所有的对象都是从一个原型创建的,因此所有的对象可能会有相同的属性和行为,这可能会限制应用程序的灵活性和可扩展性。
写在最后
感谢您阅读我们的文章!如果您觉得这篇文章对您有所帮助、内容丰富、或者仅仅是让您感到轻松愉快,请不要吝啬您的点赞。您的赞和支持是我们不断进步和提高的动力。同时,如果您还有其他想法或建议,欢迎在评论区与我们分享。再次感谢您的支持,非常期待与您的下一个交流!