06_原型模式
原型模式是一种创建型设计模式,它通过克隆现有对象来创建新对象,而不是通过实例化类来创建。原型模式允许我们创建具有相同属性和方法的对象集合,从而减少了对象的创建成本。
在原型模式中,我们首先创建一个原始对象,然后通过克隆该对象来创建新的对象。这样,我们可以在不重新实例化类的情况下创建多个相似的对象。
原型模式适用于以下场景:
-
当一个系统需要创建大量相似对象时,使用原型模式可以提高性能。
-
当对象的创建成本比克隆成本高时,使用原型模式可以节省资源。
-
当一个对象需要配置大量属性时,使用原型模式可以简化对象的创建过程。
总结而言,原型模式通过克隆现有对象来创建新对象,减少了对象的创建成本,提高了系统的性能和效率。
/// <summary> /// 电池 /// </summary> [Serializable] public class Battery { /// <summary> /// 容量 /// </summary> public int Capacity { get; set; } = 0; /// <summary> /// 电压 /// </summary> public double Voltage { get; set; } = 0; /// <summary> /// 功率 /// </summary> public double Power { get; set; } = 0; }
手机对象接口
public interface IPhone { /// <summary> /// CPU /// </summary> string CPU { get; set; } /// <summary> /// 内存 /// </summary> int Memory { get; set; } /// <summary> /// 电池 /// </summary> Battery Battery { get; set; } void Write(string tag); /// <summary> /// 浅拷贝 /// </summary> /// <returns></returns> IPhone Clone(); /// <summary> /// 深拷贝 /// </summary> /// <returns></returns> IPhone DeepClone(); }
/// <summary> /// 序列化帮助类 /// </summary> public class SerializableHelper { /// <summary> /// 序列化 /// </summary> /// <param name="target"></param> /// <returns></returns> public string Serializable(object target) { using(MemoryStream stream= new MemoryStream()) { new BinaryFormatter().Serialize(stream, target); return Convert.ToBase64String(stream.ToArray()); } } /// <summary> /// 反序列化 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="target"></param> /// <returns></returns> public T Derializable<T>(string target) { return (T)Derializable(target); } public object Derializable(string target) { byte[] array = Convert.FromBase64String(target); using(MemoryStream stream = new MemoryStream(array)) { return new BinaryFormatter().Deserialize(stream); } } }
/// <summary> /// 苹果手机类 /// </summary> [Serializable] public class ApplePhone : IPhone { public ApplePhone() { Battery = new Battery { Capacity = 5000, Power = 5, Voltage = 3.7 }; } /// <summary> /// CPU /// </summary> public string CPU { get; set; } = string.Empty; /// <summary> /// 内存 /// </summary> public int Memory { get; set; } = 0; /// <summary> /// 电池 /// </summary> public Battery Battery { get; set; } /// <summary> /// 浅克隆 /// </summary> /// <returns></returns> public IPhone Clone() { return this.MemberwiseClone() as ApplePhone; } /// <summary> /// 深克隆 /// </summary> /// <returns></returns> public IPhone DeepClone() { SerializableHelper helper = new SerializableHelper(); string target = helper.Serializable(this); return helper.Derializable<IPhone>(target); } public void Write(string tag) { Console.WriteLine($"{tag}=> CPU = {CPU},Memory = {Memory}"); } }
浅克隆
在浅克隆中,如果原型对象的成员变量是值类型,将复制一份给新对象,如果是引用类型,在浅克隆中会复制一份引用类型的引用给新对象,也就是说新对象和原型对象的引用变量指向相同的内存地址。简单来说,浅克隆只会复制变量中直接存储的内容。
深克隆
深克隆中,如果原型对象的成员变量是值类型,将复制一份给新对象,如果是引用类型,深克隆会将引用变量指向内存区域中存储的实际数据复制一份给新对象,这时新对象的所有操作都不会对原型对象产生影响,真正意义上的全新的对象。
调用
public class Client { public void Start() { IPhone iphone1 = new ApplePhone(); iphone1.CPU = "最初的三星S5L8900"; iphone1.Memory = 1; iphone1.Write("iphone1"); Console.WriteLine($"iphone1.Battery.Capacity={iphone1.Battery.Capacity} maA"); IPhone iphone15 = iphone1.Clone();//浅拷贝 iphone15.Write("iphone15"); Console.WriteLine($"iphone15.Battery.Capacity={iphone15.Battery.Capacity} maA"); //修改iphone15对象的内容 iphone15.CPU = "芯片:A16仿生芯片,16核神经引擎,5核GPU、6核CPU"; iphone15.Memory = 512; iphone15.Battery.Capacity++; iphone15.Write("iphone15修改后"); iphone1.Write("iphone1"); Console.WriteLine($"iphone15.Battery.Capacity={iphone15.Battery.Capacity} maA"); Console.WriteLine($"iphone1.Battery.Capacity={iphone1.Battery.Capacity} maA"); Console.WriteLine("---------------------漂亮的分割线------------------------"); IPhone iphone16 = iphone1.DeepClone();//深拷贝 iphone16.Write("iphone16"); Console.WriteLine($"iphone16.Battery.Capacity={iphone16.Battery.Capacity} maA"); iphone16.CPU = "12核CPU,10核GPU"; iphone16.Memory = 1024; iphone16.Battery.Capacity++; iphone16.Write("iphone16修改后"); iphone1.Write("iphone1"); Console.WriteLine($"iphone16.Battery.Capacity={iphone16.Battery.Capacity} maA"); Console.WriteLine($"iphone1.Battery.Capacity={iphone1.Battery.Capacity} maA"); } }
static void Main(string[] args) { new Client().Start(); Console.ReadKey(); }