工厂模式怎么用?举例说明

工厂模式主要用于创建对象。
它的好处:

  • 调用者获取对象简单,它封装了创建对象的逻辑;
  • 易于扩展;
  • 扩展不影响调用者;

例子说明:假设京东在广州,上海有两个货物仓库,发货时就近原则。
扩展要求:会在其它地方增加仓库;
为了关注点在模式的使用,假设不存在一个仓库没货,需从另一个仓库发货的情况;

例子代码:
先建Model,顾客(Client)

    public class Client
    {
        public Guid userID { get; set; }
        public string postCode { get; set; }
        public string address { get; set; }
    } 

仓库接口,只有发货方法:

    public interface StorageInterface
    {
        bool send(Client client);
    }

广州仓库:

   public class GuangZhou : StorageInterface
    {
       public bool send(Client client)
        {
            //广州仓库发货...
            return true;
        }
    }

上海仓库:

    public class ShangHai :StorageInterface
    {
        public bool send(Client client)
        {
            //上海仓库发货...
            return true;
        }
    }  

发货工厂类:

    public class SendFactory
    {
        /// <summary>
        /// 根据邮政编码,就近选择发货仓库;
        /// </summary>
        /// <param name="postCode"></param>
        /// <returns></returns>
        public static StorageInterface GetStorage(string postCode)
        {
            StorageInterface _storageInterface;
            // 邮政编码的开头位代表地区:
            // 邮政编码规律:http://baike.baidu.com/link?url=Sq2z-xClEMVY_PbJtEZ-Soy_PQmx5Sn-FozBK-lkgOQHw2jyvUwzKjgIufRZMgs37CaJjWq_ZCAKCgjLqPQUWq
            //华北,东北,华东:上海仓库发货
            //华中,华南:广州仓库发货
            switch (postCode.Substring(0, 1))
            {
                case "0":
                case "1":
                case "2":
                case "3":
                    _storageInterface = new ShangHai();
                    break;
                case "4":
                case "5": _storageInterface = new GuangZhou();
                    break;
                default: _storageInterface = new ShangHai();
                    break;
            }
            return _storageInterface;
        }
    }  

调用console示例:

        static void Main(string[] args)
        {
            //顾客
            Client client = new Client { userID = new Guid(), postCode = "510000", address = "虚拟地址" };
            //工厂模式,根据邮政编码,就近选择发货仓库;
            StorageInterface _storeage = SendFactory.GetStorage(client.postCode);
            bool flat = _storeage.send(client);
            if (flat)
            { 
                //发货后的处理,例如跟踪物流等;
            }
        }  

可见,调用者简单,不关心底层是那个仓库实现发货功能的。
扩展:在北京建立新仓库,添加新类实现StorageInterface 接口,还有修改GetStorage 工厂根据邮政编码,选择发货仓库的逻辑,调用者不需改动。

增加仓库,使用添新类的方式,属于面向对象的开放封闭原则:对扩展开放,对修改封闭。

全部代码在这里:github

posted on 2015-04-01 21:37  向振文  阅读(814)  评论(0编辑  收藏  举报