zoukankan      html  css  js  c++  java
  • 设计模式C#实现(八)——原型模式

    原型模式:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。(要创建一个对象,这个对象为实现原型接口,方法是原型克隆。克隆只是方法而不是原型模式的目的,创建对象才是目的)

    UML类图:

    构成:

    1.原型接口,提供给客户操作,声明一个clone()方法,用于克隆自身创建另一个实例

    2.原型,实现clone()方法,分为浅层克隆和深层克隆。浅层克隆,值类型成员的值相同,但是在内存是存储在不同空间上的,而引用类型成员是相同的引用,即是同一块内存空间,修改其中一个,另一个也随之改变。而深层克隆,不论是值类型还是引用类型,都是不同的内存。

    以电脑为例,先定义电脑接口,包含clone()方法

     interface Computer
        {
            string CPU { get; set; }
            string Memory { get; set; }
            //string GPU { get; set; }
            GPU GPU { get; set; }
            Computer clone();
            Computer deepClone();
        }

    原型实现这个接口,因为.NET所有类都是object的子类,而object类有一个MemberwiseClone()方法返回自身的浅层克隆,所以可以用它实现浅层克隆clone()(自己实现?)。而深层克隆deepClone()是用序列化和反序列化实现的(这个现在还不懂为什么

    class ComputerPrototype : Computer
        {
            private string cpu;
            private string memory;
            private GPU gpu;
            public Computer clone()
            {
                return (Computer)this.MemberwiseClone();
            }
            public Computer deepClone()
            {
                MemoryStream stream = new MemoryStream();
                BinaryFormatter formatter = new BinaryFormatter();
                formatter.Serialize(stream, this);
                stream.Position = 0;
                return formatter.Deserialize(stream) as Computer;
            }
            public override string ToString()
            {
                return CPU + "
    " + Memory + "
    " + GPU.Producer+" "+gpu.Type;
            }
            public GPU GPU
            {
                get { return gpu; }
                set { gpu = value; }
            }
            public string Memory
            {
                get { return memory; }
                set { memory = value; }
            }
            public string CPU
            {
                get { return cpu; }
                set { cpu = value; }
            }
        }

    Computer包含一个类GPU,用来演示浅层和深层克隆的不同,它被标记为可序列化

    [Serializable]
        class GPU
        {
            public GPU(string producer, string type)
            {
                this.Producer = producer;
                this.Type = type;
            }
            public string Producer
            {
                get;
                set;
            }
            public string Type
            {
                get;
                set;
            }
        }

    先实例化一个ComputerPrototype原型,再为它的成员赋值,接下来,通过浅层克隆方法clone()创建一个实例,修改新实例的成员,最后查看两个实例的异同

    class Program
        {
            static void Main(string[] args)
            {
                Computer low = new ComputerPrototype();
                low.CPU = "e3 1231v3";
                low.Memory = "4 G";
                low.GPU = new GPU("凄惨红", "GTX970");
                //Computer high = low.deepClone();
                Computer high = low.clone();
    
                high.GPU.Producer = "高贵的阿苏斯";
                high.Memory = "8 G";
                Console.Write("GPU是否是同一引用:");
                Console.WriteLine(low.GPU == high.GPU);
    
                Console.WriteLine("Low:");
                Console.WriteLine(low.ToString());
                Console.WriteLine("High:");
                Console.WriteLine(high.ToString());
                Console.ReadKey();
            }
        }

    结果如下

    结果表明,两个实例的GPU是同一引用,修改了克隆,原型也被修改了,但是Memory确是各自独立的,修改克隆并不影响原型。

    而将clone()改为执行deepClone()方法结果为

    这表明,两个实例GPU为不同引用,修克隆的GPU和Memory不会影响原型。

    效果:

    1.运行时刻增加和删除产品。运行时注册原型就可以增加新的产品(low是一个新产品)

    2.改变值以指定新对象。减少需要的类的数量(通过改变一些值,创建无数种对象,high为一个新对象)

    3.改变结构以指定新对象。(?)

    4.减少子类的构造。工厂方法,一个产品一个ConcreteCreator,而原型模式不需要

    5.用类动态配置应用。

  • 相关阅读:
    LeetCode 867. 转置矩阵
    LeetCode 26. 删除排序数组中的重复项
    LeetCode 905. 按奇偶排序数组
    LeetCode 922. 按奇偶排序数组 II
    CentOS 7.4 系统安装 git
    浅谈final修饰的变量
    【笔试题】京东2017秋招笔试真题
    【笔试题】在 Java 中,如何跳出当前的多重嵌套循环?
    【面试题】反转单链表
    Windows 系统采用批处理命令修改 ip 地址
  • 原文地址:https://www.cnblogs.com/castdream/p/4817335.html
Copyright © 2011-2022 走看看