设计模式之抽象工厂模式,用简单工厂来改进抽象工厂以及反射+抽象工厂的数据访问程序

当设计到多个产品系列的问题时使用抽象工厂模式;

抽象工厂的优缺点不想提,总之我基本不会去用,扩展起来太tm愁人了,增加一个产品要至少增加三个类,修改三个工厂类,之前搞过一次差点烦死我,哎,都怪学艺不精啊~~

OK上代码:

这里建立一个用户表,提供insert和get的功能。建立用户的接口,实现接口。

   class User
    {
        private int nid;
        public int ID
        {
            get
            {
                return nid;
            }
            set {
                nid = value;
            }
        }
        private string strName;
        public string  Name
        {
            get
            {
                return strName;
            }
            set
            {
                strName = value;
            }
        }
    }

    interface IUser
    {
        void inser(User user);
        User getUser(int id); 
    }
    class SqlUser:IUser
    {
        public void inser(User user)
        {
            Console.WriteLine("在sql中创建一条数据");
        }

        public User getUser(int id)
        {
            Console.WriteLine("根据ID得到一条数据");
            return null;
        }

    }

    class AceUser:IUser
    {
        public void inser(User user)
        {
            Console.WriteLine("在Access中创建一条数据");
        }

        public User getUser(int id)
        {
            Console.WriteLine("根据ID得到一条数据");
            return null;
        }

    }

和上面一样 

 class Department
    {
        private int nid;
        public int ID
        {
            get
            {
                return nid;
            }
            set
            {
                nid = value;
            }
        }
        private string strName;
        public string Name
        {
            get
            {
                return strName;
            }
            set
            {
                strName = value;
            }
        }
    }

    interface IDepartment
    {
        void inserDepartment(Department department);
        Department getDepartment(int id);
    }

    class SqlDepartment : IDepartment
    {
        public void inserDepartment(Department department)
        {
            Console.WriteLine("在sql中创建一条Department数据");
        }

        public Department getDepartment(int id)
        {
            Console.WriteLine("根据ID得到一条Department数据");
            return null;
        }

    }

    class AceDepartment : IDepartment
    {
        public void inserDepartment(Department department)
        {
            Console.WriteLine("在Access中创建一条Department数据");
        }

        public Department getDepartment(int id)
        {
            Console.WriteLine("根据ID得到一条Department数据");
            return null;
        }

    }

建立工厂类:

 interface IFactory
    {
        IUser CreatorUser(); //用户
        IDepartment CreatorDepartment();//部门
    }

    class SqlFactory:IFactory
    {
        public IUser CreatorUser()
        {
            return new SqlUser();
        }

        public IDepartment CreatorDepartment()
        {
            return new SqlDepartment();
        }
    }

    class AceFactory : IFactory
    {
        public IUser CreatorUser()
        {
            return new AceUser();
        }

        public  IDepartment CreatorDepartment()
        {
            return new AceDepartment();
        }
    }

调用

 

            User user = new User();
            IFactory factor = new SqlFactory();
            IUser iu = Datebase.CreatorUser();
            user.ID=1;
            user.Name="sqlserver";

            iu.inser(user);
            iu.getUser(1);

            Department dp = new Department();
            dp.ID = 2;
            dp.Name = "zhao";
            IDepartment id = Datebase.CreatorDepartment();
            id.inserDepartment(dp);
            id.getDepartment(1);

 抽象工厂就是这么回事,会了工厂方法模式,这个基本就会了。如果说是维护代码还好,真的还算方便,如果是扩展,对不起好烦。不过没事咱还能改进(为什么我之前没想到???奇怪。)

class Datebase
    {
        private static readonly string db = "Sqlserver";//"Access"

        public static IUser CreatorUser()
        {
            IUser result = null;
            switch(db)
            {
                case "Sqlserver":
                    result =  new SqlUser();
                    break;
                case "Access":
                    result =  new AceUser();
                    break;
            }

            return result;
        }

        public static IDepartment CreatorDepartment()
        {
            IDepartment result = null;
            switch (db)
            {
                case "Sqlserver":
                    result = new SqlDepartment();
                    break;
                case "Access":
                    result = new AceDepartment();
                    break;
            }

            return result;
        }
    }

改进:将抽象工厂去掉改为简单工厂使用switch语句进行分别,这样就不用每个类里面使用数据库的时候写  IFactory factor = new SqlFactory();看看调用:

            User user = new User();
          //  IFactory factor = new SqlFactory();
            IUser iu = Datebase.CreatorUser();
            user.ID=1;
            user.Name="sqlserver";

            iu.inser(user);
            iu.getUser(1);

            Department dp = new Department();
            dp.ID = 2;
            dp.Name = "zhao";
            IDepartment id = Datebase.CreatorDepartment();
            id.inserDepartment(dp);
            id.getDepartment(1);

但是这样做还是不太好,新增数据库种类的话我还是要在case里面加分支。这个时候可以考虑用什么技术呢??反射技术。

格式:Assembly.Load("程序集名称").CreateInstance("命名空间.类名称");//要是还有问什么是程序集名称的我就不管了。。

当然用反射肯定要引用东西的:using System.Reflection;//要引用这个

修改后:

using System.Reflection;//要引用这个

 class Datebase
    {
        private static readonly string AssemblyName = "myFactory";
        private static readonly string db = "Sql";

        public static IUser CreatorUser()
        {
           //这里注意有可能程序集名称并不是命名空间,我没改默认是一样的。
            string classname = AssemblyName + "." + db + "User";
            return (IUser)Assembly.Load(AssemblyName).CreateInstance(classname);
        }
       

        public static IDepartment CreatorDepartment()
        {
            string classname = AssemblyName + "." + db + "Department";
            return (IDepartment)Assembly.Load(AssemblyName).CreateInstance(classname);
        }
    }

调用时一样的;

这样写在更改已存在数据库调用的时候只更改DB名就可以了,如果增加数据库,那就没办法了,加类吧,这叫扩展。如果想不改源码不重新编译就实现数据库的更改,也是可以的,修改配置文件呗。读取配置文件数据库名复制给db。我这里就不写了。。。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值