设计模式3---抽象工厂模式

public interface IFactory {

    IUser CreateUser();

    IDepartment CreateDepartment();

}

在工厂模式中,每个工厂类会为特定的操作类型产生操作对象类。

但是如果有产品系列的话,工厂模式就不太适用。

考虑一个数据库的问题。

1.数据库可能有替换

2.每个数据库可以修改多个表,比如user,department。

抽象工厂类就是对于工厂类产生的对象,我其实不需要得到具体的类,只要抽象类(接口)就可以了。

main方法:

public class AbstractFactoryMain extends BasicExample {



    @Override

    public void startDemo() {

        // TODO Auto-generated method stub

        User user = new User();

        Department department = new Department();

        IFactory factory = new AccessFactory();

        IUser iu = factory.CreateUser();

        iu.insertUser(user);

        iu.getUser(1);

        

        IDepartment id = factory.CreateDepartment();

        id.insertDepartment(department);

        id.getDepartment(1);

    }



}
IFactory 是工厂方法接口
IUser 和IDepartment 是对于User和Department的操作接口,具体是access还是SQLserver其实客户端不关心。

其他类具体实现:
public interface IFactory {

    IUser CreateUser();

    IDepartment CreateDepartment();

}
 
  
//封装对User表的操作

public interface IUser {

    void insertUser(User user);

    User getUser(int id);

}
//封装对Department表的操作

public interface IDepartment {

    void insertDepartment(Department department);

    Department getDepartment(int id);

}

SQLserver工厂类:

public class SqlServerFactory implements IFactory {



    @Override

    public IUser CreateUser() {

        // TODO Auto-generated method stub

        return new SqlserverUser();

    }



    @Override

    public IDepartment CreateDepartment() {

        // TODO Auto-generated method stub

        return new SqlserverDepartment();

    }



}

Access工厂类:

public class AccessFactory implements IFactory {



    @Override

    public IUser CreateUser() {

        // TODO Auto-generated method stub

        return new AccessUser();

    }



    @Override

    public IDepartment CreateDepartment() {

        // TODO Auto-generated method stub

        return new AccessDepartment();

    }



}

具体操作类:

 
  
public class SqlserverUser implements IUser {



    @Override

    public void insertUser(User user) {

        System.out.println("在SQLserver 中给user表添加一条记录");

    }



    @Override

    public User getUser(int id) {

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

        return null;

    }



}
 
  
public class SqlserverDepartment implements IDepartment {



    @Override

    public void insertDepartment(Department department) {

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

    }



    @Override

    public Department getDepartment(int id) {

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

        return null;

    }



}

 

 
  
public class AccessDepartment implements IDepartment {



    @Override

    public void insertDepartment(Department department) {

        // TODO Auto-generated method stub

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

    }



    @Override

    public Department getDepartment(int id) {

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

        return null;

    }



}
 
  
public class AccessUser implements IUser {



    @Override

    public void insertUser(User user) {

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

    }



    @Override

    public User getUser(int id) {

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

        return null;

    }



}
public class User {

    

    private int _id;

    private String _name;



    

    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;

    }

    

}
public class Department {

    private int _id;

    private String _name;



    

    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;

    }

}

 

如果需要添加Oracle 数据库,那只要添加 工厂生成类OracleFactory,以及操作OracleUser 和OracleDepartment类。
这样就不会改动原有代码,可以快速替换数据库。
抽象工厂模型:
优点: 1.可以方便的交换产品系列,只需在初始化的地方出现一次,就可以应用一个具体工厂。  
    2.具体实现隔离客户端,客户端通过抽象接口来操作具体实例。

简单工厂模型优化抽象工厂模型。
把AccessFactory 和SqlserverFactory可以合并成DataAccess方法来处理。

问题:如果上述“ IFactory factory = new AccessFactory();” 有还多处地方,甚至好几百处,这样就需要做大量的修改。
AccessFactory用DataAccess来代替,客户端彻底杜绝出现数据库字段。
public class DataAccess {

//    private static final String db = "Sqlserver";

    private static final String db = "Access";

    

    public static IUser CreateUser()

    {

        IUser result = null;

        switch(db)

        {

        case "Sqlserver":

            result = new SqlserverUser();

            break;

        case "Access":

            result = new AccessUser();

            break;

        }

        return result;

    }

    

    public static IDepartment CreateDepartment()

    {

        IDepartment result = null;

        switch(db)

        {

        case "Sqlserver":

            result = new SqlserverDepartment();

            break;

        case "Access":

            result = new AccessDepartment();

            break;

        }

        return result;

    }

}
 
  

main方法修改为:

public class AbstractFactoryMain extends BasicExample {



    @Override

    public void startDemo() {

        // TODO Auto-generated method stub

        User user = new User();

        Department department = new Department();

//        IFactory factory = new AccessFactory();

        IUser iu = DataAccess.CreateUser();

        iu.insertUser(user);

        iu.getUser(1);

        

        IDepartment id = DataAccess.CreateDepartment();

        id.insertDepartment(department);

        id.getDepartment(1);

    }



}

  从main方法看,根本看不到任何SQL和Access的字段,也就是客户端与业务逻辑隔离了!

  但是,如果新增一个Oracle数据库,需要修改DataAccess的switch--case,如何彻底不用switch语句呢?

 

利用反射,把类对象反射出来,这样只需要添加工厂类定义就可以了。
package com.jayfulmath.designpattern.abstractfactory;



import java.lang.reflect.*;

public class DataAccessReflection {



    private static final String AssemblyName = "com.jayfulmath.designpattern.abstractfactory";

    private static final String db = "Access";

    

    public static IUser CreateUser()

    {

        String className =AssemblyName+"."+db+"User";

        IUser  result = null;

        try {

            Class<?> c = Class.forName(className);

            Constructor<?> ct = c.getConstructor();

            result = (IUser) (ct.newInstance());

        } catch (NoSuchMethodException |ClassNotFoundException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {

            // TODO Auto-generated catch block

            e.printStackTrace();

        }

        

        return result;

    }

    

    public static IDepartment CreateDepartment()

    {

        String className = AssemblyName+"."+db+"Department";

        IDepartment  result = null;

        try {

            Class<?> c = Class.forName(className);

            Constructor<?> ct = c.getConstructor();

            result = (IDepartment) (ct.newInstance());

        } catch (NoSuchMethodException |ClassNotFoundException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {

            // TODO Auto-generated catch block

            e.printStackTrace();

        }

        

        return result;

    }

}
 
  

自此,完美的解决了switch---case的问题。如果使用配置文件的话,可以彻底不用修改代码,而达到更换数据库的问题。

      


 

你可能感兴趣的:(抽象工厂模式)