【版本任你发】-6-自己的事情自己做

81 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 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 的哪些应用呢?欢迎你在评论区和其他读者讨论!