设计模式-工厂模式实现解耦

1. 什么是耦合

在一个大程序中,多个模块之间存在着依赖关系, 就是耦合, 耦合不可避免, 我们要做的就是尽可能降低耦合度, 实现高内聚低耦合的代码;
举个例子:
javaWEB开发中常用的三层结构, Controller层, Service层, Dao层,
Service层要调用dao层方法,就必须要在Service层创建一个Dao层接口的实现类对象, 如果Service层有很多类都创建了Daoceng接口实现类的对象, 当Dao层接口修改的时候, Service层的所有类都要一一修改, 给后期维护造成了很大的麻烦; 所以本章我们来介绍工厂模式是如何解决这类耦合的.

2. 传统未解耦时

Dao层接口和实现类

//Dao层接口
public interface AccountDao {
     

    void saveAccount();
}
//Dao层接口的实现类
public class AccountDaoImpl implements AccountDao {
     
    @Override
    public void saveAccount() {
     
        System.out.println("模拟保存账号操作......");
    }
}

Service层接口和实现类,在Service实现类中我们看到创建了dao层的实现类对象,出现了耦合情况;

//service层接口
public interface AccountService {
     
    //存钱方法
    void saveAccount();
}
//service层接口的实现类
public class AccountServiceImpl implements AccountService {
     
    //这里有耦合,创建了dao层接口的实现类对象
    private AccountDao accountDao= new AccountDaoImpl();
    @Override
    public void saveAccount() {
     
        //调用dao方法实现保存功能
        accountDao.saveAccount();
    }
}

3 工厂模式解决耦合

  1. 新建beans.xml文件
<?xml version="1.0" encoding="utf-8" ?>
<beans>
    <bean id="AccountDao" class="com.itheima.Dao.impl.AccountDaoImpl"/>
    <bean id="AccountService" class="com.itheima.service.impl.AccountServiceImpl"/>
</beans>
  1. 定义一个工厂类工具类
public class BeanFactory {
     
    //定义一个map集合, 键是接口名字,作为参数, 值为接口名字对应的实现类对象 作为方法的返回值
    private static Map<String,Object> map=new HashMap<>();
    static{
     

        //将beans.xml文件加载到内存中得到字节输入流对象
        InputStream inputStream = BeanFactory.class.getClassLoader().getResourceAsStream("beans.xml");
        //创建SAXReader对象,调用read方法将字节输入流读入,生成document对象
        SAXReader saxReader=new SAXReader();
        try {
     
            Document document = saxReader.read(inputStream);
            //使用document对象的getRootElement方法获取beans标签对象
            Element beans = document.getRootElement();
            //获取所有bean标签的集合数据
            List<Element> beanList = beans.elements();
            //遍历beanList,
            for (Element bean : beanList) {
     
                //获取id的属性值
                String idValue = bean.attributeValue("id");
                //获取class的属性值,得到接口实现类对应的全限定名
                String classValue = bean.attributeValue("class");
                //通过反射获取实现类的类对象
                Class clazz = Class.forName(classValue);
                //创建实例
                Object interfaceImplObj = clazz.newInstance();
                //将id和实例对象存放到map集合中, 这样集合中就包含了beans.xml中所有实现类对应的对象了
                map.put(idValue,interfaceImplObj);
            }
        } catch (Exception e) {
     
            e.printStackTrace();
        }
    }
    //定义一个静态方法传递健 获取值
    public static Object getBean(String interfaceName){
     

        //返回接口对象
        return map.get(interfaceName);
    }
}

  1. 在Service接口实现类中,调用工厂类的getBean方法, 成功获取了AccountDao接口实现类对象; 以后如果dao层的实现类有改动, 我们只需要在beans.xml配置文件中进行响应修改就可以了,不需要操作Service层代码, 实现了解耦;
public class AccountServiceImpl implements AccountService {
     

    //调用工厂类的getBean方法,基于接口名字获取接口的实现类对象
    private AccountDao accountDao= (AccountDao) BeanFactory.getBean("AccountDao");

    @Override
    public void saveAccount() {
     

        //调用dao方法实现保存功能
        accountDao.saveAccount();
    }
}

你可能感兴趣的:(Java入门)