如何编写优雅的 Java 代码( 二 )

@Cleanup添加输入输出流 close 方法,如:
public static void main(String[] args) throws Exception{@Cleanup InputStream inputStream = new FileInputStream("1.txt");}我们通过断点调试发现,它会调用 close(),说明 lombok 帮我们生成了 close():

如何编写优雅的 Java 代码

文章插图
 
通过 lombok 的注解,可以极大的减少我们的代码量,并且更加清爽,更加优雅 。
lombok 还有很多注解,如:
  • @ToString: 生成 toString() 方法 。
  • @EqualsAndHashCode: 生成 equals 和 hashCode 方法 。
日志相关注解(当然需要添加相关日志依赖):
  • Slf4j、Log4j 等 。
  • NoArgsConstructor、AllArgsConstructor: 生成无参和全参构造函数 。
  • Value: 生成 getter、toString、equals、hashCode 和全参构造函数 。
  • NonNull: 标注在字段和方法上,表示非空,会在第一次使用时判断 。
巧用设计模式一说到设计模式,我相信大家都能说出那 23 种设计模式,并且还能说出每种设计模式的用法,但是大多数同学应该都没有在实际应用中真正运用过设计模式,还只是停留在理论阶段 。
不知道各位是否有过这个感觉,整个应用被相同的代码充斥着,自己也知道这种代码不好,但是不知道怎么做优化,虽然知道有 23 种设计模式,却不知道怎么运用 。
本节我就将以实际的例子教大家如何在实际应用中灵活运用所学的设计模式 。
(实际应用中,一个场景可能不只包含一个设计模式,很有可能需要多种设计模式配合使用才能写出优雅的高质量的代码 。)
场景 1:导出报表我们在做后台管理系统时,会有这样一个需求,根据后台的数据统计导出报表,需要支持 Excel、word、PPT、PDF 等格式 。
对于以上需求,一般做法是:为每一个导出报表的方法提供一个方法,然后在 Service 里判断,如果为 excel,则调用 excel 的方法,如果为 Word 则调用 word 的方法,
如:
public void exportReport(String type){if("Excel".equals(type)){exportExcel();}else if("Word".equals(type)){exportWord();}...}这样写本身没有问题,也能实现需求,但是它有以下缺点:
  • 1.代码不够优雅,业务方法内存在太多 if - else 。
  • 2.扩展性不强,每增加一个报表格式,就需要修改业务方法,增加一个 if - else 。
我们在开发时需要遵循有一个原则:一个方法做你该做的事 。也就是无论增加什么样的报表格式,业务方法 exportReport 的作用依然是导出功能,除非业务需求发生改变,否则不能修改业务方法 。
那么,我们该怎么改造呢?
我们发现,导出报表可以导出不同的格式,这些格式我们可以理解为产品,需要由一个地方产出,因此马上就能想到可以利用工厂模式对其进行改造,下面是改造后的代码:
public enum Type {EXCEL,WORD,PPT,PDF;}/** * 模板引擎基类 * 所有模板类继承此类 * @author 李熠 * */public abstract class Template {//读取内容public abstract List<Serializable> read(InputStream inputStream)throws Exception;//写入内容public abstract void write(List<Serializable> data)throws Exception;}//Excel模板public class ExcelTemplate extends Template {@Overridepublic List<Serializable> read(InputStream inputStream)throws Exception{List<Serializable> list = new ArrayList<>();return list;}@Overridepublic void write(List<Serializable> data) throws Exception {}}public class TemplateFactory {public static Template create(Type type){Template template = null;switch (type){case EXCEL:template = new ExcelTemplate();break;}return template;}public static void main(String[] args) {Template template = TemplateFactory.create(Type.EXCEL);template.read(input);template.write(data);}}这样就完成了工厂模式对报表导出的改造,在业务方法内,通过 TemplateFactory 创建 template,然后调用 template 的 read 或 write 方法,以后我们每增加一个格式,只需要实现 Template 的相应方法,在 factory 实例化它即可,无需修改业务方法 。
此场景用到的设计模式有:简单工厂模式 。
场景 2:分步骤执行任务这种场景也比较多见,比如: