• 设计模式(单例模式+原型模式)+ c#的内存分配机制


    设计模式:OOP语言开发过程中,遇到种种场景和问题,提出的解决方案
     -----设计模式,其实就是解决问题的套路

    1.设计模式包含三种类型:

    创造型设计模式:

      关注对性的创建--三大工厂+创造者+单例+原型
      即使是一个简单的对象复用,都有很多招数

    结构型设计模式
    行为型设计模式

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

    /// <summary>
    /// 单例类
    /// </summary>
    public class StudentSington
    {
    /// <summary>
    /// 1.构造器函数私有化--避免随意构造
    /// </summary>
    private StudentSington()
    {
    Thread.Sleep(2000);
    long lReasult = 0;
    for (int i = 0; i < 1000000; i++)
    {
    lReasult += i;
    }
    Console.WriteLine("{0}被构造.", this.GetType().Name);
    }

    /// <summary>
    /// 2.私有的静态字段--内存唯一,不会释放,在第一次使用这个类时被初始化,且只初始化一次
    /// </summary>
    private static StudentSington studentSington = new StudentSington() { Id = 1, Name = "StudentA" };

    /// <summary>
    /// 3.公开的静态方法来提供实例
    /// </summary>
    /// <returns></returns>
    public static StudentSington GetInstance()
    {
    if (studentSington != null)
    return studentSington;
    else
    {
    studentSington = new StudentSington() { Id = 1, Name = "StudentA" };
    return studentSington;
    }
    }

    public int Id { get; set; }
    public string Name { get; set; }

    public void Study()
    {
    Console.WriteLine($"{this.Name}正在学习,请勿扰");
    }
    }

    测试:

    //不同的方法/类/线程/类库的重用? ---单例模式:保证整个进程中,该对象只有一个实例
    //单例在整个进程中只有一个实例--不能出来呢2个学生,--如果两个学生都写个了某个属性,后一个会覆盖前一个
    for (int i = 0; i < 5; i++)
    {
    StudentSington student = StudentSington.GetInstance();
    student.Study();
    }
    Console.ReadLine();

    3.原型模式:利用对象Copy,快速获取对象。需要大量的新对象的时候可以用原型模式

    /// <summary>
    /// 原型模式
    /// </summary>
    public class StudentPrototype
    {
    /// <summary>
    /// 1.构造器函数私有化--避免随意构造
    /// </summary>
    private StudentPrototype()
    {
    Thread.Sleep(2000);
    long lReasult = 0;
    for (int i = 0; i < 1000000; i++)
    {
    lReasult += i;
    }
    Console.WriteLine("{0}被构造.", this.GetType().Name);
    }

    /// <summary>
    /// 2.私有的静态字段--内存唯一,不会释放,在第一次使用这个类时被初始化,且只初始化一次
    /// </summary>
    private static StudentPrototype student = new StudentPrototype() { Id = 1, Name = "StudentA", Class = new Class() { ClassId = 1, ClassName = ".net高级班" } };

    /// <summary>
    /// 3.公开的静态方法来提供实例
    /// </summary>
    /// <returns></returns>
    public static StudentPrototype GetInstance()
    {
    //student.MemberwiseClone是在堆内存中直接拷贝,不走构造函数,所以没有性能损失,而且产生的是新对象
    //student.MemberwiseClone是浅拷贝,浅拷贝是指只拷贝引用
    StudentPrototype studentPrototype = (StudentPrototype)student.MemberwiseClone();

    return studentPrototype;
    }


    public int Id { get; set; }
    public string Name { get; set; }

    public Class Class { get; set; }

    public void Study()
    {
    Console.WriteLine($"{this.Name}正在学习,请勿扰");
    }
    }

    public class Class
    {
    public int ClassId { get; set; }
    public string ClassName { get; set; }
    }

    测试代码:

    //单例可以对象复用--但是会出现属性覆盖
    //修改使其实现不覆盖,又可以复用对象,且性能高-->原型模式
    for (int i = 0; i < 5; i++)
    {
    StudentPrototype student = StudentPrototype.GetInstance();
    student.Study();
    }
    StudentPrototype student1 = StudentPrototype.GetInstance();
    student1.Name = "student1";
    StudentPrototype student2 = StudentPrototype.GetInstance();
    student2.Name = "student2";
    student1.Study();
    student2.Study();
    Console.ReadLine();

    4.深拷贝和浅拷贝

    4.1)浅拷贝和深拷贝

     4.2 深拷贝的三种方式:

      4.2.1.直接New
      4.2.2.子类提供原型方式
      4.2.3.基于序列化反序列化:
        4.2.3.1当前类和子类都要用序列化属性标记
        4.2.3.2 调用深度克隆的序列化方法

    /// <summary>
    /// 原型模式
    /// </summary>
    public class StudentPrototype
    {
    /// <summary>
    /// 1.构造器函数私有化--避免随意构造
    /// </summary>
    private StudentPrototype()
    {
    Thread.Sleep(2000);
    long lReasult = 0;
    for (int i = 0; i < 1000000; i++)
    {
    lReasult += i;
    }
    Console.WriteLine("{0}被构造.", this.GetType().Name);
    }

    /// <summary>
    /// 2.私有的静态字段--内存唯一,不会释放,在第一次使用这个类时被初始化,且只初始化一次
    /// </summary>
    private static StudentPrototype student = new StudentPrototype() { Id = 1, Name = "StudentA", Class = new Class() { ClassId = 1, ClassName = ".net" } };

    /// <summary>
    /// 3.公开的静态方法来提供实例
    /// </summary>
    /// <returns></returns>
    public static StudentPrototype DeepClone()
    {
    return SerializableHelper.DeepClone<StudentPrototype>(student);
    }

    public int Id { get; set; }
    public string Name { get; set; }

    public Class Class { get; set; }

    public void Study()
    {
    Console.WriteLine($"{this.Name}正在学习,请勿扰");
    }
    }

    public class Class
    {
    public int ClassId { get; set; }
    public string ClassName { get; set; }
    }


    public class SerializableHelper
    {
    public static string Serializable(Object target)
    {
    using (MemoryStream stream = new MemoryStream())
    {
    new BinaryFormatter().Serialize(stream, target);
    return Convert.ToBase64String(stream.ToArray());
    }
    }

    public static T Deriallizable<T>(string target)
    {
    byte[] targetArray = Convert.FromBase64String(target);
    using (MemoryStream stream = new MemoryStream())
    {
    return (T)(new BinaryFormatter().Deserialize(stream));
    }
    }

    public static T DeepClone<T>(T t)
    {
    return Deriallizable<T>(Serializable(t));
    }
    }

    5. c#的内存分派机制

    StudentPrototype student1 = StudentPrototype.GetInstance();
    //student1.Name = "student1";等同于new String(""student1""),相当于开辟新空间,不会影响其他的,实际上string类型是不可修改的,所以当创建多个student之后,修改Name的值,都是互不影响的

      2.1)c#内存分为:

    进程堆(进程唯一.每个网站打开都有一个进程堆)
    线程栈(每个线程一个)
    引用类型在堆里,引用类型里面的值类型在堆里
    值类型在栈中, 引用类型的变量和值类型的变量在栈中
    值类型对应的引用类型--Custom.Name在堆里面(任何引用类型的值都在堆里面)

    /// <summary>
    /// 结构体是值类型,Custom.Name就是值类型中的引用类型
    /// </summary>
    public struct Custom
    {
    public string Name;
    }


    总结:

    所有的引用类型的值一定在堆里面,
    值类型如果是变量对应的值在栈里面,
    如果是引用类型里面包裹的值类型,他的值在栈里面

  • 相关阅读:
    计划任务
    Crontab 定时任务格式参数
    Nginx 内核优化
    AC自动机
    Benelux Algorithm Programming Contest 2017(D)
    BAPC2017
    2018.9青岛网络预选赛(K)
    2018.9青岛网络预选赛
    2018.9青岛网络预选赛(A)
    2018.9青岛网络预选赛(C)
  • 原文地址:https://www.cnblogs.com/fblogs/p/12307342.html
Copyright © 2020-2023  润新知