Preface:
In complex actual businesses, various nested conditional judgment logics often appear. We need to consider all possible situations. As the demand increases, the conditional logic will become more and more complex, and the judgment function will become quite long, and these codes cannot be easily modified. Every time you change the requirements, you must ensure that all branches' logical judgments are changed.
Faced with this situation, simplifying the judgment logic is something that has to be done. Here are a few methods
Practical examples
@GetMapping("/exportOrderRecords") public void downloadFile(User user, HttpServletResponse response) { if (user != null) { if (!() && authenticate()) { String fileType = (); // Obtain file type if (!(fileType)) { if (("csv")) { doDownloadCsv(); // Download strategies for different types of files } else if (("excel")) { doDownloadExcel(); // Download strategies for different types of files } else { doDownloadTxt(); // Download strategies for different types of files } } else { doDownloadCsv(); } } } } public class User { private String username; private String role; private String fileType; }
The above example is a file download function. We download Excel, CSV or TXT files according to user needs. Before downloading, you need to make some legal judgments, such as verifying user permissions and verifying the format of the requested file.
How to use
In the example above, there are four layers of nesting. But the outermost two layers nesting is to verify the validity of the parameters. The code can only run normally if the condition is true. Assertions can be used()
. Thrown if the assertion is not trueRuntimeException
. (Note that exception will be thrown, the same is true in kotlin)
@GetMapping("/exportOrderRecords") public void downloadFile(User user, HttpServletResponse response) throws Exception { (user != null, "the request body is required!"); ((()), "download file is for"); (authenticate(()), "you do not have permission to download files"); String fileType = (); if (!(fileType)) { if (("csv")) { doDownloadCsv(); } else if (("excel")) { doDownloadExcel(); } else { doDownloadTxt(); } } else { doDownloadCsv(); } }
It can be seen that after using assertions, the code is more readable. The code can be divided into two parts, one is the parameter verification logic, and the other is the file download function.
Table Driver
Assertions can optimize some conditional expressions, but they are not good enough. We still need to judgefiletype
Properties to determine the file format to download. Assuming that the requirements have changed now and we need to support the download of word format files, we need to directly modify the code in this section, which actually violates the principle of opening and closing.
Table drivers can solve this problem:
private HashMap<String, Consumer> map = new HashMap<>(); public Demo() { ("csv", response -> doDownloadCsv()); ("excel", response -> doDownloadExcel()); ("txt", response -> doDownloadTxt()); } @GetMapping("/exportOrderRecords") public void downloadFile(User user, HttpServletResponse response) { (user != null, "the request body is required!"); ((()), "download file is for"); (authenticate(()), "you do not have permission to download files"); String fileType = (); Consumer consumer = (fileType); if (consumer != null) { (response); } else { doDownloadCsv(); } }
It can be seen that after using table driver, if you want to add a new type, you only need to add a key-value to the map.
Use enumeration
In addition to table drivers, we can also use enumerations to optimize conditional expressions and encapsulate various logics in specific enumeration instances. This can also improve the scalability of the code. In fact, Enum is essentially a table-driven implementation. (Kotlin can use sealed class to deal with this problem, but the implementation method is different)
public enum FileType { EXCEL(".xlsx") { @Override public void download() { } }, CSV(".csv") { @Override public void download() { } }, TXT(".txt") { @Override public void download() { } }; private String suffix; FileType(String suffix) { = suffix; } public String getSuffix() { return suffix; } public abstract void download(); } @GetMapping("/exportOrderRecords") public void downloadFile(User user, HttpServletResponse response) { (user != null, "the request body is required!"); ((()), "download file is for"); (authenticate(()), "you do not have permission to download files"); String fileType = (); FileType type = (fileType); if (type!=null) { (); } else { (); } }
Policy Mode
We can also use policy patterns to simplify conditional expressions and abstract download processing in different file formats into different policy classes.
public interface FileDownload{ boolean support(String fileType); void download(String fileType); } public class CsvFileDownload implements FileDownload{ @Override public boolean support(String fileType) { return "CSV".equalsIgnoreCase(fileType); } @Override public void download(String fileType) { if (!support(fileType)) return; // do something } } public class ExcelFileDownload implements FileDownload { @Override public boolean support(String fileType) { return "EXCEL".equalsIgnoreCase(fileType); } @Override public void download(String fileType) { if (!support(fileType)) return; //do something } } @Autowired private List<FileDownload> fileDownloads; @GetMapping("/exportOrderRecords") public void downloadFile(User user, HttpServletResponse response) { (user != null, "the request body is required!"); ((()), "download file is for"); (authenticate(()), "you do not have permission to download files"); String fileType = (); for (FileDownload fileDownload : fileDownloads) { (fileType); } }
The policy pattern is helpful for improving code scalability. To extend a new type, just add a policy class.
This is the article about Android's method of using Java to elegantly eliminate complex conditional expressions. For more relevant contents of Android conditional expressions, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!