今天,我向开源世界迈出了第一步

今天,我在halo中提交了人生中的第一个pull request, 优化了一下附件上传的逻辑。 最主要的,是我成功迈出了走向开源的第一步。

事情起因

疫情在家, 时间充足;
再不收假, 毕设踌躇;

静极思动, 久坐念学;
项目先冲, 秋招一绝;

写个网盘, 两眼抹黑;
不会咋办? 翻遍Git;

突遇哈喽, 研究一手;
宝刀屠龙, 思路已有;

操作一波, 回看哈喽;
部分冗余, 可以动手;

轮讯不易, Hash优许;
说干就干, 编码走起;

改动的模块

在 halo 中,附件图片模块有多种存储方式, 如SMMS阿里OSS腾讯COS等。 一开始 halo 是将其存储在一个LinkList中的,用策略模式(或者是适配器?)在 FileHandler中提供统一的方法,然后根据参数去调用不同的实现。 这样就导致每次上传附件都需要遍历这个LinkList。 自然,此处比较容易想到可以用 Map 去存放数据,然后能够在 $O(1)$ 的时间内取得所需要的资源。 但是 Map 系列的容器需要取得所用的 Key。 这里由于上述的存储方式都实现自统一接口,所以我在接口中新加了一个方法getType去返回具体实现所支持的存储类型,然后小改了一下逻辑,使得逻辑更清楚了一些。

这里贴一下我改动影响比较大的部分

改动前(一)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
@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);
}

改动后(一)

1
2
3
4
@NonNull
public UploadResult upload(@NonNull MultipartFile file, @NonNull AttachmentType attachmentType) {
return getSupportedType(attachmentType).upload(file);
}

改动前

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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);
}

改动后(二)

1
2
3
4
public void delete(@NonNull Attachment attachment) {
Assert.notNull(attachment, "Attachment must not be null");
getSupportedType(attachment.getType()).delete(attachment.getFileKey());
}

新增方法

1
2
3
4
5
6
7
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;
}

可以看到,改动之后确实省下了不少代码量。 而且整个时间复杂度也从$O(n)$降低到了$O(1)$.


小记

在此之前,我一直很喜欢GitHub, 也想过贡献一些自己的代码。 但是限于能力和精力, 只是提交了几个 issue, 一是用到的开源产品已经比较完善了,二是没有深入研究过某些模块的源码。

其实这次我也没有专门去研究 halo 的全部源码,只是因为我自己毕设(打算写个可高度自定义的个人网盘)的原因就去参考了一下 halo 的附件模块和缓存模块的实现, 后来自己在仿写的时候发现这一部分能够优化,才有了提交 pull request 的想法。 我个人其实对开源世界一直怀有憧憬, 从我大二课设使用的 durid 开始, 一直到后面了解到 LombokfFastjsonSpringMyBatis 这些优秀的开源产品。 就像小时候有个江湖梦一样,现在的我也怀有一个开源的梦。


此次有机会能够为 halo 贡献小小的几十行代码我真的特别开心。

愿大家各出己力, 为开源世界添砖加瓦~

觉得文章不错的话可以请我喝一杯茶哟~
  • 本文作者: bestsort
  • 本文链接: https://bestsort.cn/2020/03/13/313/
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-SA 许可协议。转载请注明出处!并保留本声明。感谢您的阅读和支持!
-------------本文结束感谢您的阅读-------------