原型模式

目录

一、原型模式

二、原型模式角色

三、代码实例一

四、代码实例二

         五、代码实例三

 UML图


一、原型模式

通过给出一个原型对象来指明所要创建的对象类型。然后复制这个原型对象来创建更多的同类型对象。

用原型实例创建对象的种类,并且通过拷贝这些原型创建新的对象。

应用场景:

1、需要从一个对象出发,得到若干个和其他状态相同,并可以相互独立变化状态的对象。

2、对象创建和对象构建独立。

PROS AND CONS

PROS

1、允许动态增加或减少产品类,创建产品类对象实例的方法是产品类内部具有的,增加新的产品对结构没有影响。

2、提供了简化的创建结构。

CONS

1、每个原型的子类必须实现Clone接口。

2、包含引用类型对象时要实现深复制,比较麻烦。

二、原型模式角色

1、客户角色:提出创建对象请求

2、抽象原型:抽象类,给出具体原型所需要的接口。在C#中,抽象原型通常实现ICloneable接口。

3、具体原型:被复制的对象,实现抽象类接口。

三、代码实例一

原型模式类似于c++中的深浅拷贝,通过一个原型对象来复制出其他的同类型对象。

利用c#中的ICloneable接口,我们可以实现浅复制,但当数据比较复杂,例如有引用类型,这事要利用深复制来完成功能。

例如一个简历类代码实例:

第一个类是工作经验类

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

namespace 原型模式一
{
    class WorkExperience : ICloneable
    {
        private string workDate;
        private string workCompany;

        public WorkExperience(string workDate, string workCompany)
        {
            this.workDate = workDate;
            this.workCompany = workCompany;
        }

        public string WorkDate
        {
            get { return workDate; }
            set { workDate=value; }
        }
        public string WorkCompany
        {
            get { return workCompany; }
            set { workCompany = value; }
        }
        public object Clone()
        {
            return (Object)(this.MemberwiseClone());
        }
    }
}

第二个类是简历类,里面包含工作经验类对象,并完成深复制功能。

要仔细体会一下这里的写法,感觉很巧妙。

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

namespace 原型模式一
{
    class Resume : ICloneable
    {
        private string name;
        private string age;
        private string major;
        private WorkExperience work;
        public Resume(string name)
        {
            this.name = name;
        }
        private Resume(WorkExperience work)
        {
            this.work = (WorkExperience)work.Clone();
        }
        public void SetPersonalInfor(string age,string major)
        {
            this.age = age;
            this.major = major;
        }
        public void SetWorkExperience(WorkExperience work)
        {
            this.work = work;                                                                                               
        }
        public void show()
        {
            Console.WriteLine("{0},{1},{2}", name, age, major);
            Console.WriteLine("工作经历:{0},{1}", work.WorkDate, work.WorkCompany);
        }
        public object Clone()
        {
            Resume obj = new Resume(this.work );
            obj.name = this.name;
            obj.age = this.age;
            obj.major = this.major;
            return obj;
        }
    }
}

接着是测试类

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

namespace 原型模式一
{
    class Program
    {
        static void Main(string[] args)
        {
            Resume Pa = new Resume("小李");
            Pa.SetPersonalInfor("19", "计算机");
            Pa.SetWorkExperience(new WorkExperience ("1999-2002", "百度"));
            Resume Pb = (Resume)Pa.Clone();
            Pb.SetPersonalInfor("18", "数学");
            Pb.SetWorkExperience(new WorkExperience("2001-2007", "腾讯"));
            Pa.show();
            Pb.show();
        }
    }
}

四、代码实例二

抽象原型类

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

namespace PrototypeOne
{
    abstract class Prototype
    {
        private string id;

        protected Prototype(string id)
        {
            this.Id = id;
        }

        public string Id { get => id; set => id = value; }
        abstract public Prototype Clone(); 
    }
}

具体原型类: 

 

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

namespace PrototypeOne
{
    class ConcretePrototypeOne : Prototype
    {
        public ConcretePrototypeOne(string id) : base(id) { }
        public override Prototype Clone()
        {
            return (Prototype)this.MemberwiseClone();
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PrototypeOne
{
    class ConcretePrototypeTwo : Prototype
    {
        public ConcretePrototypeTwo(string id):base(id){}
        public override Prototype Clone()
        {
            return (Prototype)this.MemberwiseClone();
        }
    }
}

 测试:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace PrototypeOne
{
    static class Program
    {
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main()
        {
            ConcretePrototypeOne c1 = new ConcretePrototypeOne("99");
            ConcretePrototypeOne c11 = (ConcretePrototypeOne)c1.Clone();
            Console.WriteLine("::{0}", c11.Id);

        }
    }
}

五、代码实例三

订单处理系统 现在有一个订单处理系统,里面有一个保存订单的业务功能,需求:每当订单的预定产品数量超过1000的时候,就需要把订单拆成两份订单来保存。如果拆成两份后还是超过1000,则继续拆分,直到每份产品预订数量不超过1000. 根据业务,目前的订单系统分成两种,一种是个人订单、一种是公司订单。 客户名称、产品对象(ID,Name),订购产品数量。 公司名称、产品对象(ID,Name),订购产品数量

订单接口:

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

namespace PrototypeTwo
{
    abstract class Order:ICloneable
    {
        abstract public void SetInformation(string name,int num);
        abstract public void SetProductInformation(string name, int id);
        abstract public void Show();
        abstract public Object Clone();
        abstract public int GetNum();
        abstract public string GetName();
    }
}

 订单类:

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

namespace PrototypeTwo
{
    class CompanyOrder : Order
    {
        private string name;
        private int num;
        private Product product;

        public CompanyOrder(string name, int num)
        {
            product = new Product();//注意初始化
            this.name = name;
            this.num = num;
        }
        private CompanyOrder(Product p)
        {
            this.product = (Product)p.Clone();//
        }

        public override object Clone()
        {
            CompanyOrder com = new CompanyOrder(this.product);//
            com.name = name;
            com.num = num;
            return com;
        }

        public override string GetName()
        {
            return name;
        }

        public override int GetNum()
        {
            return num;
        }

        public override void SetInformation(string name, int num)
        {
            this.name = name;
            this.num = num;
        }

        public override void SetProductInformation(string name, int id)
        {
            this.product.Name = name;
            this.product.Id = id;
        }

        public override void Show()
        {
            Console.WriteLine("所属者:{0} 数量:{1}", name, num);
        }
    }
}

产品类:

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

namespace PrototypeTwo
{
    class Product
    {
        private int id;
        private string name;

        public Product()
        {
        }

        public Product(string name, int id)
        {
            this.Id = id;
            this.Name = name;
        }

        public int Id { get => id; set => id = value; }
        public string Name { get => name; set => name = value; }
        public Object Clone()
        {
            return (Object)this.MemberwiseClone();
        }
    }
}

 订单处理类:

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

namespace PrototypeTwo
{
    class OrderMan
    {
        private Order order;
        private List<Order> list = new List<Order>();
        public OrderMan(Order order)
        {
            this.order = order;
        }
        public void Process()
        {
            int len = order.GetNum();
            while(len>1000)
            {
                len -= 1000;
                CompanyOrder c11 = (CompanyOrder)order.Clone();
                c11.SetInformation(order.GetName(), 1000);
                list.Add(c11);
            }
            order.SetInformation(order.GetName(), len);
            list.Add(order);
        }
        public void Show()
        {
            foreach(Order o1 in list)
            {
                o1.Show();
            }
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace PrototypeTwo
{
    static class Program
    {
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main()
        {
            CompanyOrder c1 = new CompanyOrder("阿里",7503);
            c1.SetProductInformation("A", 1);//不要忘了
            int num = c1.GetNum();
            OrderMan o = new OrderMan(c1);
            o.Process();
            o.Show();
            //while(num>1000)
            //{
            //    CompanyOrder c11 = (CompanyOrder)c1.Clone();
            //    c11.SetInformation(c1.GetName(), 1000);
            //    num -= 1000;
            //    c11.Show();
            //}
            //Console.WriteLine("------");
            //c1.SetInformation(c1.GetName(), num);
            //c1.Show();
            //k  --c+u
        }
    }
}

 

 UML图

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值