• 说谎的简单工厂模式设计模式&工厂方法模式&Abstract Factory模式


     工厂模式被分成三个:简单工厂模式,抽象工厂模式和工厂模式。


     定义:

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


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


    延迟到其子类。


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


     结构图:


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


      简单工厂的长处:


      依据用户须要,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;
            }
        }
     

     client:

        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,则要加入类。改动client的代码将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//产品实现。实现产品接口的详细类,决定了产品在client中的详细行为。
        {
            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();
            }
        }

      工厂的实现:工厂实现决定怎样实例化产品,是实现拓展的途径。须要有多少中产品,就须要有多少个详细的工厂实现。

      client:

      

        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维操作,我们须要用到抽象工厂:

     这里事实上非常easy。就是加一个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;
            }
        }

      client:

        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();
    
            }
        }


     以上就是场景分析。

    长处:

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

      第一:易于交换产品系列,在一个应用中值须要再初始化的时候。出现一次,这就是的改变一个应用的详细工厂变得很easy,他仅仅须要改变详细工厂就可以使用不同的产品配置。

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

      

    版权声明:本文博客原创文章。博客,未经同意,不得转载。

  • 相关阅读:
    监控系统如何选择合适的时序数据库?
    面试官:谈谈如何防止消息丢失和消息重复
    面试官:mysql的四种事务隔离级别
    一致性Hash介绍及使用场景
    微服务之服务监控
    什么是公考、联考、国考、省考、选调生?
    LINQ: When to use SingleOrDefault vs. FirstOrDefault() with filtering criteria
    Async. Postbacks cause Page_Init? (C#)
    在线求解 不定积分 高等数学
    wpf Load
  • 原文地址:https://www.cnblogs.com/gcczhongduan/p/4615588.html
Copyright © 2020-2023  润新知