Java第三十八天,Spring框架系列,使用工厂模式降低程序耦合度

一、什么是耦合

程序之间的依赖关系:

①类之间的依赖

②方法之间的依赖

注意:

不可能完全的消除依赖关系,而只能是降低程序之间的依赖关系

二、解耦

降低程序之间的依赖关系:

1.解决类之间的依赖关系:

①通过读取配置文件来获取要创建对象的全限定类名

②使用反射来创建类的对象,尽量避免new关键字的使用

三、问题引出

1.新建Maven项目

2.修改配置文件,添加如下代码,让程序打包成Jar包的形势

<packaging>jar</packaging>

3.开始编写实验代码,整体架构如下:

3.持久层接口

package com.huhai.Dao;

/**
 *持久层接口
 */
public interface IAccountDao {
    public abstract void save();
}

4.持久层接口实现类

package com.huhai.Dao.Impl;

import com.huhai.Dao.IAccountDao;

/**
 * 持久层实现类
 */
public class AccountDaoImpl implements IAccountDao {
    public void save() {
        System.out.println("数据保存成功");
    }
}

5.业务层接口

package com.huhai.Service;

/**
 *业务层接口
 */
public interface ISaveAccountService {
    public abstract void save();
}

6.业务层接口实现类

package com.huhai.Service.Impl;

import com.huhai.Dao.Impl.AccountDaoImpl;
import com.huhai.Service.ISaveAccountService;

/**
 * 业务层实现类
 */
public class AccountServiceImpl implements ISaveAccountService {
    private AccountDaoImpl accountDao = new AccountDaoImpl();

    public void save() {
        accountDao.save();
    }
}

7.表现层

package com.huhai;

import com.huhai.Service.Impl.AccountServiceImpl;

public class Realize {
    private static AccountServiceImpl accountService;

    public static void main(String[] args) {
        accountService = new AccountServiceImpl();
        accountService.save();
    }
}

可以看出,它们之间的依赖关系非常严重,因此需要解耦

四、使用工厂模式降低程序耦合度

1.项目架构

2.工厂类:

package com.huhai.Factory;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

/**
 * 一个创建Bean对象的工厂
 * 它就是创建Server和Dao对象的
 */
public class BeanFactory {
    /**
     * 定义Properties对象
     */
    private static Properties properties;

    /**
     * 使用静态代码段为properties赋值
     */
    static {
        /**
         * 实例化对象
         */
        properties = new Properties();
        /**
         * 获取properties流对象
         * 最好不要直接new,因为传路径的时候,路径是一个容易出错的地方
         * 因为配置文件在resources根目录下,所以可以直接填写文件名字bean.properties作为参数
         * 使用类加载器来获得文件的路径
         */
        InputStream in = BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties");
        try {
            properties.load(in);
        } catch (IOException e) {
            /**
             * 配置文件如果出错,则没有必要继续运行
             * 抛出错误,终止整个程序
             */
            throw new ExceptionInInitializerError("初始化异常");
        }
    }

    /**
     * 使用工厂模式创建对象
     * 因为返回的对象不一定是一个类,所以返回值类型为Object或者泛型
     * 根据bean的名称获取bean对象
     */
    public static Object getBean(String beanName){
        /**
         * 初始化返回对象
         */
        Object bean = null;
        /**
         * 根据传入的beanName参数获取properties中的对应类的全限定类名
         */
        String beanPath = properties.getProperty(beanName);
        try {
            bean = Class.forName(beanPath).newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return bean;
    }
}

工厂类升级版——工厂类的单例模式

package com.huhai.Factory;

import java.io.InputStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * 一个创建Bean对象的工厂
 * 它就是创建Server和Dao对象的
 */
public class BeanFactory {
    /**
     * 定义Properties对象
     */
    private static Properties properties;

    /**
     * 定义一个Map,使之能够存放已经实例化的对象
     * 该Map即为容器
     * 该容器的建造是为了完成工厂的类的单例模式
     */
    private static Map<String, Object> beans;

    /**
     * 使用静态代码段为properties赋值
     */
    static {
        try {
            /**
             * 实例化对象
             */
            properties = new Properties();
            /**
             * 获取properties流对象
             * 最好不要直接new,因为传路径的时候,路径是一个容易出错的地方
             * 因为配置文件在resources根目录下,所以可以直接填写文件名字bean.properties作为参数
             * 使用类加载器来获得文件的路径
             */
            InputStream in = BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties");

            properties.load(in);
            /**
             * 配置文件如果出错,则没有必要继续运行
             * 抛出错误,终止整个程序
             */

            /**
             *
             */
            beans = new HashMap<String, Object>();
            Enumeration keys = properties.keys();
            /**
             * 遍历所有的keys
             */
            while(keys.hasMoreElements()){
                String key = keys.nextElement().toString();
                //根据配置文件得到指定类的全限定类名
                String property = properties.getProperty(key);

                //使用反射实例化对象
                Object obj = Class.forName(property).newInstance();
                //将对象放进仓库
                beans.put(key, obj);

            }
        }catch (Exception e){
            throw new ExceptionInInitializerError("初始化properties失败!");
        }
    }

    /**
     * 使用工厂模式创建对象
     * 因为返回的对象不一定是一个类,所以返回值类型为Object或者泛型
     * 根据bean的名称获取bean对象
     */
    public static Object getBean(String beanName){

        //根据bean的名称获取bean单例对象
        return beans.get(beanName);
    }
}

3.持久层接口

package com.huhai.Dao;

/**
 *持久层接口
 */
public interface IAccountDao {
    public abstract void save();
}

4.持久层接口实现类

package com.huhai.Dao.Impl;

import com.huhai.Dao.IAccountDao;

/**
 * 持久层实现类
 */
public class AccountDaoImpl implements IAccountDao {
    public void save() {
        System.out.println("数据保存成功");
    }
}

5.业务层接口

package com.huhai.Service;

/**
 *业务层接口
 */
public interface IAccountService {
    public abstract void save();
}

6.业务层接口实现类

package com.huhai.Service.Impl;

import com.huhai.Dao.IAccountDao;
import com.huhai.Factory.BeanFactory;
import com.huhai.Service.IAccountService;

/**
 * 业务层实现类
 */
public class AccountServiceImpl implements IAccountService {

    /**
     * 使用工厂模式创建对象,降低程序耦合度
     */
    private IAccountDao accountDao = (IAccountDao)BeanFactory.getBean("accountDaoImpl");
    public void save() {
        accountDao.save();
    }
}

7.表现层

package com.huhai;

import com.huhai.Factory.BeanFactory;
import com.huhai.Service.IAccountService;

public class Realize {

    public static void main(String[] args) {
        /**
         * 为了解耦,使用工厂模式创建对象
         */
        IAccountService accountService = (IAccountService) BeanFactory.getBean("accountServiceImpl");
        accountService.save();
        System.out.println(accountService);
    }
}

8.bean.properties配置文件

#键(key)用小写
accountServiceImpl=com.huhai.Service.Impl.AccountServiceImpl
accountDaoImpl=com.huhai.Dao.Impl.AccountDaoImpl

 

posted @ 2020-06-17 19:19  IT蓝月  阅读(249)  评论(0编辑  收藏  举报
Live2D