java耦合与解耦

耦合

程序间的依赖关系,如:程序代码和第三方库(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 类,编译期间也不会提示错误,在运行期间,才会报错,这就是解耦


原文出处:/show_1IX1OJiZw2u.html