耦合
程序间的依赖关系,如:程序代码和第三方库(mybatis、log4j),Servlet层与service层
分2种:
- 类之间的依赖
- 方法间的依赖
解耦
降低程序间的依赖关系:编译时不依赖,运行时才依赖
耦合与解耦 例子1
程序 和 第三方类库的耦合
耦合
创建maven工程
pom.xml增加依赖:
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
</dependencies>
在 java 包下创建类,代码如下:
//耦合性强,如果没有引入 mysql驱动包 就会提示错误
Driver driver=new com.mysql.jdbc.Driver();
DriverManager.registerDriver(driver);
String url="jdbc:mysql://127.0.0.1:3308/douban";
String username="root";
String password="";
//创建数据库连接
Connection conn=DriverManager.getConnection(url, username, password);
if(conn!=null && !conn.isClosed()){
System.out.println("连接成功!");
}
造成耦合的原因: 直接使用类,会造成耦合
注意: 不可能做到 完全不使用类。这是一种平衡,不要走极端
解耦方式一
String driver="com.mysql.jdbc.Driver";
//反射方式加载驱动,就是为了解耦
Class.forName(driver);
String url="jdbc:mysql://127.0.0.1:3308/douban";
String username="root";
String password="";
//创建数据库连接
Connection conn=DriverManager.getConnection(url, username, password);
if(conn!=null && !conn.isClosed()){
System.out.println("连接成功!");
}
避免耦合的方法: 避免使用类,用反射的方法使用类
解耦方式二
如果需要连接oracle数据库,就需要修改上面的源代码,加载 oracle.jdbc.driver.OracleDriver驱动类
还是有耦合性
解决方法:将 类全名 写在配置文件中,java代码通过读取配置文件,加载驱动类
db.properties配置文件:
# driver=com.mysql.jdbc.Driver
driver=oracle.jdbc.driver.OracleDriver
java代码
//从配置文件中读取驱动类
Properties p=new Properties();
p.load(new FileInputStream("src\\main\\resources\\db.properties"));
String driver=p.getProperty("driver");
//反射方式加载驱动
Class.forName(driver);
String url="jdbc:mysql://127.0.0.1:3308/douban";
String username="root";
String password="";
//创建数据库连接
Connection conn= DriverManager.getConnection(url, username, password);
if(conn!=null && !conn.isClosed()){
System.out.println("连接成功!");
}
驱动类名字完全不出现在源代码中,而是通过配置文件决定加载哪个驱动类,极大的降低了耦合性
耦合与解耦 例子2
层与层之间的耦合,为了简化程序,只实现了 主启动类 和 service类,没有实现 dao 类
耦合
service接口
public interface IUserService {
public void save(String username,String password);
}
接口实现类
public class UserSrvImpl implements IUserService {
public void save(String username,String password){
System.out.println("保存 "+username+","+password+" 成功!");
}
}
主启动类
public class Main {
public static void main(String[] args) {
IUserService srv=new UserSrvImpl();
srv.save("李雷","123456");
}
}
在 主启动类 中出现了 new UserSrvImpl() ,层与层之间,通过 new 创建对象,耦合性就强
同理,如果实现了 dao 接口 和 类,那么在 service 中 new dao类,也是耦合性强
解耦
修改 主启动类,不再出现 new UserSrvImpl() ,而是通过读取配置文件,用反射的方式创建对象,如下:
public class Main {
public static void main(String[] args) {
try {
Properties p = new Properties();
p.load(new FileInputStream("src\\main\\resources\\bean.properties"));
String clazz = p.getProperty("UserSrvImpl");
IUserService srv=(IUserService)Class.forName(clazz).newInstance();
srv.save("李雷","123456");
}catch (Exception e){
e.printStackTrace();
}
}
}
即使工程中没有 UserSrvImpl 类,编译期间也不会提示错误,在运行期间,才会报错,这就是解耦