zoukankan      html  css  js  c++  java
  • 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
    作者:蓝月

    -------------------------------------------

    个性签名:能我之人何其多,戒骄戒躁,脚踏实地地走好每一步

  • 相关阅读:
    微信小程序中从后台获取的数组,然后需要改变数组其中一个属性值,然后setData
    vue 项目中监听 localStorage 或 sessionStorage 的变化
    微信小程序怎么区分线上和测试环境
    vue中使用SVG图标,并且想批量导入,然后需要使用的时候直接添加就可以
    微信小程序中引用VantUI组件
    解决webStorm打开vue项目时加载文件卡死的问题
    关于ES6中的Proxy
    Object.defineProperty()详解
    openCV模块应用之解析传输的图片
    [Java EE]缓存技术初探
  • 原文地址:https://www.cnblogs.com/viplanyue/p/13573757.html
Copyright © 2011-2022 走看看