zoukankan      html  css  js  c++  java
  • 原型模式(Prototype Pattern)

    1、概述

    在软件系统中,有时候面临的产品类是动态变化的,而且这个产品类具有一定的等级结构。这时如果用工厂模式,则与产品类等级结构平行的工厂方法类也要随着这种变化而变化,显然不大合适。那么如何封装这种动态的变化?从而使依赖于这些易变对象的客户程序不随着产品类变化?

    2、意图

    原型模式是通过现有的一个对象,复制出更多的此类型的对象以供使用。

    3、结构图

    截图01

    图解说明

    UsePrototype类是用户类也是程序启动类

    RGBColor类是一个颜色类

    ColorPrototype类是抽象类,含有Clone方法

    ConcretePrototype 类继承ColorPrototype,实现浅拷贝。

    ConcretePrototypeDeep类继承ColorPrototype,实现深拷贝

    关于深拷贝和浅拷贝简单的说:

    浅拷贝(Shallow Copy影子克隆):只复制对象的基本类型。对象类型,仍属于原来的引用。
    深拷贝(Deep Copy 深度克隆):不仅复制对象的基本类,同时也复制原对象中的对象.完全产生新对象。

    4、代码的实现

    注意:代码中的深拷贝是使用序列化实现的。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Runtime.Serialization.Formatters.Binary;
    using System.IO;
    
    namespace PrototypePattern
    {
        [Serializable]
        public abstract class ColorPrototype
        {
            public abstract ColorPrototype Clone();
        }
        [Serializable]
        public class RGBColor
        {
            /// <summary>
            /// 颜色的三色素:红、绿、兰
            /// </summary>
            private int _red,_green,_blue;
            public RGBColor(int red, int green, int blue)
            {
                this._red = red;
                this._green = green;
                this._blue = blue;
            }
            public int RED
            {
                get
                {
                    return this._red;
                }
                set
                {
                    this._red = value;
                }
            }
            public int GREEN
            {
                get
                {
                    return this._green;
                }
                set
                {
                    this._green = value;
                }
            }
            public int BLUE
            {
                get
                {
                    return this._blue;
                }
                set
                {
                    this._blue = value;
                }
            }
        }
        /// <summary>
        /// 实现浅拷贝
        /// </summary>
        public class ConcretePrototype  :ColorPrototype
        {
            /// <summary>
            /// 长、宽、高
            /// </summary>
            private int _lenth, _hign, _wide;
            private RGBColor _color = null;
            /// <summary>
            /// 构造函数
            /// </summary>
            /// <param name="length"></param>
            /// <param name="hign"></param>
            /// <param name="wide"></param>
            public ConcretePrototype(int length, int hign, int wide,RGBColor color)
            {
                this._wide = wide;
                this._lenth = length;
                this._hign = hign;
                this._color = color;
            }
            public void SetRectangle(int length, int hign, int wide)
            {
                this._lenth = length;
                this._wide = wide;
                this._hign = hign;
            }
            public RGBColor SGRGBColor
            {
                set
                {
                    this._color = value;
                }
                get
                {
                    return this._color;
                }
            }
            /// <summary>
            /// 浅拷贝,只复制对象的基本类型.对象类型,仍属于原来的引用.
            /// </summary>
            /// <returns></returns>
            public override ColorPrototype Clone()
            {
                //创建当前ConcretePrototype的浅拷贝
                return (ColorPrototype)this.MemberwiseClone();
            }
            /// <summary>
            /// 将对象的信息显示出来
            /// </summary>
            public void Display()
            {
                //注意this._lenth, this._hign, this._wide是值类型
                Console.WriteLine("This rectangle's area: ({0},{1},{2})", this._lenth, this._hign, this._wide);
                //注意this._color是引用类型
                Console.WriteLine("This rectangle's color: ({0},{1},{2})", this._color.RED,this._color.GREEN,this._color.BLUE);
            }
        }
       /// <summary>
       /// 深拷贝
       /// </summary>
        [Serializable]
        public class ConcretePrototypeDeep : ColorPrototype
        {
    
            /// <summary>
            /// 长、宽、高
            /// </summary>
            private int _lenth, _hign, _wide;
            private RGBColor _color = null;
            /// <summary>
            /// 构造函数
            /// </summary>
            /// <param name="length"></param>
            /// <param name="hign"></param>
            /// <param name="wide"></param>
            public ConcretePrototypeDeep(int length, int hign, int wide, RGBColor color)
            {
                this._wide = wide;
                this._lenth = length;
                this._hign = hign;
                this._color = color;
            }
            public void SetRectangle(int length, int hign, int wide)
            {
                this._lenth = length;
                this._wide = wide;
                this._hign = hign;
            }
            public RGBColor SGRGBColor
            {
                set
                {
                    this._color = value;
                }
                get
                {
                    return this._color;
                }
            }
            /// <summary>
            /// 深度拷贝,不仅复制对象的基本类,同时也复制原对象中的对象.完全产生新对象。
            /// </summary>
            /// <returns></returns>
            public override ColorPrototype Clone()
            {
                MemoryStream stream = new MemoryStream();
                BinaryFormatter formatter = new BinaryFormatter();
                formatter.Serialize(stream, this);
                stream.Position = 0;
                return (ColorPrototype)formatter.Deserialize(stream);
            }
            public void Display()
            {
                Console.WriteLine("This rectangle's area: ({0},{1},{2})", this._lenth, this._hign, this._wide);
                Console.WriteLine("This rectangle's color: ({0},{1},{2})", this._color.RED,this._color.GREEN,this._color.BLUE);
            }
        }
        public class UsePrototype
        {
            public static void Main(string[] args)
            {
                Console.WriteLine("======   ====== 浅拷贝 ======   ======");
                ColorPrototype colorPrototype = new ConcretePrototype(100, 200, 300,new RGBColor(20,100,130));
                Console.WriteLine("原对象信息为:");
                ((ConcretePrototype)colorPrototype).Display();
                ColorPrototype colorPrototypeClone = colorPrototype.Clone();
    
                ((ConcretePrototype)colorPrototypeClone).SetRectangle(150, 250, 350);
                ((ConcretePrototype)colorPrototypeClone).SGRGBColor.RED = 30;
                ((ConcretePrototype)colorPrototypeClone).SGRGBColor.GREEN = 120;
                ((ConcretePrototype)colorPrototypeClone).SGRGBColor.BLUE = 100;
                Console.WriteLine("拷贝对象信息改变后为:");
                ((ConcretePrototype)colorPrototypeClone).Display();
                Console.WriteLine("只复制对象的基本类型.对象类型,仍属于原来的引用");
                ((ConcretePrototype)colorPrototype).Display();
    
                Console.WriteLine("======   ======   深拷贝   ======   ======");
                colorPrototype = new ConcretePrototypeDeep(100, 200, 300, new RGBColor(20, 100, 130));
                Console.WriteLine("原对象信息为:");
                ((ConcretePrototypeDeep)colorPrototype).Display();
                colorPrototypeClone = colorPrototype.Clone();
    
                ((ConcretePrototypeDeep)colorPrototypeClone).SetRectangle(150, 250, 350);
                ((ConcretePrototypeDeep)colorPrototypeClone).SGRGBColor.RED = 30;
                ((ConcretePrototypeDeep)colorPrototypeClone).SGRGBColor.GREEN = 120;
                ((ConcretePrototypeDeep)colorPrototypeClone).SGRGBColor.BLUE = 100;
                Console.WriteLine("拷贝对象信息改变后为:");
                ((ConcretePrototypeDeep)colorPrototypeClone).Display();
                Console.WriteLine("不仅复制对象的基本类,同时也复制原对象中的对象.完全产生新对象。");
                ((ConcretePrototypeDeep)colorPrototype).Display();
            }
        }
    }
    

    5、运行结果

    result1

    可以看出,浅拷贝中,拷贝对象中的引用对象(RGBColor类对象)与原对象中的对应的引用对象(RGBColor类对象)指向同一个内存地址,而值信息则拷贝对象有一个另外的拷贝。

    深拷贝中值变量和引用变量都重新开辟了一个内存,所以拷贝对象与原对象中的变量间所在的内存不一样。

  • 相关阅读:
    android Context 持有导致的内存泄漏
    android PreferenceFragment
    android 修改 SwitchPreferenceCompat 高度,内边距,字体大小
    Android MPAndroidChart RadarChart (蜘蛛网图)
    Bugtags 测试平台(支持ios、android)
    BlockCanary 一个轻量的,非侵入式的性能监控组件(阿里)
    RecyclerView item 状态错乱
    RecyclerView android:layout_width="match_parent" 无效
    android-async-http cancelRequests
    Android MultiDex
  • 原文地址:https://www.cnblogs.com/smallstone/p/1673721.html
Copyright © 2011-2022 走看看