Spring带你飞(2)—— 当没用spring之前,我们如何解决程序的耦合问题

首先我们先了解一下什么是程序的耦合,耦合指的是程序间的依赖关系。那么解耦的意思就是要降低程序间的依赖关系。在我们实际开发中:应该做到,编译期不依赖,运行时才依赖

好了上面废话那么多,我们先来看一段程序。

/**
 * @ClassName: AccountServiceImpl
 * @author: benjamin
 * @version: 1.0
 * @description: 账户业务层接口的实现类
 * @createTime: 2019/07/24/17:10
 */
public class AccountServiceImpl implements IAccountService {
    private IAccountDao accountDao = new AccountDaoImpl();
    public void  saveAccount(){   
        System.out.println("业务层保存账户。。。");
    }
}

可以看到,此时业务层的代码调用了持久层的实体类,如果我们此时没有持久层实现类,那么编译不能通过。这种编译期间依赖关系,我们应该杜绝。

工厂模式解耦

​ 在实际开发中我们可以把三层的对象都使用配置文件配置起来,当启动服务器应用加载的时候,让一个类中的方法通过读取配置文件,把这些对象创建出来并存起来。在接下来的使用的时候,直接拿过来用就好了。那么,这个读取配置文件, 创建和获取三层对象的类就是工厂。

我们先来看一下项目的结构:

  1. 创建maven工程;

  2. 创建业务层接口和实现类

    /**
     * 账户的业务层接口
     * @ClassName: IAccountService
     * @author: benjamin
     * @createTime: 2019/07/24/17:08
     */
    public interface IAccountService {
        /**
         * 模拟保存账户
         */
        void saveAccount();
    }
    
    /**
     * @ClassName: AccountServiceImpl
     * @author: benjamin
     * @version: 1.0
     * @description: 账户业务层接口的实现类
     * @createTime: 2019/07/24/17:10
     */
    
    public class AccountServiceImpl implements IAccountService {
        private IAccountDao accountDao = new AccountDaoImpl();
    
        public void  saveAccount(){
            System.out.println("业务层保存账户。。。");
            accountDao.saveAccount();
        }
    }
    
  3. 创建持久层接口和实现类

    /**
     * 账户的持久层接口
     * @ClassName: IAccountDao
     * @author: benjamin
     * @createTime: 2019/07/24/17:07
     */
    public interface IAccountDao {
    
        /**
         * 模拟保存账户
         */
        void saveAccount();
    }
    
    /**
     * @ClassName: AccountDaoImpl
     * @author: benjamin
     * @version: 1.0
     * @description: 账户的持久层实现类
     * @createTime: 2019/07/24/17:10
     */
    
    public class AccountDaoImpl implements IAccountDao {
        public  void saveAccount(){
            System.out.println("保存了账户");
        }
    }
    
  4. 创建表现层

    /**
     * @ClassName: Client
     * @author: benjamin
     * @version: 1.0
     * @description: 模拟一个表现层,用于调用业务层
     * @createTime: 2019/07/24/17:08
     */
    
    public class Client {
        public static void main(String[] args) {
            // 耦合
            IAccountService as = new AccountServiceImpl();
            System.out.println(as);
            as.saveAccount();
        }
    }
    

    可以看到,现在程序中表现层与业务层,表现层和持久层出现了耦合,我们应该进行避免,下面采用工厂模式来降低耦合。

  5. 创建一个bean.properties文件

    accountService=com.ben.service.impl.AccountServiceImpl
    accountDao=com.ben.dao.impl.AccountDaoImpl
    
  6. 创建bean对象的工厂,它就是创建我们的service和dao对象的。

    Bean:在计算机英语中,有可重用组件的含义。

    JavaBean:用java语言编写的可重用组件。
    javabean > 实体类

    1. 需要一个配置文件来配置我们的service和dao配置的内容:唯一标识=全限定类名(key=value);
    2. 通过读取配置文件中配置的内容,反射创建对象。配置文件可以是xml也可以是properties(Spring框架中使用的是xml文件),在本次案例中我们使用properties。
    /**
     * @ClassName: BeanFactory
     * @author: benjamin
     * @version: 1.0
     * @description: bean工厂
     * @createTime: 2019/07/24/17:08
     */
    
    public class BeanFactory {
    
        //定义一个Properties对象
        private static Properties props;
    
        //定义一个Map,用于存放我们要创建的对象。我们把它称之为容器
        private static Map<String, Object> beans;
    
        //使用静态代码块为Properties对象赋值
        static{
            try {
                //实例化对象
                props = new Properties();
                //获取properties文件的流对象
                InputStream in = BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties");
                props.load(in);
                //实例化容器
                beans = new HashMap<String,Object>();
                //取出配置文件中所有的Key
                Enumeration keys = props.keys();
                //遍历枚举
                while (keys.hasMoreElements()){
                    //取出每个Key
                    String key = keys.nextElement().toString();
                    //根据key获取value
                    String beanPath = props.getProperty(key);
                    //反射创建对象
                    Object value = Class.forName(beanPath).newInstance();
                    //把key和value存入容器中
                    beans.put(key,value);
                }
            }catch(Exception e){
                throw new ExceptionInInitializerError("初始化properties失败!");
            }
        }
    
        /**
         * 根据bean的名称获取对象
         * @param beanName
         * @return Object
         */
        public static Object getBean(String beanName){
            return beans.get(beanName);
        }
    }
    
  7. 修改表现层文件

    public class Client {
        public static void main(String[] args) {
    
            for(int i=0;i<5;i++) {
                IAccountService as = (IAccountService) BeanFactory.getBean("accountService");
                System.out.println(as);
                as.saveAccount();
            }
        }
    }
    
posted @ 2019-07-25 10:38  伊万夫斯基  阅读(250)  评论(0编辑  收藏  举报