【Java】浅谈关于代码的耦合性
前言
前几天一个在公司里的朋友对还正在Java的道路上的我说了一些关于代码耦合性的问题,刚好今天碰上一个很好的案例,就拿来运用一下,用这个简单的案例突出一下**业务与逻辑分离**的一种思想,希望能对大家有所帮助。一、需求
根据用户选择从而获取网络资源或本地资源。(实现会非常的简单,此文章的意义在于利用反射突出 业务与逻辑分离 的优点)
二、简单的实现
1.资源代码(项目提供)
资源的父类:
public abstract class DataSource {
public abstract void getData();
}
本地资源:
public class LocalDataSource extends DataSource{
@Override
public void getData() {
System.out.println("获取本地资源");
}
}
网络资源:
public class NetworkDataSource extends DataSource{
@Override
public void getData() {
System.out.println("获取网络资源");
}
}
2.对需求的普通实现
代码如下:
import java.util.Scanner;
public class Test01 {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.println("请选择资源: 1.本地资源 2.网络资源");
int num = scan.nextInt();
LocalDataSource localDataSource = new LocalDataSource();
NetworkDataSource networkDataSource = new NetworkDataSource();
if(num == 1) {
localDataSource.getData();//获取本地资源
}else if(num == 2){
networkDataSource.getData();//获取网络资源
}
scan.close();
}
}
实现的截图:
简单的实现结束,但是大家有没有想过,如果客户针对需求改进,增加其他的资源,程序编写者将做何改变呢?在源码上修改输出?重新实例化一个对象然后再增加一个判断方式?也许一个你觉得简单,如果客户增加了多种资源的获取途径呢?这只是个简单的项目,如果后续的项目涉及到更多的关联,改变源码会变成一个很不明智的行为。
接下来将 利用反射体现一下 业务与逻辑分离 的思想,以及这样编写的优势。
三、利用业务与逻辑分离的方式实现
改进
首先编写配置文件:
import java.util.ArrayList;
import java.util.List;
//配置文件
public class Config {
public static List<String> nameList = new ArrayList<>();
public static List<String> classPathList = new ArrayList<>();
static{
nameList.add("本地资源");
nameList.add("网络资源");
classPathList.add("packet.class.LocalDataSource");
classPathList.add("packet.class.NetworkDataSource");
}
}
对测试代码的改进:
import java.util.List;
import java.util.Scanner;
public class Test01 {
public static void main(String[] args) throws Exception {
/**
* 利用反射 -- 传达 业务与逻辑分离 的思想
*/
Scanner scan = new Scanner(System.in);
System.out.println("请选择资源: ");
printMenu(); //后续更新的资源会自动填补打印
int num = scan.nextInt();
DataSource dataSource = getDataSource(num);
dataSource.getData();
scan.close();
}
//根据用户的选择,创建出对应的数据对象
public static DataSource getDataSource(int num) throws Exception{
List<String> classPathList = Config.classPathList;
String classPath = classPathList.get(num-1);
Class<?> c = Class.forName(classPath);
DataSource dataSource = (DataSource) c.newInstance();
return dataSource;
}
//打印菜单
public static void printMenu(){
List<String> nameList = Config.nameList;
StringBuilder sb = new StringBuilder();
for (int i = 0; i < nameList.size(); i++) {
sb.append(i+1);
sb.append(".");
sb.append(nameList.get(i));
sb.append(" ");
}
System.out.println(sb.toString());
}
}
虽然代码增多了,但耦合性也降低了,如果客户提供了新的需求,更改会非常的方便,更改如下:
四、对需求改进后的同步项目改进(优点)
新需求:在原先功能上增加一个其他类资源。
这是新增的其他资源:
//其他资源
public class OtherDataSource extends DataSource{
@Override
public void getData() {
System.out.println("获取其他资源");
}
}
该如何改进呢?很简单!我们只需要在配置文件里增加一个新的类名和类路径,不需要对源码做任何修改。如图所示:
让我们看一下运行结果:
总结
通过这个简单的案例,相信大家也对业务与逻辑分离的思想有了一定的认识。能降低耦合性就降低耦合性,情愿写麻烦一点也不要让耦合性太高,耦合性太高的代码,移植和改造都很不容易。