模式简介
原型模式是一种创建型设计模式,用于通过克隆原型对象来创建对象,克隆对象作为原型对象的副本,并以原型对象的状态作为初始状态,可以考虑对创建过程复杂或初始化的字段属性繁多的对象应用原型模式,用以简化创建过程。
常见的应用场景:创建成本较高的对象、动态配置的对象、数据库连接池、图形化编辑器和框架中的Bean对象管理等。
模式结构
-
抽象原型(Prototype): 定义了一个克隆自身的接口,声明了一个
clone
方法。 -
具体原型(ConcretePrototype): 实现抽象原型接口的具体类,负责实现
clone
方法来复制自身。 -
客户端(Client): 使用原型对象的客户端代码,在需要创建新对象时,通过克隆原型对象而不是直接实例化来得到新对象。
-
原型管理器(Prototype Manager): 用于注册和管理原型对象的类,提供根据键值获取原型对象的方法。
工作原理
-
客户端通过原型管理器获取原型对象的克隆,而不是通过直接实例化新对象。
-
原型管理器负责注册和存储原型对象,并提供获取原型对象的方法。
-
具体原型类实现了抽象原型接口,包含一个
clone
方法,该方法通过复制自身来创建新对象。 -
客户端代码调用原型对象的
clone
方法来获取新对象,从而避免了直接使用new
关键字创建对象。 -
在需要创建新对象时,客户端可以向原型管理器请求原型对象的克隆,从而实现动态创建对象的目的。
代码示例(C#)
提示:可在本栏目的资源篇“设计模式代码示例合集”下载所有完整代码资源。
3D对象:3DObject.cs
namespace PrototypePattern;
// 原型
interface IPrototype
{
// 克隆
IPrototype Clone();
}
// 3D物体类型
enum _3DObjectType
{
None, Cube, Sphere
}
// 3D物体
abstract class _3DObject : IPrototype
{
public string name;
public _3DObjectType type { get; protected set; }
public _3DObject(string name)
{
this.name = name;
}
public abstract IPrototype Clone();
}
// 立方体
class Cube : _3DObject
{
public Cube(string name) : base(name)
{
type = _3DObjectType.Cube;
}
public override IPrototype Clone()
{
return new Cube(name);
}
public override string ToString()
{
return $"[Name:{name},Type:{type},HashCode:{GetHashCode()}]";
}
}
// 球体
class Sphere : _3DObject
{
public Sphere(string name) : base(name)
{
type = _3DObjectType.Sphere;
}
public override IPrototype Clone()
{
return new Sphere(name);
}
public override string ToString()
{
return $"[Name:{name},Type:{type},HashCode:{GetHashCode()}]";
}
}
3D对象管理器:3DObjectManager.cs
namespace PrototypePattern;
#pragma warning disable
// 3D原型对象管理器
class _3DObjectManager
{
private Dictionary<_3DObjectType, IPrototype> objects; // 3D原型对象集合
public _3DObjectManager()
{
objects = new Dictionary<_3DObjectType, IPrototype>();
}
// 注册指定类型的3D原型对象
public void Register(IPrototype _3dObject, _3DObjectType type)
{
objects[type] = _3dObject;
}
// 获取指定类型的3D原型对象的克隆对象
public IPrototype Get3DObject(_3DObjectType type)
{
if (objects.ContainsKey(type)) return objects[type].Clone();
return null;
}
}
测试代码:Program.cs
// ************* 20.原型模式测试 **************
using PrototypePattern;
#pragma warning disable
// 创建实例
Cube cube = new Cube("Default Cube");
Sphere sphere = new Sphere("Default Sphere");
_3DObjectManager manager = new _3DObjectManager();
// 向3D原型对象管理器注册立方体和球体的原型对象
manager.Register(cube, _3DObjectType.Cube);
manager.Register(sphere, _3DObjectType.Sphere);
// 从3D原型对象管理器获取立方体和球体的克隆对象
Cube cube1 = manager.Get3DObject(_3DObjectType.Cube) as Cube;
Sphere sphere1 = manager.Get3DObject(_3DObjectType.Sphere) as Sphere;
// 输出立方体以及球体的原型和克隆对象的信息
Console.WriteLine(cube);
Console.WriteLine(cube1);
Console.WriteLine(sphere);
Console.WriteLine(sphere1);
代码解说
上述代码演示了创建立方体和球体两个3D对象的过程。两个3D对象都实现了原型接口的克隆方法。通过向3D对象管理器注册立方体和球体的原型对象,实现通过传递3D对象类型的方式获取原型对象的克隆对象。值得一提的是编写克隆方法时要注意浅拷贝和深拷贝的问题,对于值类型和引用类型的拷贝可能会有所不同。
如果这篇文章对你有帮助,请给作者点个赞吧!