一、原型模式概述
原型模式(Prototype Pattern)是一种创建型设计模式,其核心思想是通过复制(克隆)已有对象(原型)来创建新对象,而非通过构造函数重新初始化。
在该模式中,新对象的初始状态与原型完全一致,后续可根据需求修改自身属性。这种方式绕开了复杂的初始化流程(如数据库查询、资源加载等),直接复用原型的状态,从而减少重复劳动,提高对象创建效率。
原型模式的核心角色包括:

二、原型模式的使用场景
三、原型模式的优缺点
优点
缺点
四、使用原型模式的注意事项
五、示例代码
using System;
using System.Collections.Generic;
// 原型接口(实现ICloneable或自定义克隆方法)
public interface IPrototype<T>
{
T Clone();
}
// 具体原型类(可克隆对象)
public class Product : IPrototype<Product>
{
public int Id { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
public List<string> Tags { get; set; } // 引用类型成员
public Product(int id, string name, decimal price, List<string> tags)
{
Id = id;
Name = name;
Price = price;
Tags = tags;
}
// 深克隆实现(复制值类型+引用类型深拷贝)
public Product Clone()
{
// 对引用类型成员进行深拷贝
List<string> clonedTags = new List<string>(Tags);
return new Product(Id, Name, Price, clonedTags);
}
public override string ToString()
{
return $"Id: {Id}, Name: {Name}, Price: {Price}, Tags: [{string.Join(", ", Tags)}]";
}
}
// 客户端调用示例
public class Client
{
public static void Main()
{
// 创建原始对象
var originalTags = new List<string> { "电子", "数码", "新品" };
Product originalProduct = new Product(1, "智能手机", 3999.99m, originalTags);
Console.WriteLine("原始对象:" + originalProduct);
// 通过原型克隆新对象
Product clonedProduct = originalProduct.Clone();
Console.WriteLine("\n克隆对象(初始状态):" + clonedProduct);
// 修改克隆对象的属性(验证深克隆:引用类型修改不影响原始对象)
clonedProduct.Id = 2;
clonedProduct.Name = "高端智能手机";
clonedProduct.Price = 5999.99m;
clonedProduct.Tags.Add("旗舰");
Console.WriteLine("\n修改后的克隆对象:" + clonedProduct);
Console.WriteLine("修改后原始对象:" + originalProduct);
}
}
六、原型模式与使用new关键字创建对象的区别
原型模式与通过 new关键字创建对象(即直接实例化)是两种不同的对象创建方式,核心区别体现在创建逻辑、效率、适用场景等方面。以下从多个维度对比两者的差异:
(1)、核心思想不同
(2)、创建过程不同
对比维度 | new 关键字创建对象 | 原型模式 |
执行逻辑 | 调用类的构造函数,执行完整的初始化流程(如参数校验、资源加载、属性赋值等)。 | 不执行构造函数,直接复制原型的内存数据或状态(浅克隆复制值类型和引用,深克隆递归复制所有成员)。 |
| 完全依赖构造函数的参数和内部逻辑,初始状态由代码硬编码或外部参数决定。 | 初始状态与原型完全一致,后续可通过修改属性生成变体。 |
| 必须知道具体类名,编译期需确定类型(如 new MyClass() 依赖 MyClass的可见性)。 | 无需知道具体类名,通过原型对象动态克隆(如 prototype.Clone(),原型可以是接口或抽象类的实现)。 |
(3)、效率不同
(4)、灵活性不同
(5)、适用场景不同
new 关键字创建对象 | 原型模式 |
1. 对象初始化逻辑简单 | 1. 对象初始化成本高 |
2. 无需频繁创建相似对象,或对象间差异较大 | 2. 需频繁创建相似对象(仅部分属性不同) |
3. 编译期可确定对象类型,且类型固定 | 3. 运行时需动态生成对象(类型不确定或需灵活切换) |
4. 不需要保存对象快照 | 4. 需要保存对象快照 |
对象快照(Object Snapshot): 某一时刻内存中对象的 “静态副本”。
(6)、代码示例对比
场景:创建“用户订单”对象,包含订单信息和用户信息(引用类型)。
1. 使用 new 关键字创建public class User
{
public string Name { get; set; }
public int Age { get; set; }
public User(string name, int age)
{
// 模拟复杂初始化(如查询用户等级)
Console.WriteLine("执行User构造函数,查询用户等级...");
Name = name;
Age = age;
}
}
public class Order
{
public int Id { get; set; }
public decimal Amount { get; set; }
public User Buyer { get; set; }
public Order(int id, decimal amount, User buyer)
{
// 模拟复杂初始化(如校验订单金额)
Console.WriteLine("执行Order构造函数,校验金额...");
Id = id;
Amount = amount;
Buyer = buyer;
}
}
// 客户端
var user = new User("张三", 30);
// 多次创建相似订单(每次都执行构造函数)
var order1 = new Order(1, 100, user);
var order2 = new Order(2, 200, user); // 重复执行校验逻辑,效率低
输出(构造函数被多次执行):
执行User构造函数,查询用户等级...
执行Order构造函数,校验金额...
执行Order构造函数,校验金额...
2. 使用原型模式创建public class User
{
public string Name { get; set; }
public int Age { get; set; }
public User(string name, int age)
{
Console.WriteLine("执行User构造函数,查询用户等级...");
Name = name;
Age = age;
}
}
public class Order : ICloneable
{
public int Id { get; set; }
public decimal Amount { get; set; }
public User Buyer { get; set; }
public Order(int id, decimal amount, User buyer)
{
Console.WriteLine("执行Order构造函数,校验金额...");
Id = id;
Amount = amount;
Buyer = buyer;
}
// 浅克隆(示例)
public object Clone() => this.MemberwiseClone();
}
// 客户端
var user = new User("张三", 30);
var prototypeOrder = new Order(1, 100, user); // 仅执行一次构造函数
// 克隆生成新订单(不执行构造函数)
var order2 = (Order)prototypeOrder.Clone();
order2.Id = 2;
order2.Amount = 200;
输出(构造函数仅执行一次):
执行User构造函数,查询用户等级...
执行Order构造函数,校验金额...
实际开发中,两者并非互斥:简单对象用 new,复杂且重复创建的对象用原型模式,需根据具体场景权衡选择。
七、原型模式在特来电业务中可应用的场景
1.电站信息创建,目前电站有多种,普通电站、光伏电站、储能站、互联互通电站。 基本信息有很多是一样的,只是有个别属性不一致。在构建电站信息时,可使用原型模式。
2.价格策略创建,与电站类似,价格策略也是有多种不同的策略,普通策略、接入电价策略、超时占用费策略、折扣策略等,在创建策略信息时,也可使用原型模式。
八、总结思考
原型模式通过 “克隆” 实现对象创建,是一种高效的 “以空间换时间” 的设计思想。其核心价值在于复用已有对象的状态,减少重复初始化操作,尤其适合处理创建成本高或需频繁生成相似对象的场景。
从实践角度看,使用原型模式需注意以下几点:
总之,原型模式是对传统对象创建方式的有效补充,合理使用可显著提升系统性能和灵活性,但需权衡其实现复杂度与业务需求的匹配度,避免为了设计而设计。