首页 > 其他分享 >PrototypePattern-原型模式

PrototypePattern-原型模式

时间:2023-08-09 17:57:41浏览次数:38  
标签:Name student2 student1 PrototypePattern StudentPrototype 模式 原型 StudentSingleton 

在C#中,原型模式(Prototype Pattern)是一种创建型设计模式,它允许通过克隆现有对象来创建新对象,而无需依赖于显式的构造函数。原型模式通过复制现有对象的属性和状态,创建一个新对象,并在需要创建对象时返回这个克隆的副本。

原型模式的核心是使用原型接口或基类来定义克隆方法,并让具体类实现该方法来实现克隆功能。在C#中,原型模式的实现方式可以使用对象的MemberwiseClone()方法或序列化和反序列化来实现。

原型模式的意义在于对象的复用,减小对象构建对资源的开销

1.单例原型

单例模式:保证整个进程中,该对象只有一个实例

public class StudentSingleton
{
    public int Id { get; set; }
    public string Name { get; set; }
    /// <summary>
    /// 构造函数私有化
    /// </summary>
    private StudentSingleton()
    {
        Console.WriteLine("{0}被构造..", this.GetType().Name);
    }
    /// <summary>
    /// 静态字段
    /// </summary>
    private static StudentSingleton _Student = new StudentSingleton()
    {
        Id = 001,
        Name = "小明"
    };
    /// <summary>
    /// 开放的静态方法获取实例
    /// </summary>
    /// <returns></returns>
    public static StudentSingleton CreateInstance()
    {
        return _Student;
    }
    public void Study()
    {
        Console.WriteLine("{0}正在学习", this.Name);
    }
}
internal class Program
{
    static void Main(string[] args)
    {
        for (int i = 0; i < 3; i++)
        {
            StudentSingleton student = StudentSingleton.CreateInstance();
            student.Study();
        }
        //输出结果
        //StudentSingleton被构造..
        //小明正在学习
        //小明正在学习
        //小明正在学习
    }
}

扩展:C#内存分配机制

C#中的内存分配面向对象,对于值类型(如int、float)和引用类型(如string、类)的内存分配方式有所不同

int 的内存分配:int 是值类型,它的值直接存储在栈上。当声明一个 int 变量时,分配的内存空间大致等于一个 int 的大小(通常为4字节)。

string 的内存分配:string 是引用类型,它的实例存储在托管堆(Managed Heap)上。当使用 new 关键字创建一个 string 对象时,会在堆上分配一块内存空间来存储字符串的值。

{
    Console.WriteLine("***************Singleton**************");
    StudentSingleton student1 = StudentSingleton.CreateInstance();
    StudentSingleton student2 = StudentSingleton.CreateInstance();
    student1.Id = 002;
    student1.Name = "小红";

    student2.Id = 003;
    student2.Name = "小黄";

    Console.WriteLine(student1.Id);
    Console.WriteLine(student1.Name);
    Console.WriteLine(student2.Id);
    Console.WriteLine(student2.Name);
    //输出结果
    //3
    //小黄
    //3
    //小黄
}

单例模式整个进程只有一个实例,在C#内存分配机制中student1与student2属于引用类型,指向堆的同一块区域。所以后面的会覆盖前面的。

2.拷贝原型

MemberwiseClone()方法:内存拷贝,不走构造函数,直接内存copy,所以没有性能损失;

public class Classroom
{
    public int ClassroomId { get; set; }
    public string ClassroomName { get; set; }
}
public class StudentPrototype
{
    public int Id { get; set; }
    public string Name { get; set; }
    public Classroom classroom { get; set; }

    /// <summary>
    /// 构造函数私有化
    /// </summary>
    private StudentPrototype()
    {
        Console.WriteLine("{0}被构造..", this.GetType().Name);
    }
    /// <summary>
    /// 静态字段
    /// </summary>
    private static StudentPrototype _Student = new StudentPrototype()
    {
        Id = 001,
        Name = "小明",
        classroom = new Classroom()
        {
            ClassroomId = 1,
            ClassroomName = "小学"
        }
    };
    /// <summary>
    /// 开放的静态方法获取实例
    /// </summary>
    /// <returns></returns>
    public static StudentPrototype CreateInstance()
    {
        StudentPrototype student = (StudentPrototype)_Student.MemberwiseClone();
        return student;
    }
    public void Study()
    {
        Console.WriteLine("{0}{1}正在{2}号{3}学习", this.Name, this.Id, this.classroom.ClassroomId, this.classroom.ClassroomName);
    }
}
{
    Console.WriteLine("***************Prototype**************");
    StudentPrototype student1 = StudentPrototype.CreateInstance();
    StudentPrototype student2 = StudentPrototype.CreateInstance();
    StudentPrototype student3 = StudentPrototype.CreateInstance();
    student1.Id = 002;
    student1.Name = "小红";
    student1.classroom.ClassroomId = 2;
    student1.classroom.ClassroomName = "初中";
    //因为string类型的 ="CodeMan" 等同于 new String("CodeMan"); 开辟新的空间,不影响之前的-----实际上string是不可修改的----

    student2.Id = 003;
    student2.Name = "小黄";
    student2.classroom.ClassroomId = 3;
    student2.classroom.ClassroomName = "高中";

    student3.Id = 004;
    student3.Name = "小蓝";
    student3.classroom = new Classroom()
    {
        ClassroomId = 4,
        ClassroomName = "大学"
    };
    student1.Study();
    student2.Study();
    student3.Study();
    //输出结果
    //StudentPrototype被构造..
    //小红2正在3号高中学习
    //小黄3正在3号高中学习
    //小蓝4正在4号大学学习
}

student1与student2的classroom属性属于引用类型,MemberwiseClone()方法属于浅拷贝,只拷贝classroom属性的引用地址。

StudentPrototype中的Name属性也属于引用类型(string),但student1.Name = "小红"等同于student1.Name = new String("小红"),这是String类型的特性,每次重新赋值只会重新开辟一块新的空间。

student3的classroom属性把引用的地址重新赋值,完成了深拷贝——不仅拷贝引用,还得拷贝引用类型的值。

标签:Name,student2,student1,PrototypePattern,StudentPrototype,模式,原型,StudentSingleton,
From: https://www.cnblogs.com/ZHIZRL/p/17617550.html

相关文章

  • js-设计模式之订阅发布模式简单理解和实践
    /***啥是发布订阅模式*举个栗子--场景:充值成功切换到个人中心页面刷新余额切换到会员中心页面刷新会员状态等*///定义一个对象作为接收事件的载体consteventBus={topic:{},//这里为啥是个对象呢首先肯定不止是一个事件,所以得是数组或者对象,那为什么不......
  • 原型链
    ......
  • 23种设计模式及其应用场景
    23种设计模式及其应用场景设计模式主要分三个类型:创建型、结构型和行为型。创建型有:一、Singleton,单例模式:保证一个类只有一个实例,并提供一个访问它的全局访问点;应用场景:一个无状态的类使用单例模式节省内存资源。二、AbstractFactory,抽象工厂:提供一个创建一系列相关或相......
  • 代理模式(Proxy)
    定义为其他对象提供一种代理以控制对这个对象的访问。结构和说明Proxy:代理对象,通常具有如下功能。实现与具体的目标对象一样的接口,这样就可以使用代理来代替具体的目标对象。保存一个指向具体目标对象的引用,可以在需要的时候调用具体的目标对象。可以控制对具体目标对象的访......
  • 前端原型和原型链constructor
     目录前言导语运行结果总结 代码部分总结前言我是歌谣我有个兄弟巅峰的时候排名c站总榜19叫前端小歌谣曾经我花了三年的时间创作了他现在我要用五年的时间超越他今天又是接近兄弟的一天人生难免坎坷大不了从头再来歌谣的意志是永恒的放弃很容易但是坚持一定很酷导语前......
  • 前端原型和原型链构造函数的使用
     目录前言导语代码部分 总结代码部分 总结前言我是歌谣我有个兄弟巅峰的时候排名c站总榜19叫前端小歌谣曾经我花了三年的时间创作了他现在我要用五年的时间超越他今天又是接近兄弟的一天人生难免坎坷大不了从头再来歌谣的意志是永恒的放弃很容易但是坚持一定很酷导语......
  • 一种创新的 Hybird App 技术开发模式
    Hybrid这个词,在App开发领域,相信大家都不陌生。HybridApp是指介于web-app、native-app这两者之间的app,它虽然看上去是一个NativeApp,但只有一个UIWebView,里面访问的是一个WebApp。Hybrid在移动领域的发展,可以说经历了大致3个阶段:1、早期的WebApp(2000年~2010年)在智能手机还未......
  • mongodb副本集模式的单机修改ip(update方式)
    环境:OS:Centos7mongodb:4.4.22 1.停掉当前运行的mongodb/usr/local/services/mongodb/bin/mongolocalhost:29001useadmindb.shutdownServer() 2.网络层面修改ip地址[root@localhostnetwork-scripts]#servicenetworkrestart 3.修改参数修改配置文件,注释掉副本集......
  • 分享 Java 开发中常用到的设计模式(一)
    分享Java开发中常用到的设计模式(一)前言不知道大家在开发的时候,有没有想过(遇到)这些问题:大家都是按需要开发,都是一个职级的同事,为什么有些人的思路就很清晰,代码也很整洁、易懂;而自己开发,往往不知道怎么下手设计,写完了也是bug一堆,codereview的时候更是频频被怼...感觉每天都是......
  • 9、Spring之代理模式
    9.1、环境搭建9.1.1、创建module9.1.2、选择maven9.1.3、设置module名称和路径9.1.4、module初始状态9.1.5、配置打包方式和依赖<?xmlversion="1.0"encoding="UTF-8"?><projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http......