设计模式--Prototype模式

也就是原型模式。它是通过已经存在的对象来克隆出一个新的可定制的对象。

 

如果是用Java或C#的话这个过程会简单一点,因为Java的各种类中都有一个clone() 方法,C#中除了clone() 外还有一个MemberwiseClone()方法 可以用来克隆。

官网上说明:

 

 

MemberwiseClone 方法创建一个浅表副本,方法是创建一个新对象,然后将当前对象的非静态字段复制到该新对象。如果字段是值类型的,则对该字段执行逐位复制。如果字段是引用类型,则复制引用但不复制引用的对象;因此,原始对象及其复本引用同一对象。

例如,考虑一个名为 X 的对象,该对象引用对象 A 和 B。对象 B 又引用对象 C。X 的浅表副本创建一个新对象 X2,该对象也引用对象 A 和 B。与此相对照,X 的深层副本创建一个新对象 X2,该对象引用新对象 A2 和 B2,它们分别是 A 和 B 的副本。B2 又引用新对象 C2,C2 是 C 的副本。使用实现 ICloneable 接口的类执行对象的浅表或深层复制。

 

(关于深拷贝和浅拷贝的差别我会再写篇博客详述)

 

这个模式比前几个模式复杂,它主要用于隔离类对象的使用者和具体类型(易变类)之间的耦合关系。。。下面还是通过例子来学。这是从KiddLee的一篇博客中转过来的。这代码是用C#写的。

//我们现在回来看看原型模式的实现,我定义了一个场景,一个人开这一辆车在一条公路上。现在这件事是确定的,但不确定的有几点:1、人:姓名,性别,年龄;2车:什么牌子的;3公路:公路名字,长度,类型(柏油还是土路)。现在我们一个个实现。
//       先来实现人,定义一个抽象类,AbstractDriver,具体实现男性(Man)和女性(Women)
public abstract class AbstractDriver
    {
        public AbstractDriver()
        {
            //
            // TODO: 在此处添加构造函数逻辑
            //
        }
 
        public string name;
        public string sex;
        public int age;
 
        public abstract string drive();
 
        public abstract AbstractDriver Clone();
    }
 
    public class Man:AbstractDriver
    {
        public Man(string strName,int intAge)
        {
            sex = "Male";
            name = strName;
            age = intAge;
        }
 
        public override string drive()
        {
            return name + " is drive";
        }
 
        public override AbstractDriver Clone()
        {
            return (AbstractDriver)this.MemberwiseClone();
        }
    }
 
    public class Women:AbstractDriver
    {
        public Women(string strName,int intAge)
        {
            sex = "Female";
            name = strName;
            age = intAge;
        }
 
        public override string drive()
        {
            return name + " is drive";
        }
 
        public override AbstractDriver Clone()
        {
            return (AbstractDriver)this.MemberwiseClone();
        }
    }
//    注意:抽象代码中有一个Clone的方法,个人认为这个方法是原型模式的一个基础,因为前面讲了原型模式是通过拷贝自身来创建新的对象。
//      下面我们再来实现公路和汽车
//      公路:
public abstract class AbstractRoad
    {
        public AbstractRoad()
        {
            //
            // TODO: 在此处添加构造函数逻辑
            //
        }
 
        public string Type;
        public string RoadName;
        public int RoadLong;
 
        public abstract AbstractRoad Clone();
    }
 
    public class Bituminous:AbstractRoad    //柏油路
    {
        public Bituminous(string strName,int intLong)
        {
            RoadName = strName;
            RoadLong = intLong;
            Type = "Bituminous";
        }
 
        public override AbstractRoad Clone()
        {
            return (AbstractRoad)this.MemberwiseClone();
        }
    }
 
    public class Cement:AbstractRoad        //水泥路
    {
        public Cement(string strName,int intLong)
        {
            RoadName = strName;
            RoadLong = intLong;
            Type = "Cement";
        }
 
        public override AbstractRoad Clone()
        {
            return (AbstractRoad)this.MemberwiseClone();
        }
    }
   
//    汽车:
    public abstract class AbstractCar
    {
        public AbstractCar()
        {
            //
            // TODO: 在此处添加构造函数逻辑
            //
        }
 
        public string OilBox;
        public string Wheel;
        public string Body;
 
        public abstract string Run();
        public abstract string Stop();
 
        public abstract AbstractCar Clone();
    }
 
    public class BMWCar:AbstractCar
    {
        public BMWCar()
        {
            OilBox = "BMW's OilBox";
            Wheel = "BMW's Wheel";
            Body = "BMW's body";
        }
 
        public override string Run()
        {
            return "BMW is running";
        }
 
        public override string Stop()
        {
            return "BMW is stoped";
        }
 
        public override AbstractCar Clone()
        {
            return (AbstractCar)this.MemberwiseClone();
        }
    }
 
    public class BORACar:AbstractCar
    {
        public BORACar()
        {
            OilBox = "BORA's OilBox";
            Wheel = "BORA's Wheel";
            Body = "BORA's Body";
        }
 
        public override string Run()
        {
            return "BORA is running";
        }
 
        public override string Stop()
        {
            return "BORA is stoped";
        }
 
        public override AbstractCar Clone()
        {
            return (AbstractCar)this.MemberwiseClone();
        }
    }
 
    public class VolvoCar:AbstractCar
    {
        public VolvoCar()
        {
            OilBox = "Volvo's OilBox";
            Wheel = "Volvo's Wheel";
            Body = "Volvo's Body";
        }
 
        public override string Run()
        {
            return "Volvo is running";
        }
 
        public override string Stop()
        {
            return "Volvo is stoped";
        }
 
        public override AbstractCar Clone()
        {
            return (AbstractCar)this.MemberwiseClone();
        }
    }
//    然后我们再来看看场景,我们定义一个Manage类,在这个场景中有一个人,一辆车和一条公路,代码实现如下:
class Manage
    {
        public AbstractCar Car;
        public AbstractDriver Driver;
        public AbstractRoad Road;
 
        public void Run(AbstractCar car,AbstractDriver driver,AbstractRoad road)
        {
            Car = car.Clone();
            Driver = driver.Clone();
            Road = road.Clone();
        }
    }
//    可以看到,在这个代码中,场景只是依赖于那几个抽象的类来实现的。最后我们再来实现一下客户代码,比如我现在要一辆Volvo车,一个叫“Anli”的女司机,在一条叫“Road1”、长1000的柏油路上。
        static void Main(string[] args)
        {
            Manage game = new Manage();
            game.Run(new VolvoCar(),new Women("Anli",18),new Bituminous("Road1",1000));
            Console.Write("CarRun:" + game.Car.Run() + "\n");
            Console.Write("DriverName:" + game.Driver.name + "\n");
            Console.Write("DriverSex:" + game.Driver.sex + "\n");
            Console.Write("RoadName:" + game.Road.RoadName + "\n");
            Console.Write("RoadType:" + game.Road.Type + "\n");
            Console.Write("CarStop:" + game.Car.Stop() + "\n");
            Console.Read();
        }
    运行的结果是:
    CarRun:Volvo is running
DriverName:Anli
DriverSex:Female
RoadName:Road1
RoadType:Bituminous
CarStop:Volvo is stoped
 
如果我现在想换成BORA车,让我(kid-li)开,在一个水泥马路上,我们只要更改Main函数中Run的实参。
game.Run(new BORACar(),new Man("kid-li",24),new Cement("Road1",1000));
运行结果是:
CarRun:BORA is running
DriverName:kid-li
DriverSex:Male
RoadName:Road1
RoadType:Cement
CarStop:BORA is stoped
这样,经过简单的更改,可以实现实现细节的变化。
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值