开发者社区> 问答> 正文

如何利用设计模式精简Java代码?

已解决

如何利用设计模式精简Java代码?

展开
收起
游客lmkkns5ck6auu 2022-10-26 19:05:45 586 0
1 条回答
写回答
取消 提交回答
  • 推荐回答
    1. 模板方法模式 模板方法模式(Template Method Pattern)定义一个固定的算法框架,而将算法的 一些步骤放到子类中实现,使得子类可以在不改变算法框架的情况下重定义该算法 的某些步骤。 @Repository public class UserValue { /** 值操作 / @Resource(name = "stringRedisTemplate") private ValueOperations<String, String> valueOperations; /* 值模式 / private static final String KEY_FORMAT = "Value:User:%s"; /* 设置值 / public void set(Long id, UserDO value) { String key = String.format(KEY_FORMAT, id); valueOperations.set(key, JSON.toJSONString(value)); } /* 获取值 / public UserDO get(Long id) { String key = String.format(KEY_FORMAT, id); String value = valueOperations.get(key); return JSON.parseObject(value, UserDO.class); } ... } @Repository public class RoleValue { /* 值操作 / @Resource(name = "stringRedisTemplate") private ValueOperations<String, String> valueOperations; /* 值模式 / private static final String KEY_FORMAT = "Value:Role:%s"; /* 设置值 / public void set(Long id, RoleDO value) { String key = String.format(KEY_FORMAT, id); valueOperations.set(key, JSON.toJSONString(value)); } /* 获取值 */ public RoleDO get(Long id) { String key = String.format(KEY_FORMAT, id); String value = valueOperations.get(key); return JSON.parseObject(value, RoleDO.class); } ... }

    public abstract class AbstractDynamicValue<I, V> { /** 值操作 / @Resource(name = "stringRedisTemplate") private ValueOperations<String, String> valueOperations; /* 设置值 / public void set(I id, V value) { valueOperations.set(getKey(id), JSON.toJSONString(value)); } /* 获取值 / public V get(I id) { return JSON.parseObject(valueOperations.get(getKey(id)), getValueClass()); } ... /* 获取主键 / protected abstract String getKey(I id); /* 获取值类 / protected abstract Class getValueClass(); } @Repository public class UserValue extends AbstractValue<Long, UserDO> { / * 获取主键 / @Override protected String getKey(Long id) { return String.format("Value:User:%s", id); } /* 获取值类 / @Override protected Class getValueClass() { return UserDO.class; } } @Repository public class RoleValue extends AbstractValue<Long, RoleDO> { / * 获取主键 / @Override protected String getKey(Long id) { return String.format("Value:Role:%s", id); } /* 获取值类 */ @Override protected Class getValueClass() { return RoleDO.class; } }

    1. 访问者模式 访问者模式(Visitor),封装一些作用于某种数据结构的各元素的操作,它可以在不 改变数据结构的前提下定义作用于这些元素的新的操作。 普通: public interface DataHandler { /** 解析数据 */ public T parseData(Record record);

      /** 存储数据 */ public boolean storeData(List dataList); } public long executeFetch(String tableName, int batchSize, DataHandler dataHandler) throws Exception { // 构建下载会话 DownloadSession session = buildSession(tableName); // 获取数据数量 long recordCount = session.getRecordCount(); if (recordCount == 0) { return 0; } // 进行数据读取 long fetchCount = 0L; try (RecordReader reader = session.openRecordReader(0L, recordCount, true)) { // 依次读取数据 Record record; List dataList = new ArrayList<>(batchSize); while ((record = reader.read()) != null) { // 解析添加数据 T data = dataHandler.parseData(record); if (Objects.nonNull(data)) { dataList.add(data); } // 批量存储数据 if (dataList.size() == batchSize) { boolean isContinue = dataHandler.storeData(dataList); fetchCount += batchSize; dataList.clear(); if (!isContinue) { break; } } } // 存储剩余数据 if (CollectionUtils.isNotEmpty(dataList)) { dataHandler.storeData(dataList); fetchCount += dataList.size(); dataList.clear(); } } // 返回获取数量

      return fetchCount; } /** 使用案例 / long fetchCount = odpsService.executeFetch("user", 5000, new DataHandler() { /* 解析数据 */ @Override public T parseData(Record record) { UserDO user = new UserDO(); user.setId(record.getBigint("id")); user.setName(record.getString("name")); return user; }

      /** 存储数据 */ @Override public boolean storeData(List dataList) { userDAO.batchInsert(dataList); return true; } }); 精简: public long executeFetch(String tableName, int batchSize, Function<Record, T> dataParser, Function<List , Boolean> dataStorage) throws Exception { // 构建下载会话 DownloadSession session = buildSession(tableName); // 获取数据数量 long recordCount = session.getRecordCount(); if (recordCount == 0) { return 0; } // 进行数据读取 long fetchCount = 0L; try (RecordReader reader = session.openRecordReader(0L, recordCount, true)) { // 依次读取数据 Record record; List dataList = new ArrayList<>(batchSize); while ((record = reader.read()) != null) { // 解析添加数据 T data = dataParser.apply(record); if (Objects.nonNull(data)) { dataList.add(data); } // 批量存储数据 if (dataList.size() == batchSize) { Boolean isContinue = dataStorage.apply(dataList); fetchCount += batchSize; dataList.clear(); if (!Boolean.TRUE.equals(isContinue)) { break; } } } // 存储剩余数据 if (CollectionUtils.isNotEmpty(dataList)) { dataStorage.apply(dataList); fetchCount += dataList.size();

      dataList.clear(); } } // 返回获取数量 return fetchCount; } /** 使用案例 */ long fetchCount = odpsService.executeFetch("user", 5000, record -> { UserDO user = new UserDO(); user.setId(record.getBigint("id")); user.setName(record.getString("name")); return user; }, dataList -> { userDAO.batchInsert(dataList); return true; });

    普通的访问者模式,实现时需要定义 DataHandler 接口,调用时需要实现
    DataHandler 匿名内部类,代码较多较繁琐。而精简后的访问者模式,充分利用了
    函数式编程,实现时无需定义接口,直接使用 Function 接口;调用时无需实现匿名
    内部类,直接采用 lambda 表达式,代码较少较简洁。
    3. 代理模式
    Spring 中最重要的代理模式就是 AOP(Aspect-Oriented Programming,面向切面
    的编程),是使用 JDK 动态代理和 CGLIB 动态代理技术来实现的。
    普通:
    
    精简 1:
    基于@ControllerAdvice 的异常处理:
    精简 2:
    基于 AOP 的异常处理:
    
    以上内容摘自《Java工程师必读手册》电子书,点击https://developer.aliyun.com/ebook/download/7780
    可下载完整版
    2022-10-26 20:46:28
    赞同 展开评论 打赏
来源圈子
更多
收录在圈子:
阿里云开发者社区官方技术圈,用户产品功能发布、用户反馈收集等。
问答排行榜
最热
最新

相关电子书

更多
Spring Cloud Alibaba - 重新定义 Java Cloud-Native 立即下载
The Reactive Cloud Native Arch 立即下载
JAVA开发手册1.5.0 立即下载