大话设计模式之简单工厂模式&工厂方法模式&抽象工厂模式

 工厂模式分为三种:简单工厂模式,工厂模式和抽象工厂模式。


 定义:

 简单工厂模式:用一个单独的类来做创造实例的过程。


 工厂模式:一个用于创建对象的接口,让子类决定实例化哪一个类,讲一个类的实例化


延迟到其子类。


 抽象工厂模式:为创建一组相关或相互依赖的对象的类,而不指定具体类。


 结构图:


  这是简单工厂的结构图,从图中就很好理解。


  简单工厂的优点:


  根据用户需要,new出需要的对象。


  但是简单工厂弊端:


  当新加入一个功能是,就要修改工厂。这个时候,就需要工厂模式了。


 从图中我们可以看出:


 工厂模式客服了修改工厂类,运用扩展,加一个算法工厂,就行了。


 工厂模式的有点:典型的解耦和模式。




  


 这个就是抽象工厂,最核心的思想就是:抽象出接口类和抽象类,实现化不同的子类。

 

 使用场景:

 在数据库访问中,在SQLserver中有User和Department两张表,在Access中也有同样的

同样的两张表,现在,需要向不同的数据库中代码访问User表,进行添加数据和查询数据的方法。

 分析:

 怎样做到最高效率的在SQLServer和Access中进行转换时我们需要考虑的。

 第1版代码:不加如何模式

 

    class User
    {
        private int _id;
        public int ID
        {
            get { return _id; }
            set { _id = value; }
        }
        private string _name;
        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }
    }
    class SqlserverUser
    {
        public void Insert(User user)
        { Console.WriteLine("在SQL Server中给User表添加一条记录"); }
        public User GetUser(int id)
        {
            Console.WriteLine("在SQL Server中根据ID得到User表一条记录");
            return null;
        }
    }
 

 客户端:

    class Program
    {
        static void Main(string[] args)
        {
            User user = new User();
            SqlserverUser su = new SqlserverUser();
            su.Insert(user);
            su.GetUser(1);
            Console.Read();
        }
    }

  从代码中我们可以看到,如果我们需要从Access数据库中访问User,则要添加类,修改客户端的代码将SqlserverUser su=new SqlserverUser();这句代码改为SqlAccessUser ac=new SqlAccessUser();这样写就违反了开闭原则。

 第2版代码:工厂方法模式的数据访问程序

 接口层

    interface IFactory//工厂接口,与调用者交互
    {
        IUser CreateUser();
    }
    interface IUser//产品接口,定义产品的规范,所有的产品实现都必须遵循产品接口定义规范。
    {
        void Insert(User user);
        User GetUser(int id);
    }

   上面是两个接口,上面有他们的结构图,一目了然。工厂接口是工厂方法模式的核心,与调用者直接交互用来提供产品。产品接口是定义产品的规范,所有的产品实现都必须遵循产品接口定义的规范。产品接口是调用者最为关心的,产品接口定义的优劣直接决定了调用者代码的稳定性。

  实现:


    class SqlserverUser : IUser//产品实现,实现产品接口的具体类,决定了产品在客户端中的具体行为。
    {
        public void Insert(User user)
        {
            Console.WriteLine("在SQL Server中给User表增加一条记录");
        }
        public User GetUser(int id)
        {
            Console.WriteLine("在SQL Server根据ID得到User表一条记录");
            return null;
        }
    }
    class SqlAccessUser : IUser
    {
        public void Insert(User user)
        {
            Console.WriteLine("在Access中给User表添加一条记录");
        }
        public User GetUser(int id)
        {
            Console.WriteLine("在Access中根据ID得到User表一条记录");
            return null;
        }
    }
    class SqlserverFactory : IFactory//工厂实现,工厂实现决定如何实例化产品,是实现拓展的途径。需要多少中产品,就要有多少个具体的工厂实现。
    {
        public IUser CreateUser()
        {
            return new SqlserverUser();
        }
    }
    class SqlAccessFactory : IFactory
    {
        public IUser CreateUser()
        {
            return new SqlAccessUser();
        }
    }

   工厂的实现:工厂实现决定如何实例化产品,是实现拓展的途径,需要有多少中产品,就需要有多少个具体的工厂实现。

  客户端:

  

    class Program
    {
        static void Main(string[] args)
        {
            User user = new User();//实例化实体
            IFactory factory = new SqlserverFactory();//实现工厂类

            IUser iu = factory.CreateUser();//工厂中创造出想要的对象         
            iu.Insert(user);
            iu.GetUser(1);

            Console.Read();

        }
    }

  若要访问Department表,设计到2维操作,我们需要用到抽象工厂:

 这里其实很简单,就是加一个Department接口,两个子类继承,加一个实体类,修改工厂类。

 由于代码千篇一律,怕大家看烦了,就不晒了。


  第3版:抽象模式加简单工厂模式:

  结构图:


 

    class DataAccess
    {
        //private static readonly string db = "Sqlserver";
        private static readonly string db = "Access";
        public static IUser CreateUser()
        {
            IUser result = null;//一定是父类
            switch (db)
            {
                case "Sqlserver":
                    result = new SqlserverUser();
                    break;
                case "Access":
                    result = new SqlAccessUser();
                    break;
            }
            return result;
        }
        public static IDeparment CreateDep()
        {
            IDeparment result = null;
            switch (db)
            {
                case "Sqlserver":
                    result = new SqlserverDeparment();
                    break;
                case "Access":
                    result = new SqlAccessDepartment();
                    break;

            }
            return result;
        }
    }

  客户端:

    class Program
    {
        static void Main(string[] args)
        {
            User user = new User();
            Department dep = new Department();
            IUser iu = DataAccess.CreateUser();//创造实例化的子类

            iu.Insert(user);
            iu.GetUser(1);

            IDeparment dept = DataAccess.CreateDep();

            dept.Insert(dep);
            dept.GetDep(1);

            Console.Read();

        }
    }


 以上就是场景分析。

优点:

  简单工厂、工厂、抽象工厂是层层递进的关系,但是都存在这有点和缺点,我都在里面说了,所以,这里仅简单介绍一下抽象工厂的优点:

  第一:易于交换产品系列,在一个应用中值需要再初始化的时候,出现一次,这就是的改变一个应用的具体工厂变得非常容易,他只需要改变具体工厂即可使用不同的产品配置。

  第二:让具体的创建实例过程与客户端分离,客户端是通过他们的抽象接口操纵实例,产品的具体类名也被具体工厂的实现分离,不会出现在客户代码中。

  

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值