设计模式 - 12)抽象工厂

class User
{
    int _id;
    public int Id
    {
        get { return _id; }
        set { _id = value; }
    }

    string _name;
    public string Name
    {
        get { return _name; }
        set { _name = value; }
    }
}

interface IUser
{
    void InsertUser(User user);
    User GetUser(int id);
}    

class SqlserverUser : IUser
{
    public void InsertUser(User user)
    {
        Console.WriteLine("Insert into user by Sqlserver");
    }

    public User GetUser(int id)
    {
        Console.WriteLine("Get user by Sqlserver");
        return null;
    }
}

class AccessserverUser : IUser
{
    public void InsertUser(User user)
    {
        Console.WriteLine("Insert into user by Accessserver");
    }

    public User GetUser(int id)
    {
        Console.WriteLine("Get user by Accessserver");
        return null;
    }
}

class Department
{
    int _id;
    public int Id
    {
        get { return _id; }
        set { _id = value; }
    }

    string _name;
    public string Name
    {
        get { return _name; }
        set { _name = value; }
    }
}

interface IDepartment
{
    void InsertDepartment(Department department);
    Department GetDepartment(int id);
}

class SqlserverDepartment : IDepartment
{
    public void InsertDepartment(Department department)
    {
        Console.WriteLine("Insert into Department by Sqlserver");
    }

    public Department GetDepartment(int id)
    {
        Console.WriteLine("Get Department by Sqlserver");
        return null;
    }
}

class AccessserverDepartment : IDepartment
{
    public void InsertDepartment(Department department)
    {
        Console.WriteLine("Insert into Department by Accessserver");
    }

    public Department GetDepartment(int id)
    {
        Console.WriteLine("Get Department by Accessserver");
        return null;
    }
}

interface IFactoryDB
{
    IUser CreateUser();
    IDepartment CreateDepartment();
}

class SqlserverFactory : IFactoryDB
{
    public IUser CreateUser()
    {
        return new SqlserverUser();
    }

    public IDepartment CreateDepartment()
    {
        return new SqlserverDepartment();
    }
}

class AccessFactory : IFactoryDB
{
    public IUser CreateUser()
    {
        return new AccessserverUser();
    }

    public IDepartment CreateDepartment()
    {
        return new AccessserverDepartment();
    }
}   

User user = new User() { Name = "Boy", Id = 1 };
Department dp = new Department() { Name = "department", Id = 2 };
IFactoryDB dbFactory = new AccessFactory();

IUser iu = dbFactory.CreateUser();
iu.InsertUser(user);
iu.GetUser(user.Id);

IDepartment idp = dbFactory.CreateDepartment();
idp.InsertDepartment(dp);
idp.GetDepartment(dp.Id);

缺点:每增加一个表,就需要新增 3 个类的同时,
修改 IFactory、SqlserverFactory、AccessFactory 类,
这违法了开放-封闭原则。下面使用 DataAccess。

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

    public static IUser CreateUser()
    {
        IUser result = null;
        switch (db)
        {
            case "Sqlserver":
                result = new SqlserverUser();
                break;
            case "Access":
                result = new AccessserverUser();
                break;                
        }
        return result;
    }

    public static IDepartment CreateDepartment()
    {
        IDepartment result = null;
        switch (db)
        {
            case "Sqlserver":
                result = new SqlserverDepartment();
                break;
            case "Access":
                result = new AccessserverDepartment();
                break;
        }
        return result;
    }
}

//业务代码:
User user = new User() { Name = "Boy", Id = 1 };
Department dp = new Department() { Name = "department", Id = 2 };

IUser iu = DataAccess.CreateUser();
iu.InsertUser(user);
iu.GetUser(user.Id);

IDepartment idp = DataAccess.CreateDepartment();
idp.InsertDepartment(dp);
idp.GetDepartment(dp.Id);

缺点:如果这时候再加一个 Oracle 数据库,如果是原来的抽象工厂,只需要加一个 OracleFactory 就可以,现在每个方法的 switch 里面都得再加一个 case。因此采用反射技术:

namespace WpfApp1.AbstractFactory {
class DataAccess
{
    private static readonly string AssemblyName = "WpfApp1";
    private static readonly string db = ConfigurationManager.AppSettings["DB"];

    public static IUser CreateUser()
    {
        string className = AssemblyName + ".AbstractFactory." + db + "User";
        return (IUser)Assembly.Load(AssemblyName).CreateInstance(className);
    }

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

// 业务代码:
User user = new User() { Name = "Boy", Id = 1 };
Department dp = new Department() { Name = "department", Id = 2 };

IUser iu = DataAccess.CreateUser();
iu.InsertUser(user);
iu.GetUser(user.Id);

IDepartment idp = DataAccess.CreateDepartment();
idp.InsertDepartment(dp);
idp.GetDepartment(dp.Id);            
posted @ 2020-12-27 21:52  鑫茂  阅读(74)  评论(0编辑  收藏  举报