今天,我在halo中提交了人生中的第一个pull request
, 优化了一下附件上传的逻辑。 最主要的,是我成功迈出了走向开源的第一步。
事情起因
疫情在家, 时间充足;
再不收假, 毕设踌躇;
静极思动, 久坐念学;
项目先冲, 秋招一绝;
写个网盘, 两眼抹黑;
不会咋办? 翻遍Git;
突遇哈喽, 研究一手;
宝刀屠龙, 思路已有;
操作一波, 回看哈喽;
部分冗余, 可以动手;
轮讯不易, Hash优许;
说干就干, 编码走起;
改动的模块
在 halo 中,附件图片模块有多种存储方式, 如SMMS、阿里OSS、腾讯COS等。 一开始 halo 是将其存储在一个LinkList中的,用策略模式(或者是适配器?)在 FileHandler中提供统一的方法,然后根据参数去调用不同的实现。 这样就导致每次上传附件都需要遍历这个LinkList。 自然,此处比较容易想到可以用 Map 去存放数据,然后能够在 的时间内取得所需要的资源。 但是 Map 系列的容器需要取得所用的 Key。 这里由于上述的存储方式都实现自统一接口,所以我在接口中新加了一个方法getType
去返回具体实现所支持的存储类型,然后小改了一下逻辑,使得逻辑更清楚了一些。
这里贴一下我改动影响比较大的部分
改动前(一)
@NonNull
public UploadResult upload(@NonNull MultipartFile file, @NonNull AttachmentType attachmentType) {
public UploadResult upload(@NonNull MultipartFile file, @NonNull AttachmentType attachmentType) {
Assert.notNull(attachmentType, "Attachment type must not be null");
return upload(file, attachmentType.name());
}
}
/**
* Uploads files.
*
* @param file multipart file must not be null
* @param type store type
* @return upload result
* @throws FileOperationException throws when fail to delete attachment or no available file handler to upload it
*/
@NonNull
public UploadResult upload(@NonNull MultipartFile file, @Nullable String type) {
Assert.notNull(file, "Multipart file must not be null");
for (FileHandler fileHandler : fileHandlers) {
if (fileHandler.supportType(type)) {
return fileHandler.upload(file);
}
}
throw new FileOperationException("No available file handlers to upload the file").setErrorData(type);
}
改动后(一)
@NonNull
public UploadResult upload(@NonNull MultipartFile file, @NonNull AttachmentType attachmentType) {
return getSupportedType(attachmentType).upload(file);
}
改动前
public void delete(@NonNull Attachment attachment) {
Assert.notNull(attachment, "Attachment must not be null"
getSupportedType(attachment.getType())
delete(attachment.getType().name(), attachment.getFileKey());
}
/**
* Deletes attachment.
*
* @param key file key
* @throws FileOperationException throws when fail to delete attachment or no available file handler to delete it
*/
public void delete(@Nullable String type, @NonNull String key) {
for (FileHandler fileHandler : fileHandlers) {
if (fileHandler.supportType(type)) {
// Delete the file
fileHandler.delete(key);
return;
}
}
throw new FileOperationException("No available file handlers to delete the file").setErrorData(type);
}
改动后(二)
public void delete(@NonNull Attachment attachment) {
Assert.notNull(attachment, "Attachment must not be null");
getSupportedType(attachment.getType()).delete(attachment.getFileKey());
}
新增方法
private FileHandler getSupportedType(AttachmentType type) {
FileHandler handler = fileHandlers.getOrDefault(type, fileHandlers.get(AttachmentType.LOCAL));
if (handler == null) {
throw new FileOperationException("No available file handlers to operate the file").setErrorData(type);
}
return handler;
}
可以看到,改动之后确实省下了不少代码量。 而且整个时间复杂度也从降低到了.
小记
在此之前,我一直很喜欢GitHub, 也想过贡献一些自己的代码。 但是限于能力和精力, 只是提交了几个 issue, 一是用到的开源产品已经比较完善了,二是没有深入研究过某些模块的源码。
其实这次我也没有专门去研究 halo 的全部源码,只是因为我自己毕设(打算写个可高度自定义的个人网盘)的原因就去参考了一下 halo 的附件模块和缓存模块的实现, 后来自己在仿写的时候发现这一部分能够优化,才有了提交 pull request
的想法。 我个人其实对开源世界一直怀有憧憬, 从我大二课设使用的 durid 开始, 一直到后面了解到 Lombok
、 fFastjson
、 Spring
、 MyBatis
这些优秀的开源产品。 就像小时候有个江湖梦一样,现在的我也怀有一个开源的梦。
此次有机会能够为 halo 贡献小小的几十行代码我真的特别开心。
愿大家各出己力, 为开源世界添砖加瓦~
本文使用 mdnice 排版