创建型模式-原型模式(五)

目录

原型模式描述

原型模式存在的问题

解决方案

使用场景

优缺点对比

代码


原型模式描述

原型模式是一种创建型设计模式, 使你能够复制已有对象, 而又无需使代码依赖它们所属的类。

原型模式存在的问题

如果你有一个对象, 并希望生成与其完全相同的一个复制品, 你该如何实现呢? 首先, 你必须新建一个属于相同类的对象。 然后, 你必须遍历原始对象的所有成员变量, 并将成员变量值复制到新对象中。

不错! 但有个小问题。 并非所有对象都能通过这种方式进行复制, 因为有些对象可能拥有私有成员变量, 它们在对象本身以外是不可见的。

解决方案

原型模式将克隆过程委派给被克隆的实际对象。 模式为所有支持克隆的对象声明了一个通用接口, 该接口让你能够克隆对象, 同时又无需将代码和对象所属类耦合。 通常情况下, 这样的接口中仅包含一个 克隆方法。

所有的类对 克隆方法的实现都非常相似。 该方法会创建一个当前类的对象, 然后将原始对象所有的成员变量值复制到新建的类中。 你甚至可以复制私有成员变量, 因为绝大部分编程语言都允许对象访问其同类对象的私有成员变量。

支持克隆的对象即为原型。 当你的对象有几十个成员变量和几百种类型时, 对其进行克隆甚至可以代替子类的构造。

其运作方式如下: 创建一系列不同类型的对象并不同的方式对其进行配置。 如果所需对象与预先配置的对象相同, 那么你只需克隆原型即可, 无需新建一个对象。

使用场景

1. 如果你需要复制一些对象, 同时又希望代码独立于这些对象所属的具体类, 可以使用原型模式。

2.如果子类的区别仅在于其对象的初始化方式, 那么你可以使用该模式来减少子类的数量。 别人创建这些子类的目的可能是为了创建特定类型的对象。

优缺点对比

优点缺点
你可以克隆对象, 而无需与它们所属的具体类相耦合克隆包含循环引用的复杂对象可能会非常麻烦
你可以克隆预生成原型, 避免反复运行初始化代码
你可以更方便地生成复杂对象
你可以用继承以外的方式来处理复杂对象的不同配置

图示表达

浅拷贝:只复制对象的基本类型、对象类型、仍然属于原引用,也称为“影子克隆”,引用地址不变;

深拷贝:不止复制对象的基本类,同时也复制原对象中的对象,说完全是就是新对象产生的,也称为“深度克隆”,引用地址变化,就是同一个对象;

代码

1.建立一个控制台程序,代码文件总览。除过深浅拷贝文件

2.抽象原型,ColorPrototype

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp3
{
    public abstract class ColorPrototype   //抽象原型
    {
        public abstract ColorPrototype Clone();    //抽象方法
    }
}

3.具体原型,Color

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp3
{
    class Color : ColorPrototype     //继承抽象的原型
    {
        private int red, green, blue;//定义变量 
        public Color(int red, int green, int blue) //初始化构造函数
        {
            this.red = red;
            this.green = green;
            this.blue = blue;
        }

        public override ColorPrototype Clone()  //重写抽象方法
        {
            return (ColorPrototype)this.MemberwiseClone();    //这是浅拷贝
        }
        public void Display()
        {
            Console.WriteLine("RGB values are: {0},{1},{2}",         //输出对应的颜色
            red, green, blue);
        }
    }
}

4.管理原型,ColorManager

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp3
{
    class ColorManager
    {
        Hashtable colors = new Hashtable();    //定义键值对变量

        public ColorPrototype this[string name]  //定义原型变量
        {
            get { return (ColorPrototype)colors[name]; }
            set { colors.Add(name, value); }
        }
    }
}

5.使用

using System;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApp3
{
    class Program
    {
        static void Main(string[] args)
        {
            ColorManager colormanager = new ColorManager();
            //初始化颜色的值
            colormanager["red"] = new Color(255, 0, 0);
            colormanager["green"] = new Color(0, 255, 0);
            colormanager["blue"] = new Color(0, 0, 255);
            //增加个性化颜色
            colormanager["angry"] = new Color(255, 54, 0);
            colormanager["peace"] = new Color(128, 211, 128);
            colormanager["flame"] = new Color(211, 34, 20);
            // 用户使用颜色
            string colorName = "red";
            Color c1 = (Color)colormanager[colorName].Clone();
            c1.Display();
            colorName = "peace";
            Color c2 = (Color)colormanager[colorName].Clone();
            c2.Display();
            colorName = "flame";
            Color c3 = (Color)colormanager[colorName].Clone();
            c3.Display();



            Console.WriteLine("结束");
        }
    }
}

6. 效果

浅拷贝,ShallowCopy

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp3
{
    class ShallowCopy : ICloneable
    {
        public int[] v = { 1, 2, 3 };
        public Object Clone()
        {
            return this.MemberwiseClone();
        }
        public void Display()
        {
            foreach (int i in v)
                Console.Write(i + ", ");
            Console.WriteLine();
        }
    }
}

深拷贝,DeepCopy

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp3
{
    class DeepCopy : ICloneable
    {
        public int[] v = { 1, 2, 3 };
        // 默认构造函数
        public DeepCopy()
        {
        }
        // 供 Clone 方法调用的私有构造函数
        private DeepCopy(int[] v)
        {
            this.v = (int[])v.Clone();
        }
        public Object Clone()
        {
            // 构造一个新的 DeepCopy 对象,构造参数为
            // 原有对象中使用的 v
            return new DeepCopy(this.v);
        }
        public void Display()
        {
            foreach (int i in v)
                Console.Write(i + ", ");
            Console.WriteLine();
        }
    }
}

效果

  

来源:创建型模式-原型模式(五)_原型模式将克隆的过程委派给被克隆的实际对象中,原型模式为所有支持克隆的对象提_故里2130的博客-CSDN博客

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

故里2130

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值