设计模式-1、简单工厂模式

前言:关于设计模式的内容均是学习心得,请适当参考,不对之处请指正。
应该有很多人跟我一样,coding到一定阶段,总想学下设计模式,提升下能力的级别,但学习过程中,那些书本上的,blog上的都能看得懂,但却很难在实际开发用应用起来。而我现在的感悟是:应该一个个模式慢慢地学,先将面对对象的封装继承多态加深理解,在看完一个设计模式的时候,coding出来,并在coding过程中思考。coding完后,不要急燥,想想以后将怎么用上。

简单工厂模式和单例模式是最易被理解的。

先回忆下,什么时候用虚方法、抽象类、接口?

虚方法:类在业务中是实际已知存在,有真实意思的(其子类当然也有意义),例如有普通固定电话、IP固定电话、传真电话,实际业务中,假定普通固定电话是有意义的,同时可以作为IP电话、传真电话的父类,那么固定电话的MakeCall方法,就可以设计成虚方法。

抽象类:当事务只是一个抽象概念,具体的事情根本不知怎么做的时候用的。例如一个系统中有两种订单(后面可能更多),手机订单和服务订单,那么订单就是一个抽象概念,叫下个订单,实际中根本不知往哪去下。所以应该定义为抽象类,不能实例化,其子类(就那两种订单)也必需去override其抽象方法。以下例子就是用抽象类去实现简单工厂模式滴。

接口:更为抽象,当遇到几类相似的事物,却又抽象不出一个父类,他们之前却有一些共同的地方时就用接口吧。例如一套普通的公司内部使用的系统,大多数表都会有简单的CRUD(增删改查),这就是抽象不出它们有父类,却有共同的特性,这时候,定义一个接口ICRUDAble,让需要增删改查的数据模式都继承自它最合适了,当然这个例子说法上,很难体现它的好处,反而让接口成了个死规矩。

ok,复习完成,简单工厂模式上代码。

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

namespace _1_简单工厂模式
{
    class Program
    {
        static void Main(string[] args)
        {

            #region 不是那么优雅的写法,这就体现不出设计模式的思想出来
            //Order order = null;
            //Console.WriteLine("你要下什么订单?mobile:手机订单;service服务订单");
            //string input = Console.ReadLine();
            //switch (input)
            //{
            //    case "mobile":
            //        order = new MobilePhoneOrder();
            //        break;
            //    case "service":
            //        order = new ServiceOrder();
            //        break;
            //    default:
            //        Console.WriteLine("非法订单");
            //        return;
            //}
            //order.Add();
            //Console.ReadKey(); 
            #endregion


            #region 利用上简单工厂模式的写法


            Console.WriteLine("你要下什么订单?mobile:手机订单;service服务订单");
            string input = Console.ReadLine();
            Order order = OrderFactory.CreateOrderSimplyFactory(input);
            if (null==order)
            {
                //突然想说,以前搞不懂设计模式的一大原因,就是书上的用例多少有点牵强,也很难在实际工厂中联想应用到哪里可以用上。
                //就连这个null==order那些大神们都不写,看多了自然会对这个世界产生怀疑,虽然我知道用意是想突出设计模式。
                return;
            }
            order.Add();
            Console.ReadKey();


            #endregion
        }

        /// <summary>
        /// 订单是一样很抽象的东西,因为不知是什么类型的订单,所以不能有个具体的Add方法
        /// 否则就可以用普通类,Add方法用virtual就够
        /// 因为见到《大话设计模式》中,介绍简单工厂的时候,用基类是普通因。将实现多态的方法用虚方法去实现了
        /// </summary>
        public abstract class Order
        {
            public abstract void Add();
            //这里应该有订单的属性
        }

        public class MobilePhoneOrder : Order
        {
            public override void Add()
            {
                Console.WriteLine("手机订单已经下达成功,我做了伟大的持久化保存");
            }
        }
        public class ServiceOrder : Order
        {
            public override void Add()
            {
                Console.WriteLine("服务订单已经下达成功,这时候应该通知人员进行服务");
            }
        }

        public class OrderFactory
        {
            public static Order CreateOrderSimplyFactory(string name)
            {
                Order order = null;
                switch (name)
                {
                    case "mobile":
                        order = new MobilePhoneOrder();
                        break;
                    case "service":
                        order = new ServiceOrder();
                        break;
                    default:
                        break;
                }
                return order;
            }
        }
    }
}

讲解:
order类为MobileOrder、ServiceOrder的父类,都有统一的Add方法,
而业务中,需要根据订单类型,针对两种不同订单对不用的添加操作。
那就是用父类order接收对象的创建,其Add方法的调用就不需要改动了,没错,就是为了让Add方法不用修改,动了这么大工夫。
这时候,马上也会怀疑人生:如果再多一种订单业务出来,switch那里还是得改,是的,我也很它很不顺眼,但至少,逻辑调用的时候,不再需要做改变了。比什么设计模式什么思想都没有的if switch去实现要进步了好多。

      最后补充:订单本身是抽象的,在实际业务中没有意义,所以它应该是抽象的,说到大话设计模式一书中,讲解大话设计模式用的是虚方法,个人认为,这同样可以,得看实际业务中父类有没有意义,并且在switch中,应该也能把父类也给生产出来。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值