设计模式之抽象工厂(抽象工厂 + 反射 + 配置文件)

目录

1.抽象工厂的概念

​2.抽象工厂的结构图

3.抽象工厂设计模式的练习示例

4.抽象工厂设计模式的练习示例结构图

5. 抽象工厂 + 反射 + 配置文件   

        5.1:什么是java的反射机制?

        5.2:抽象工厂与反射

        5.3:抽象工厂 + 反射 + 配置文件   的结构图​

         5.4:练习实例:

6.总结:


1.抽象工厂的概念

提供一个创建一系列相关或互相依赖的对象的接口,而无需指定他们具体的类

设计模式之抽象工厂(抽象工厂 + 反射 + 配置文件)2.抽象工厂的结构图

设计模式之抽象工厂(抽象工厂 + 反射 + 配置文件)

3.抽象工厂设计模式的练习示例

数据库的用户类:

/**
 * 数据库的用户类
 */
@Data
public class User {
    private int id;
    private String userName;
}

部门类:

/**
 * 部门类
 */
@Data
public class Department {
    private int id;
    private String deptName;
}

操作部门表的抽象数库:

/**
 * 操作部门表的抽象数据库
 */
interface IDepartment {
    void insert(Department department);
    Department get(int id);
}

操作用户表的抽象数据库:

/**
 * 操作用户表的抽象数据库
 */
interface IUser {
    void insert(User user);

    User getUser(int id);
}

操作用户表的mysql数据库:

/**
 * 操作用户表的mysql数据库
 */
public class MysqlUser implements IUser{
    @Override
    public void insert(User user) {
        System.out.println("MysqlUser在数据库内增加了一位用户");
    }

    @Override
    public User getUser(int id) {
        System.out.println("MysqlUser从数据库内获得了一条数据");
        return new User();
    }
}

操作部门表的mysql数据库:

/**
 * 操作部门表的mysql数据库
 */
public class MysqlDepartment implements IDepartment{
    @Override
    public void insert(Department department) {
        System.out.println("MysqlDepartment在数据库内增加了一条数据");
    }

    @Override
    public Department get(int id) {
        System.out.println("MysqlDepartment从数据库查询了一条数据");
        return null;
    }
}

操作用户表的oracle数据库:

/**
 * 操作用户表的oracle数据库
 */
public class OracleUser implements IUser{
    @Override
    public void insert(User user) {
        System.out.println("OracleUser在数据库内增加了一条数据");
    }

    @Override
    public User getUser(int id) {
        System.out.println("OracleUser从数据库内查询了一条数据");
        return null;
    }
}

操作部门表的oracle数据库:

/**
 * 操作部门表的oracle数据库
 */
public class OracleDepartment implements IDepartment{
    @Override
    public void insert(Department department) {
        System.out.println("OracleDepartment在数据库内增加了一条数据");
    }

    @Override
    public Department get(int id) {
        System.out.println("OracleDepartment从数据库内查询了一条数据");
        return new Department();
    }
}
定义一个创建操作用户表,部门表的数据库对象的抽象工厂接口:
/**
 * 定义一个创建操作用户表,部门表的数据库对象的抽象工厂接口
 */
interface IFactory {

    IUser createUser();

    IDepartment createDepartment();
}
创建一个生产mysql用户的工厂:
/**
 * 创建一个生产mysql用户的工厂
 */
public class MysqlFactory implements IFactory{
    @Override
    public IUser createUser() {
        return new MysqlUser();
    }

    @Override
    public IDepartment createDepartment() {
        return new MysqlDepartment();
    }
}
创建一个生产oracle用户的工厂:
/**
 * 创建一个生产oracle用户的工厂
 */
public class OracleFactory implements IFactory{
    @Override
    public IUser createUser() {
        return new OracleUser();
    }

    @Override
    public IDepartment createDepartment() {
        return new OracleDepartment();
    }
}

测试:

public class Test {
    public static void main(String[] args) {
        //创建一个用户
        User user = new User();
        //创建一个部门
        Department department = new Department();

        //使用抽象工厂创建一个 生产 操作用户表,部门表的mysql数据库对象 的工厂
        IFactory iFactory = new MysqlFactory();

        //工厂创建操作用户表的mysql数据库对象
        IUser user1 = iFactory.createUser();
        //操作用户表的mysql数据库对象操作用户表
        user1.getUser(1);
        user1.insert(user);

        //工厂创建操作部门表的mysql数据库对象
        IDepartment department1 = iFactory.createDepartment();
        //操作部门表的mysql数据库对象操作部门表
        department1.get(1);
        department1.insert(department);

    }
}

4.抽象工厂设计模式的练习示例结构图

设计模式之抽象工厂(抽象工厂 + 反射 + 配置文件)

5. 抽象工厂 + 反射 + 配置文件   

        5.1:什么是java的反射机制?

        JAVA反射机制是就是运行的状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。通过反射机制可以动态的访问类的属性和方法以及字段。

        5.2:抽象工厂与反射

        抽象工厂通常和java的反射机制紧密联系在一起。当遇到新的具体工厂角色出现时,如果没有java的反射机制,我们需要首先创建具体的工厂类,在UI(客户端)修改相关代码, 将具体的工厂的实例化代码加入。严重违反了开闭原则。但是通过java的反射机制就可以将抽象工厂模式的实现对修改封闭,在拓展开放,将新的具体的工厂类名的写入配置文件中,通过读取配置文件就可以读取到新增的具体工厂的类名,根据类名自动生成相应类的实例化

        5.3:抽象工厂 + 反射 + 配置文件   的结构图
设计模式之抽象工厂(抽象工厂 + 反射 + 配置文件)

         5.4:练习实例:

        Data类:

        

/**
 * 抽象工厂 + 反射 + 配置文件
 */

@Component
public  class Data {

    private static String dataBase;

    public static IUser getUser() throws Exception{
        Properties properties = new Properties();
        InputStream resourceAsStream = Data.class.getClassLoader().getResourceAsStream("application.properties");
        properties.load(resourceAsStream);
        String className = "com.example.designpatternexer.abstractfactory." + properties.get("dataBase") + "User";
        Class<IUser> iUserClass =  (Class<IUser>) Class.forName(className);
        return iUserClass.getConstructor().newInstance();
    }

    public static IDepartment getDepartment() throws Exception{
        Properties properties = new Properties();
        InputStream resourceAsStream = Data.class.getClassLoader().getResourceAsStream("application.properties");
        properties.load(resourceAsStream);
        String className = "com.example.designpatternexer.abstractfactory."+ properties.get("dataBase") + "Department";
        Class<IDepartment> iUserClass =  (Class<IDepartment>) Class.forName(className);
        return iUserClass.getConstructor().newInstance();
    }
}

测试类:

public class Test2 {

    public static void main(String[] args) {
        try {
            User user1 = new User();
            Department department = new Department();

            IUser user = Data.getUser();
            user.insert(user1);
            user.getUser(1);

            IDepartment department1 = Data.getDepartment();
            department1.insert(department);
            department1.get(1);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

配置文件:

设计模式之抽象工厂(抽象工厂 + 反射 + 配置文件)

控制台:

 设计模式之抽象工厂(抽象工厂 + 反射 + 配置文件)

 

6.总结:

现在如果我们增加了SqlServer 数据库访问,相关的类的增加是不可避免的,这点无论我们用任何办法都解决不了,不过这叫扩展,开放-封闭原则性告诉我们,对于扩展,我们开放。但对于修改,我们应该要尽量关闭,就目前而言,我们只需要更改private static string dataBase在配置文件中的值就行了。也就意味着就这一句话发生了改变

上一篇:面试官:编写一个 SQL 查询,找出每个部门工资第二高的员工


下一篇:mysql外连接、交叉连接