? 作者简介,愚公搬代码 ?《头衔》:华为云特约编辑,华为云云享专家,华为开发者专家,华为产品云测专家,CSDN博客专家,阿里云专家博主,腾讯云优秀博主,掘金优秀博主,51CTO博客专家等。 ?《近期荣誉》:2022年CSDN博客之星TOP2,2022年华为云十佳博主等。
?《博客内容》:.NET、Java、Python、Go、Node、前端、IOS、Android、鸿蒙、Linux、物联网、网络安全、大数据、人工智能、U3D游戏、小程序等相关领域知识。
??欢迎 ?点赞?评论?收藏
设计模式(Design Pattern)是软件开发领域的宝贵经验,是多人反复借鉴和广泛应用的代码设计指导。它们是一系列经过分类和归纳的代码组织方法,旨在实现可重用性、可维护性和可理解性。使用设计模式,我们能够编写高质量的代码,使其更易于他人理解,并提供了代码可靠性的保证。
毫无疑问,设计模式对个人、团队和整个系统都带来了显著的益处。它们将代码开发提升到工程化水平,为软件工程构建提供了坚实的基础,就如同大厦的一块块精巧的砖石一样。在项目中明智地应用设计模式可以完美地解决各种复杂问题。每种设计模式都有相应的原理和最佳实践,它们描述了我们日常开发中不断遇到的问题,以及这些问题的核心解决方法。正是因为这种实用性和通用性,设计模式才能在软件开发中广泛地得以应用。设计模式是构建稳健、可扩展和可维护软件的关键工具,为开发者们提供了解决问题的智慧和指导。
原型模式是一种创建型设计模式,它的核心思想是使用现有对象作为原型,通过复制这个原型来创建新的对象实例。
这种模式特别适用于需要大量相同或相似对象的情况,因为它可以节省对象的创建成本,避免了重复的初始化过程。在原型模式中,我们首先创建一个原型对象,然后通过对该原型对象进行复制或克隆操作,来生成新的对象副本,这些副本与原型对象具有相同或相似的属性和状态。
总的来说,原型模式关注对象的复制和克隆,它通过提供一个可被复制的原型对象来简化对象的创建过程,特别适合处理那些需要频繁创建相似对象的场景。这种模式的优点在于提高了性能和降低了资源消耗,同时也减少了与对象初始化相关的复杂性。
原型模式(Prototype Pattern)中的抽象原型(Prototype)是指一个抽象基类或接口,它定义了具体原型对象必须实现的方法。抽象原型通常包含一个名为clone
或copy
的方法,用于复制自身并创建一个新的对象副本。
抽象原型的主要作用是定义了对象复制的接口规范,为具体原型对象提供了一个通用的方法,使得客户端可以通过该方法创建新的对象,而不必关心对象创建的具体细节。具体原型类需要实现抽象原型中的clone
方法,以便能够正确地复制自身并返回新的对象。
抽象原型的作用可以总结如下:
抽象原型在原型模式中充当了一个关键角色,它定义了对象复制的标准接口,使得对象的复制过程更加灵活、可扩展和封装,从而提高了代码的可维护性和可复用性。
原型模式(Prototype Pattern)中的具体原型(Concrete Prototype)是指实现了抽象原型(Prototype)接口的具体类。每个具体原型类都表示一种具体的对象类型,它实现了抽象原型中定义的复制方法,用于创建该类型对象的副本。
具体原型的主要作用如下:
具体原型是原型模式中具体对象的实现,它通过实现抽象原型接口的复制方法,允许客户端创建新对象的副本。这种模式提供了一种有效的方式来管理和创建对象,尤其适用于需要大量相似对象的情况,同时提高了代码的可扩展性和可维护性。
注:C#中的MemberwiseClone属于浅克隆。
命名空间PrototypePattern包含细胞基类Cell,它的2个实现类分别为:PlantCell植物细胞类和Animal动物细胞类,另外包含CloneBase泛型基类。本案例尝试模拟细胞的分裂过程以展示原型模式在复制对象本身方面的独到之处。
[Serializable]
public abstract class Cell : CloneBase<Cell> {
public int Id { get; set; }
public string Wall { get; set; }//细胞壁
public string Membrane { get; set; }//细胞膜
public string Cytoplasm { get; set; }//细胞质
public string Nucleus { get; set; }//细胞核
public Content Content { get; set; } = new Content();//细胞器
public Cell(int id,
string wall,
string membrane,
string cytoplasm,
string nucleus) {
this.Id = id;
this.Wall = wall;
this.Membrane = membrane;
this.Cytoplasm = cytoplasm;
this.Nucleus = nucleus;
this.Content = new Content();
}
public abstract Cell Division();
}
抽象细胞基类Cell,继承自CloneBase并定义Division分裂接口。
[Serializable]
public class PlantCell : Cell {
public PlantCell(int id,
string wall,
string membrane,
string cytoplasm,
string nucleus)
: base(id, wall, membrane, cytoplasm, nucleus) {
}
public override Cell Division() {
var cell = this.MemberwiseClone() as Cell;
cell.Id = RandomUtil.RandomNum();
return cell;
}
}
植物细胞类PlantCell,细胞基类的具体实现类,标记Serializable特性以支持序列化的深克隆。
[Serializable]
public class AnimalCell : Cell {
public AnimalCell(int id,
string wall,
string membrane,
string cytoplasm,
string nucleus)
: base(id, wall, membrane, cytoplasm, nucleus) {
}
public override Cell Division() {
var cell = this.MemberwiseClone() as Cell;
cell.Id = RandomUtil.RandomNum();
return cell;
}
}
动物细胞类AnimalCell,细胞基类的具体实现类,标记Serializable特性以支持序列化的深克隆。
[Serializable]
public class Content {
public string Mitochondria { get; set; }//线粒体
public int Chloroplasts { get; set; }//叶绿体
public int EndoplasmicReticulum { get; set; }//内质网
public int GolgiBody { get; set; }//高尔基复合体
public int Ribosomes { get; set; }//核糖体
public int Centrosome { get; set; }//中心体
public int Vacuole { get; set; }//液泡
public int Lysosomes { get; set; }//溶酶体
public int Microtubule { get; set; }//微管
}
细胞质类Content,为细胞基类中所包含的一个对象成员。
[Serializable]
public class CloneBase<T> {
public virtual T Clone() {
var memoryStream = new MemoryStream();
var formatter = new BinaryFormatter();
formatter.Serialize(memoryStream, this);
memoryStream.Position = 0;
return (T)formatter.Deserialize(memoryStream);
}
}
克隆类CloneBase,包含一个虚拟的Clone方法以支持深克隆。
public class RandomUtil {
public static int RandomNum() {
return new Random().Next(1000000, 10000000);
}
}
产生细胞Id的工具类,从100万到1000万。
public class Program {
private static Cell _cell = null;
private const string SPLIT_BREAK = "-----------------------------------------------------";
public static void Main(string[] args) {
_cell = new PlantCell(RandomUtil.RandomNum(),
"wall",
"membrane",
"cytoplasm",
"nucleus");
var plant = _cell.Division();
Console.WriteLine($"_cell.GUID:{_cell.Id},{Environment.NewLine}plant.GUID:{plant.Id}," +
$"{Environment.NewLine}equals:{_cell.Id == plant.Id}.");
Console.WriteLine(SPLIT_BREAK);
_cell.Content.Mitochondria = "10010101010100101010101";
Console.WriteLine($"_cell.Content.Mitochondria:{_cell.Content.Mitochondria},\r\n" +
$"plant.Content.Mitochondria:{plant.Content.Mitochondria}," +
$"{Environment.NewLine}equals:" +
$"{_cell.Content.Mitochondria == plant.Content.Mitochondria}.");
Console.WriteLine(SPLIT_BREAK);
var animal = _cell.Clone();
Console.WriteLine($"_cell.GUID:{_cell.Id},{Environment.NewLine}animal.GUID:{animal.Id}," +
$"{Environment.NewLine}equals:{_cell.Id == animal.Id}.");
Console.WriteLine(SPLIT_BREAK);
_cell.Content.Mitochondria = "01001010010100101010010";
Console.WriteLine($"_cell.Content.Mitochondria:{_cell.Content.Mitochondria},\r\n" +
$"animal.Content.Mitochondria:{animal.Content.Mitochondria}," +
$"{Environment.NewLine}equals:" +
$"{_cell.Content.Mitochondria == animal.Content.Mitochondria}.");
Console.WriteLine(SPLIT_BREAK);
Console.ReadKey();
}
}
以上是调用方的代码,植物细胞实例调用了浅克隆,而动物细胞实例调用了深克隆,请仔细分析这段代码。以下是这个案例的输出结果:
_cell.GUID:6768270,
plant.GUID:2028096,
equals:False.
-----------------------------------------------------
_cell.Content.Mitochondria:10010101010100101010101,
plant.Content.Mitochondria:10010101010100101010101,
equals:True.
-----------------------------------------------------
_cell.GUID:6768270,
animal.GUID:6768270,
equals:True.
-----------------------------------------------------
_cell.Content.Mitochondria:01001010010100101010010,
animal.Content.Mitochondria:10010101010100101010101,
equals:False.
-----------------------------------------------------
原型模式(Prototype Pattern)具有以下优点:
原型模式通过对象的复制来创建新对象,极大地提高了对象创建的效率和灵活性,适用于需要大量相似对象的场景,同时可以降低系统的开销,提高性能。
原型模式(Prototype Pattern)虽然具有许多优点,但也存在一些缺点,包括:
原型模式在某些场景下非常有用,但也需要注意其局限性和潜在的复杂性。在使用原型模式时,需要根据具体的需求和对象的复杂性来权衡其优点和缺点。
原型模式(Prototype Pattern)适用于以下场景:
原型模式在需要大量相似对象、复杂对象创建、对象状态变化较小、动态配置对象等情况下非常有用。它可以提高性能、降低资源消耗,并提高代码的灵活性和可维护性。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。