设计模式(6)------ 原型模式

原型模式(Prototype Pattern)

概念:

是用于创建重复的对象,同时又能保证性能。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

意图:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。

优点:

  • 性能提高。
  • 逃避构造函数的约束。

原型模式的缺点:

  • 需要为每一个类都配置一个 clone 方法 clone 方法位于类的内部,当对已有类进行改造的时候,需要修改代码,违背了开闭原则。
  • 当实现深克隆时,需要编写较为复杂的代码,而且当对象之间存在多重嵌套引用时,为了实现深克隆,每一层对象对应的类都必须支持深克隆,实现起来会比较麻烦。因此,深克隆、浅克隆需要运用得当。

适用场景

多用于创建大对象,或初始化繁琐的对象。如游戏中的背景,地图。

以下场景适用:

  1. 资源优化场景。
  2. 类初始化需要消化非常多的资源,这个资源包括数据、硬件资源等。
  3. 性能和安全要求的场景。
  4. 通过 new 产生一个对象需要非常繁琐的数据准备或访问权限,则可以使用原型模式。
  5. 一个对象多个修改者的场景。
  6. 一个对象需要提供给其他对象访问,而且各个调用者可能都需要修改其值时,可以考虑使用原型模式拷贝多个对象供调用者使用。
  7. 在实际项目中,原型模式很少单独出现,一般是和工厂方法模式一起出现,通过 clone 的方法创建一个对象,然后由工厂方法提供给调用者。

浅拷贝和深拷贝

原型模式中的拷贝对象可以分为:“浅拷贝”和“深拷贝”。

浅拷贝:

  • 当类的成员变量是基本数据类型时,浅拷贝会复制该属性的值赋值给新对象。
  • 当成员变量是引用数据类型时,浅拷贝复制的是引用数据类型的地址值。这种情况下,当拷贝出的某一个类修改了引用数据类型的成员变量后,会导致所有拷贝出的类都发生改变。

深拷贝:

  • 深拷贝不仅会复制成员变量为基本数据类型的值,给新对象。还会给是引用数据类型的成员变量【申请】储存空间,并复制引用数据类型成员变量的对象。 这样拷贝出的新对象就不怕修改了是引用数据类型的成员变量后,对其它拷贝出的对象造成影响了。
/// <summary>
/// 工作信息类
/// </summary>
class 工作信息
{
    private int salary;//工资
    private string entryTime;//入职时间

    public int Salary { get => salary; set => salary = value; }
    public string EntryTime { get => entryTime; set => entryTime = value; }

}

using System;
/// <summary>
/// 服务员信息类
/// </summary>
public class 服务员
{
    //服务员个人信息
    private string name;//名字
    private int age;//年龄
    private string sex;//性别
    private 工作信息 messages = new 工作信息();

    public string Name { get => name; set => name = value; }
    public int Age { get => age; set => age = value; }
    public string Sex { get => sex; set => sex = value; }

    public void Display()
    {
        Console.WriteLine("姓名:" + name + " 年龄:" + age + " 性别:" + sex);
        Console.WriteLine("工资:" + messages.Salary + " 入职时间:" + messages.EntryTime);
    }

    public void Set工作信息(int salary, string entryTime)
    {
        messages.Salary = salary;
        messages.EntryTime = entryTime;
    }

    public object Clone()
    {   //浅拷贝
        //创建当前 Object 的浅表副本。
        return (object)this.MemberwiseClone();
    }
    public object DeepClone()
    {   //深拷贝
        服务员 other = (服务员)this.MemberwiseClone();
        other.messages = new 工作信息();
        return other;
    }

}

测试

using System;

class Program
{
    static void Main(string[] args)
    {
        服务员 a1 = new 服务员();
        a1.Name = "张三";
        a1.Age = 19;
        a1.Sex = "男";
        a1.Set工作信息(3000, "2021年1月25日");
        a1.Display();
        //----------------------------------------------------------------
        Console.WriteLine("浅拷贝:");
        服务员 a2 = (服务员)a1.Clone();
        a2.Name = "李武";
        a2.Age = 23;
        a2.Set工作信息(2500, "2021年4月12日");
        a2.Display();
        a1.Display();
        //----------------------------------------------------------------
        Console.WriteLine("深拷贝:");
        服务员 a3 = (服务员)a1.DeepClone();
        a3.Name = "李四";
        a3.Set工作信息(10000,"2014年3月14日");
        a3.Display();
        a1.Display();
        a2.Display();

        Console.Read();
    }
}

输出示例
在这里插入图片描述
设计模式------首页

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值