开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第7天,点击查看活动详情
0.背景
话说我们的小孙同志苦练老罗传授给他的函数式接口编程,几乎已经进入走火入魔的地步。一日,小黄写了一段代码,向小孙炫耀,是关于生成默认 README 文件的。只见小黄先写了一个接口:
public interface DirectoryService {
void createReadMeFile(String relativeDir);
}
然后给出了实现:
public class DirectoryServiceImpl implements DirectoryService {
private static final DirectoryProperty DIRECTORY_PROPERTY = DirectoryProperty.DIRECTORY_PROPERTY;
@Override
public void createReadMeFile(String relativeDir) {
System.out.println("create ReadMe in " + DIRECTORY_PROPERTY.getContextDir() + "/" + relativeDir);
}
}
小孙问她:“你这个 DirectoryProperty 是干什么的?”小黄回答说:“记录属性值啊,记录最外层总的目录,还有各个相对的路径,怎么样?是不是很妙?”
public class DirectoryProperty {
public static final DirectoryProperty DIRECTORY_PROPERTY = new DirectoryProperty("/myContext","pic");
/**
* 上下文目录
*/
private String contextDir;
/**
* 基于上下文的相对目录
*/
private String pictureRelativeDir;
public DirectoryProperty(String contextDir, String pictureRelativeDir) {
this.contextDir = contextDir;
this.pictureRelativeDir = pictureRelativeDir;
}
public String getPictureRelativeDir() {
return pictureRelativeDir;
}
public void setPictureRelativeDir(String pictureRelativeDir) {
this.pictureRelativeDir = pictureRelativeDir;
}
public String getContextDir() {
return contextDir;
}
public void setContextDir(String contextDir) {
this.contextDir = contextDir;
}
}
小孙一脸不屑:“那你怎么调用的呢?”
小黄给他看调用的地方:
public class DirectoryPropertyTest {
private static final DirectoryProperty DIRECTORY_PROPERTY = DirectoryProperty.DIRECTORY_PROPERTY;
public static void main(String[] args) {
DirectoryService directoryService = new DirectoryServiceImpl();
directoryService.createReadMeFile(DIRECTORY_PROPERTY.getPictureRelativeDir());
}
}
小孙笑话她:“你这,你看啊,你这 DirectoryProperty 用了两遍,外边用一遍,服务里边用一遍。人家调用的人要是给你瞎传值呢?你不完蛋了?”
小黄急了:“你凭什么说我啊?这不用两遍还用一遍啊?我存的属性我不得取啊?那你说咋改?”
小孙挠挠头:“你等我一下啊,我记得谁给我讲过,我忘了……”
小黄乐了:“你啊,就是癞蛤蟆上高速,冒充小吉普。”
1. Function 传递取值动作
老罗一边打开加湿器,一边把头凑过来看。她微笑着说:“你不是希望安全性吗?搞个“专类专用”,可以使用 Function 来做这个事儿。”
小孙怀疑地说:“行吗?”小黄使劲拽坐在座位上的小孙:“赶紧起来吧,让大神指导一下,你啥也不是!”
老罗不慌不忙敲了起来:“我们首先把 String 换成我们要传递的函数。”
public interface DirectoryService {
void createReadMeFile(Function<DirectoryProperty,String> relativeDirFunction);
}
在服务中啊,我们已经有了属性值,所以只需要让这个服务知道去获取什么就可以了,不必把真实的值传过来,因为属性值是自管理的。
public class DirectoryServiceImpl implements DirectoryService {
private static final DirectoryProperty DIRECTORY_PROPERTY = DirectoryProperty.DIRECTORY_PROPERTY;
@Override
public void createReadMeFile(Function<DirectoryProperty, String> relativeDirFunction) {
String relativeDir = relativeDirFunction.apply(DIRECTORY_PROPERTY);
System.out.println("create ReadMe in " + DIRECTORY_PROPERTY.getContextDir() + "/" + relativeDir);
}
}
老罗补充道:“在外层调用的时候,直接传递方法就可以。这样啊,就可以实现小孙说的,只有一个地方存放了属性。”
public class DirectoryPropertyTest {
public static void main(String[] args) {
DirectoryService directoryService = new DirectoryServiceImpl();
directoryService.createReadMeFile(DirectoryProperty::getPictureRelativeDir);
}
}
小孙和小黄一起为老罗鼓掌,老罗笑了笑,不自觉看了看日历,再有几天,就是她一百三十五岁的生日了。看着两个新人啥也不会,老罗的眼角泛起了泪花。
结语
本例中,我们再次学习了传递方法,而不是传递实际值的编程思想。让函数成为变量的一等公民是诸多编程语言的潮流,你听说过函数式编程吗?那么你可以了解一下!
它属于"结构化编程"的一种,主要思想是把运算过程尽量写成一系列嵌套的函数调用。
你还想到 Function 的哪些应用呢?欢迎你在评论区和其他读者讨论!