设计模式之抽象工厂模式

今天杨哥给小伙们带来了抽象工厂模式,杨哥使用一个经典的案例来讲解该模式、在我们开发中,尤且是服务端开发的小伙们,由于公司的业务或成本的需要,经常更换数据库,所以怎么做到灵活更换数据库的问题摆在了开发者们,那么我们就需要一个很好的设计模式、杨哥认为可以使用抽象工厂模式解决该业务场景。

  

这是使用了抽象工厂模式访问数据库的UML类图

下面是类图中的几个类:

User类:

package chouxianggongchang_designmode;

public class User {

private int id;

    public int getId() {

return id;

}

public void setId(int id) {

this.id = id;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

private String name;

}

Department类:

package chouxianggongchang_designmode;

public class Department {

 private int id;

     public int getId() {

return id;

}

public void setId(int id) {

this.id = id;

}

public String getDeptName() {

return deptName;

}

public void setDeptName(String deptName) {

this.deptName = deptName;

}

private String deptName;

     

}

IUser接口:

package chouxianggongchang_designmode;

public interface IUser {

void Insert(User user);

    User GetUser(int id);

}

IUser实现类AccessUser:

package chouxianggongchang_designmode;

public class AccessUser implements IUser{

 public void Insert(User user)

     {

 System.out.println("在Access中给User表增加一条记录");

     }

     public User GetUser(int id)

     {

      System.out.println("在Access中根据ID得到User表一条记录");

         return null;

     }

}

IUser实现类SqlserverUser:

package chouxianggongchang_designmode;

public class SqlserverUser implements IUser{

 public void Insert(User user)

     {

         

         System.out.println("在Sqlserver中给User表增加一条记录");

     }

     public User GetUser(int id)

     {

      System.out.println("在Sqlserver中根据ID得到User表一条记录");

       

         return null;

     }

}

IDepartment接口:

package chouxianggongchang_designmode;

public interface IDepartment {

void Insert(Department department);

    Department GetDepartment(int id);

}

IDepartment实现类SqlserverDepartment:

package chouxianggongchang_designmode;

public class SqlserverDepartment implements IDepartment{

 public void Insert(Department department)

     {

 System.out.println("在Sqlserver中给Department表增加一条记录");

     }

     public Department GetDepartment(int id)

     {

      System.out.println("在Sqlserver中根据ID得到Department表一条记录");

         return null;

     }

}


IDepartment实现类AccessDepartment :

package chouxianggongchang_designmode;

public class AccessDepartment implements IDepartment{

public void Insert(Department department)

    {

System.out.println("在Access中给Department表增加一条记录");

    }

    public Department GetDepartment(int id)

    {

     System.out.println("在Access中根据ID得到Department表一条记录");

        return null;

    }

}

IFactory接口:定义一个创建访问User表的对象的抽象的工厂接口

package chouxianggongchang_designmode;

public interface IFactory {

IUser CreateUser();

    IDepartment CreateDepartment();//增加的接口方法

}

SqlServerFactory工厂类:

package chouxianggongchang_designmode;

public class SqlServerFactory implements IFactory{

public IUser CreateUser()

    {

        return new SqlserverUser();

    }

   //增加了SqlserverDepartment()工厂

    public IDepartment CreateDepartment()

    {

        return new SqlserverDepartment();

    }

}

AccessFactory工厂类:

package chouxianggongchang_designmode;

public class AccessFactory implements IFactory{

public IUser CreateUser()

    {

        return new AccessUser();

    }

//增加了AccessDepartment()工厂

    public IDepartment CreateDepartment()

    {

        return new AccessDepartment();

    }

}

Main函数:

package chouxianggongchang_designmode;

public class AbstractFactory {

public static void main(String[] args) {

User user = new User();

        Department dept = new Department();

        //AbstractFactory factory = new SqlServerFactory();//只需要确定实例化哪一个数据访问对象给工厂即可

        IFactory factory = new AccessFactory();

        IUser iu = factory.CreateUser();//此时与具体的数据库访问对象解除了依赖

        iu.Insert(user);

        iu.GetUser(1);

        IDepartment id = factory.CreateDepartment();//此时与具体的数据库访问对象解除了依赖

        id.Insert(dept);

        id.GetDepartment(1);

}}

运行效果:

原理:

       抽象工厂模式,提供一个创建一系列的相关或相互依赖的对象的接口,而无需指定它们具体的类。

              

   总结:

     AbstractProductA和AbstractProduct是两个抽象的产品,之所以为抽象,是因为它们都有可能有两种不同的实现,就是刚才的上面的例子来说是User和Department,而ProductA1、ProductA2和ProductB1和ProductB2就是对两个抽象产品的具体分类的实现,比如ProductA1可以理解为是SqlserverUser,而ProductB1是AccessUser。

          这么说,IFactory是一个抽象工厂接口,它里面应该包含所有的产品创建的抽象方法。而ConcreteFactory1和ConcreteFactory2就是具体的工厂。就像SqlserverFactory和AccessFactory一样。

         通常是在运行时刻再创建一个ConcreteFactory类的实例,这个具体的工厂再创建具有特定实现的产品对象,也就是说,为创建不同的产品对象,客户端应使用不同的具体工厂。

原文地址:https://www.cnblogs.com/xinanheishao/p/7002017.html