简单工厂模式

          简单工厂模式,用一句话概括其特性:使用子类继承并重写父类的方法,在实例化时,通过用户输入的参数,使用父类的实例化子类方法,返回相对应的子类,并访问该子类的属性及方法;

         打个比方,我们去超市买可乐,有的人喜欢百事可乐,有的人喜欢可口可乐,那我们买可乐的过程用代码表示出来是什么样的?看看下面的代码:

    /// <summary>
    /// 可口可乐
    /// </summary>
    public class KeKou
    {
        public string KeLe()
        {
            return "I'm KeKouKeLe";
        }
    }

    /// <summary>
    /// 可口可乐
    /// </summary>
    public class BaiShi
    {
        public string KeLe()
        {
            return "I'm BaiShiKeLe";
        }
}

那么我们在超市里面买可乐的过程用代码表示出来应该是什么样的?我想应该是这样的:

            //购买百事可乐的过程
            BaiShi baiShi = new BaiShi();
            string keLe = baiShi.KeLe();

            //购买可口可乐的过程
            KeKou keKou = new KeKou();
            string keLe = keKou.KeLe();

通过上面的代码,我们分别拿到了百事可乐和可口可乐;

忽然有一天我们出差了,要买可乐,但是在外面找不到超市,只有自动售贩机,这下习惯在超市买东西的同志们犯难了,以前可以直接把东西拿出来,现在不行了,只能通过售贩机帮你取出来,经过研究,发现自动售贩机的使用流程是这样的:先把钱投到售贩机里面,如果我们要百事可乐,就按1号键,如果我们要可口可乐,就按2号键,这个流程怎么表示出来呢?我想应该是下面这样的:


 我们告诉售贩机需要什么样的可乐,售贩机将我们需要的可乐吐出来;我想实现的代码应该是下面的样子:

    /// <summary>
    /// 可乐
    /// </summary>
    public class Cola
    {
        public virtual string KeLe()
        {
            return "I'm KeLe";
        }

        public Cola GetKeLe(int index)
        {
            switch (index)
            { 
                case 1:
                    return new BaiShi();
                default :
                    return new KeKou();
            }
        }
}

    下面的百事和可口继承可乐,代码如下:

    /// <summary>
    /// 可口可乐
    /// </summary>
    public class KeKou:Cola
    {
        public override string KeLe()
        {
            return "I'm KeKouKeLe";
        }
    }

    /// <summary>
    /// 百事可乐
    /// </summary>
    public class BaiShi:Cola
    {
        public override string KeLe()
        {
            return "I'm BaiShiKeLe";
        }
}

那么客户端的代码应该为:

Cola cola = new Cola();

       cola = cola.GetKeLe(1);

    cola.KeLe();

上面的代码是不是很别扭?首先实例化了一个Cola类,然后将该实例的指向转为cola.GetKeLe(1),这里是简单工厂需要注意的地方之一:Cola cola = new Cola()代码实例化了一个Cola对象,该对象拥有的是Cole的属性和方法,与子类没有任何关系,所以此时通过cola访问不到任何与子类相关的内容;cola = cola.GetKeLe(1)代码实际上做了两件事情,首先是根据用户输入的参数实例化子类,然后将cola实例的指向转到刚才生成的子类上,所以此时即可通过cola访问子类的相关内容;

上面说到了这么写难看,那么我们怎么改一下?代码如下:

    /// <summary>
    /// 可乐工厂
    /// </summary>
    public class Cola
    {
        public virtual string KeLe()
        {
            return "I'm KeLe";
        }

        public static Cola GetKeLe(int index)
        {
            switch (index)
            {
                case 1:
                    return new BaiShi();
                default:
                    return new KeKou();
            }
        }
}

上面的代码只是在工厂类的创建对象方法上添加了一个关键字:static,使这个方法变为静态方法,同时改变了该方法的访问模式:通过类可以直接访问该方法,而不需要通过类的实例访问;修改后我们再看看客户端上应该怎样访问:

            Colacola = Cola.GetKeLe(1);

        cola.KeLe();

上面的代码不仅更符合逻辑,也更贴近真实的情况;

另外在简单工厂方法中还有一点需要注意,父类的方法必须提供为虚方法,继承父类的子类对父类虚方法进行重写,我们来看看下面的代码:

父类:

    /// <summary>
    /// 可乐工厂
    /// </summary>
    public class Cola
    {
        public virtual string KeLe()
        {
            return "I'm KeLe";
        }

        public static Cola GetKeLe(int index)
        {
            switch (index)
            {
                case 1:
                    return new BaiShi();
                default:
                    return new KeKou();
            }
        }
}

子类:

    /// <summary>
    /// 可口可乐
    /// </summary>
    public class KeKou : Cola
    {
        public new string KeLe()
        {
            return "I'm KeKouKeLe";
        }
    }

    /// <summary>
    /// 可口可乐
    /// </summary>
    public class BaiShi : Cola
    {
        public new string KeLe()
        {
            return "I'm BaiShiKeLe";
        }
}

此时通过客户端代码访问:

            Colacola = Cola.GetKeLe(1);

        cola.KeLe();

得到的解决是我们访问了父类中的方法,这里需要弄清楚两个关键字的用途:new和override;

Msdn上这么解释的,new:用于向基类成员隐藏继承成员;override:修饰符用于重写基类中方法的方法,当基类不包含具有相同签名的成员时,不得将 override 修饰符用于方法;


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值