根据用户选择从而获取网络资源或本地资源。(实现会非常的简单,此文章的意义在于利用反射突出 业务与逻辑分离 的优点)
资源的父类:
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("获取网络资源"); } }代码如下:
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("获取其他资源"); } }该如何改进呢?很简单!我们只需要在配置文件里增加一个新的类名和类路径,不需要对源码做任何修改。如图所示:
让我们看一下运行结果:
通过这个简单的案例,相信大家也对业务与逻辑分离的思想有了一定的认识。能降低耦合性就降低耦合性,情愿写麻烦一点也不要让耦合性太高,耦合性太高的代码,移植和改造都很不容易。
