问题:

程序的耦合
   耦合:程序间的依赖关系
   包括:类之间的依赖
      方法之间的依赖
解耦:降低程序之间的耦合关系
   实际开发:编译期不依赖,运行期才依赖
   解耦思路:
        1. 使用反射来创建对象,而避免使用new关键字
        2. 通过读取配置文件来获取要创建的对象全限定类名

下方代码中:注册驱动时需要依赖第三方驱动。两种处理方法

package com.itheima;import java.sql.*;
public class JdbcDemo1 {public static void main(String[] args) throws Exception {//1.注册驱动//注册驱动方法1:编译期依赖其他类,一旦该类不存在//会编译期报错:Compilation completed with 1 error and 0 warningsDriverManager.registerDriver(new com.mysql.jdbc.Driver());//注册驱动方法2:编译期不依赖其他类,一旦该类不存在//会运行期报错:java.lang.ClassNotFoundException:com.mysql.jdbc.DriverClass.forName("com.mysql.jdbc.Driver");//2.获取连接Connection conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/eesy","root","root");//3.获取操作数据库的预处理对象PreparedStatement pstm=conn.prepareStatement("select * from account");//4.执行sql,得到结果集ResultSet rs=pstm.executeQuery();//5.遍历结果集while (rs.next()){System.out.println(rs.getString("name"));}//6.释放资源rs.close();pstm.close();conn.close();}
}

真实场景的解决思路:

表现层

package com.itheima.ui;import com.itheima.Service.IAccountService;
import com.itheima.factory.BeanFactory;/*** 模拟一个表现层,用于调用业务层*/
public class Client {public static void main(String[] args) {IAccountService as =new AccountServiceImpl();as.saveAccount();}
}

业务层接口

package com.itheima.Service;/*** 账户业务层的接口*/
public interface IAccountService {/*** 模拟保存账户*/void saveAccount();
}

业务层实现

package com.itheima.Service.impl;import com.itheima.dao.IAccountDao;
import com.itheima.factory.BeanFactory;
import com.itheima.Service.IAccountService;/*** 账户的业务层实现类*/
public class AccountServiceImpl implements IAccountService {private IAccountDao accountDao=new AccountDaoImpl();private int i = 1;@Overridepublic void saveAccount() {accountDao.saveAccount();System.out.println(i);i++;}
}

持久层接口

package com.itheima.dao;/*** 账户的持久层接口*/
public interface IAccountDao {/*** 模拟保存账户的操作*/void saveAccount();
}

持久层实现

package com.itheima.dao.impl;import com.itheima.dao.IAccountDao;/*** 账户的持久层实现类*/
public class AccountDaoImpl implements IAccountDao {@Overridepublic void saveAccount() {System.out.println("保存了");}
}

运行结果:

保存了
1

初级升级改造【工厂模式解耦,同时带来多例问题】:

表现层

package com.itheima.ui;import com.itheima.Service.IAccountService;
import com.itheima.factory.BeanFactory;/*** 模拟一个表现层,用于调用业务层*/
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();}}
}

工厂层

package com.itheima.factory;import java.io.InputStream;
import java.util.Properties;public class BeanFactory {//定义一个Properties对象private static Properties props;//使用静态代码块为Properties对象赋值static{try {//实例化对象props=new Properties();//获取properties文件的流对象InputStream in = BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties");props.load(in);} catch (Exception e) {throw new ExceptionInInitializerError("初始化properties失败");}}public static Object getBean(String beanName){Object bean = null;try {String beanPath=props.getProperty(beanName);bean = Class.forName(beanPath).newInstance();//每次都会调用默认构造函数创建对象} catch (Exception e) {e.printStackTrace();}return bean;}}

业务层接口

package com.itheima.Service;/*** 账户业务层的接口*/
public interface IAccountService {/*** 模拟保存账户*/void saveAccount();
}

业务层实现

package com.itheima.Service.impl;import com.itheima.dao.IAccountDao;
import com.itheima.factory.BeanFactory;
import com.itheima.Service.IAccountService;/*** 账户的业务层实现类*/
public class AccountServiceImpl implements IAccountService {private IAccountDao accountDao= (IAccountDao)BeanFactory.getBean("accountDao");private int i = 1;@Overridepublic void saveAccount() {accountDao.saveAccount();System.out.println(i);i++;}
}

持久层接口

package com.itheima.dao;/*** 账户的持久层接口*/
public interface IAccountDao {/*** 模拟保存账户的操作*/void saveAccount();
}

持久层实现

package com.itheima.dao.impl;import com.itheima.dao.IAccountDao;/*** 账户的持久层实现类*/
public class AccountDaoImpl implements IAccountDao {@Overridepublic void saveAccount() {System.out.println("保存了");}
}

运行结果:

com.itheima.Service.impl.AccountServiceImpl@3caeaf62
保存了
1
com.itheima.Service.impl.AccountServiceImpl@e6ea0c6
保存了
1
com.itheima.Service.impl.AccountServiceImpl@6a38e57f
保存了
1
com.itheima.Service.impl.AccountServiceImpl@5577140b
保存了
1
com.itheima.Service.impl.AccountServiceImpl@1c6b6478
保存了
1

从运行结果可以看出,每次都实例化了一个新的对象
由于对象被创建多次,执行效率就没有单例对象高
不存在线程问题

终极升级改造【单例】:

表现层

package com.itheima.ui;import com.itheima.Service.IAccountService;
import com.itheima.factory.BeanFactory;/*** 模拟一个表现层,用于调用业务层*/
public class Client {public static void main(String[] args) {//IAccountService as =new AccountServiceImpl();for(int i=0;i<5;i++) {IAccountService as = (IAccountService) BeanFactory.getBean("accountService");System.out.println(as);as.saveAccount();}}
}

工厂层

package com.itheima.factory;import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;/***一个创建Bean对象的工厂** Bean:在计算机英语中,有可重用组件的含义* JavaBean:用Java语言编写的可重用组件。*   javabean >  实体类*   第一个:需要配置文件来配置我们的service和dao*    配置内容:唯一标识=全限定类名(key-value)*   第二个:通过配置文件中配置的内容,反射创建对象**   配置文件可以是xml,properties*/
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>();//取出配置文件中的所有keyEnumeration keys=props.keys();//遍历枚举while(keys.hasMoreElements()){//取出每个keyString key =keys.nextElement().toString();//根据key获取valueString beanPath=props.getProperty(key);//反射创建对象Object value=Class.forName(beanPath).newInstance();//把key和value存入容器beans.put(key,value);}} catch (Exception e) {throw new ExceptionInInitializerError("初始化properties失败");}}public static Object getBean(String beanName){return beans.get(beanName);}
}

业务层接口

package com.itheima.Service;/*** 账户业务层的接口*/
public interface IAccountService {/*** 模拟保存账户*/void saveAccount();
}

业务层实现

package com.itheima.Service.impl;import com.itheima.dao.IAccountDao;
import com.itheima.factory.BeanFactory;
import com.itheima.Service.IAccountService;/*** 账户的业务层实现类*/
public class AccountServiceImpl implements IAccountService {//关键************************************************************************private IAccountDao accountDao= (IAccountDao)BeanFactory.getBean("accountDao");private int i = 1;@Overridepublic void saveAccount() {accountDao.saveAccount();System.out.println(i);i++;}
}

持久层接口

package com.itheima.dao;/*** 账户的持久层接口*/
public interface IAccountDao {/*** 模拟保存账户的操作*/void saveAccount();
}

持久层实现

package com.itheima.dao.impl;import com.itheima.dao.IAccountDao;/*** 账户的持久层实现类*/
public class AccountDaoImpl implements IAccountDao {@Overridepublic void saveAccount() {System.out.println("保存了");}
}

运行结果:

com.itheima.service.impl.AccountServiceImpl@4554617c
保存了
1
com.itheima.service.impl.AccountServiceImpl@4554617c
保存了
2
com.itheima.service.impl.AccountServiceImpl@4554617c
保存了
3
com.itheima.service.impl.AccountServiceImpl@4554617c
保存了
4
com.itheima.service.impl.AccountServiceImpl@4554617c
保存了
5

单例情况下,对象只被创建了一次,类中的成员也就只会初始化一次
当出现多线程访问的情况,由于对象的实例只有一个,当操作对象的类成员的时候,类成员就会在对象中改变

【Spring】工厂模式解耦相关推荐

  1. Spring学习(2)-程序间耦合和工厂模式解耦

    程序的耦合及解耦 本文目录 程序的耦合及解耦 1.什么是程序的耦合 2.解决程序耦合的思路 3.工厂模式解耦 4.控制反转-Inversion Of Control 5.使用 spring 的 的 I ...

  2. 工厂模式解耦---控制反转

    控制反转 是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度.其中最常见的方式叫做依赖注入(Dependency Injection,简称DI),还有一种方式叫"依赖查找&q ...

  3. 使用Spring工厂模式管理多个类实现同一个接口

    最近小白在看 Spring IOC 和 AOP 源码时发现 Spring 中有很多类都实现了同一个接口,像下面这种 public interface AopProxy {Object getProxy ...

  4. 曾经案例中问题 与 工厂模式解耦

    一个创建Bean对象的工厂 * Bean:在计算机英语中,有可重用组件的含义. * JavaBean:用java语言编写的可重用组件. *      javabean >  实体类 * *   ...

  5. 工厂模式解耦的升级版

    package com.learn.service;/*** 账户业务层的接口*/ public interface IAccountService {/*** 模拟保存账户*/void saveAc ...

  6. 浅谈Spring框架应用的设计模式(一)——工厂模式

    文章目录 前言 一.工厂模式介绍 1.简单工厂模式 (1)静态工厂模式 (2)利用反射机制实现的简单工厂 2.工厂方法模式 3.抽象工厂模式 二.Spring框架中工厂模式的重要应用 1.BeanFa ...

  7. Spring框架----IOC的概念和作用之工厂模式

    创建bean对象的工厂 bean在计算机英语中,有可重用组件的含义 可重用:可反复使用.组件:组成部分,比如service可以被servlet反复使用,dao被service使用.service可以看 ...

  8. 一文带你看懂工厂模式

    大家好我是mihotel,今天来总结一下设计模式中的工厂模式,在平时编程中,构建对象最常用的方式是 new 一个对象.乍一看这种做法没什么不好,而实际上这也属于一种硬编码.每 new 一个对象,相当于 ...

  9. 已知长宽高用php求周长体积_PHP工厂模式计算面积与周长

    <?phpinterface InterfaceShape{ function getArea(); function getCircumference();} /** * 矩形 */class ...

最新文章

  1. Android开发之 adb 启动问题或是部署应用不成功,出现“The connection to adb is down, and a severe error has occured.”错误...
  2. 【翻译】25个浏览器开发工具的秘密
  3. Python中修改字符串的四种方法
  4. groovy定义变量获取当前时间_Groovy - 比较日期和时间
  5. Javaweb---监听器
  6. Unable to resolve target 'android-7'
  7. havok之shape
  8. C语言程序设计100个经典例子
  9. 二分类模型性能评价 2.0(ROC曲线,lift曲线,lorenz曲线)
  10. python rgb565_RGB565的转换
  11. codevs 3083 二叉树
  12. 群晖NAS Git Server项目源代码管理 配置搭建
  13. 你对MySQL中的索引了解多少?
  14. JavaScript.笔记
  15. PPI是什么?pixels per inch像素密度是什么?PPI如何计算?
  16. Virgo与Maven整合开发环境搭建(一)
  17. 西工大:那些人儿、那些事儿
  18. C语言中 * “星号”的九种用法
  19. NNDL 作业7:第五章课后题(1×1卷积核|CNN BP)
  20. Cadence 16.6安装配置教程

热门文章

  1. 更改Jenkins升级站点
  2. 2022-2028年中国氟膜行业市场全景评估及发展策略分析报告
  3. 107. Binary Tree Level Order Traversal II
  4. 2019-3:时间飞逝
  5. Pytorch Bi-LSTM + CRF 代码详解
  6. Android数据持久化:SharePreference
  7. LeetCode简单题之有序数组中出现次数超过25%的元素
  8. 大三后端暑期实习面经总结——SSM微服务框架篇
  9. MindSpore 高阶优化器
  10. JavaWeb--过滤器