将多个方法合并为一个函数的方法

我是function风格编程的世界相当新的我正在尝试在Kotlin的一些代码,下面给出的代码片段是我所做的,但看起来这么强迫我

@EmailTemplate("onCallTemplate") fun retrieveNextOnCallCreateMailRecipientAndSendMail(time: LocalDateTime, trial: Boolean = true) { val emailTemplateID = extractEmailTemplateValue( "retrieveNextOnCallAndSendMail") val messageTemplate = emailTemplateID?.let { messageTemplateAccessPoint.findByID(it) } val lisOfOnCalls = dataHubCommunicator .listOfOnCallToSendNotificationFromDataHub(time) val listOfMailRecipient = lisOfOnCalls ?.let { onCallListToMailRecipient.buildMailRecipientFromOnCalls(it) } listOfMailRecipient ?.let { messageTemplate ?.let { it1 -> emailSender .sendNotificationToOnCallPersons(it, it1, trial) } } log.info("Message Has been sent Successfully") } 

这个函数就像它检索的聚合器一样工作,并从其他函数调用相应的值/状态。 我不喜欢这个方法是声明variables(val / var)无处不在,以存储值传递给其他方法。

为了可读性,我无法做到这一点

 onCallListToMailRecipient.buildMailRecipientFromOnCalls(dataHubCommunicator .listOfOnCallToSendNotificationFromDataHub(time)) 

有没有任何声明的方式来写这种方法。我可以做些什么变化,使其更多的声明/function。

你可以合并一些计算,减少局部variables的数量。 另外,两个let的最后一个序列是无用的,只需用你的局部variables调用函数。 我添加了一些null检查。

 val messageTemplate = extractEmailTemplateValue("retrieveNextOnCallAndSendMail")?.let { messageTemplateAccessPoint.findByID(it) } ?: throw IllegalStateException (“Todo”) val listOfMailRecipient = dataHubCommunicator.listOfOnCallToSendNotificationFromDataHub(time)?.let { onCallListToMailRecipient.buildMailRecipientFromOnCalls(it) } ?: throw IllegalStateException (“Todo”) emailSender .sendNotificationToOnCallPersons(listOfMailRecipient, messageTemplate, trial).also{ println("Message Has been sent Successfully") } 

你可以尝试这样的事情

 fun retrieveNextOnCallCreateMailRecipientAndSendMail(time: LocalDateTime, trial: Boolean = true) { doWithListOfMail(time) { l -> doWithTemplate('retrieveNextOnCallAndSendMail') { t -> emailSender.sendNotificationToOnCallPersons(l, t, trial) } } log.info("Message Has been sent Successfully") } fun doWithTemplate(id: String, action: (Template) -> Void){ val emailTemplateID = extractEmailTemplateValue(id) val messageTemplate = emailTemplateID?.let { messageTemplateAccessPoint.findByID(it) } messageTemplate?.let(action) } fun doWithListOfMail(time : LocalDateTime, action: (List) -> Void) { val lisOfOnCalls = dataHubCommunicator .listOfOnCallToSendNotificationFromDataHub(time) val listOfMailRecipient = lisOfOnCalls?.let { onCallListToMailRecipient.buildMailRecipientFromOnCalls(it) } listOfMailRecipient?.let(action) } 

如果仅在下一条语句中使用val临时variables,则可以省略val临时variables。 应用该经验法则,您的示例可能如下所示:

 val messageTemplate = extractEmailTemplateValue("retrieveNextOnCallAndSendMail") ?.let(messageTemplateAccessPoint::findByID) dataHubCommunicator.listOfOnCallToSendNotificationFromDataHub(time) ?.let(onCallListToMailRecipient::buildMailRecipientFromOnCalls) ?.let { messageTemplate?.let { emailSender.sendNotificationToOnCallPersons(it, messageTemplate, trial) } } 

它可能不是更具可读性,但体积更小。

事情可能取决于其中的一些无效,如果你喜欢let家庭,你也可以做这样的事情:

 fun retrieveNextOnCallCreateMailRecipientAndSendMail(time: LocalDateTime, trial: Boolean = true) = dataHubCommunicator .listOfOnCallToSendNotificationFromDataHub(time) .let { onCallListToMailRecipient.buildMailRecipientFromOnCalls(it) } .apply { val template = messageTemplateAccessPoint.findByID( extractEmailTemplateValue("retrieveNextOnCallAndSendMail")) emailSender.sendNotificationToOnCallPersons(this, template, trial) } .also { log.info("Message has been sent successfully to ${it}") } // if you have nullable recipient and want to detect failure // ?: log.info("Message not sent") 

注意:块中的新行有助于IDEA显示提示,因此您可以获得自动variables+一些免费的types信息: IDEA提示

注:一般来说,我会阻止?. 那里的一切真的是空的吗? 如果我们需要指定it1来区分it ,那么也可以借此机会很好地命名variables。

附录中的types安全测试的声明存根(我假设非null,但是可以在任何地方添加questionmarks):

 interface OnCall interface MessageTemplate interface MessageTemplateID interface MailRecipient interface MessageTemplateAccessPoint { fun findByID(it: MessageTemplateID): MessageTemplate } interface DataHubCommunicator { fun listOfOnCallToSendNotificationFromDataHub(time: LocalDateTime): List } interface OnCallListToMailRecipient { fun buildMailRecipientFromOnCalls(oncalls: List): MailRecipient } interface EmailSender { fun sendNotificationToOnCallPersons(recipient: MailRecipient, template: MessageTemplate, trial: Boolean) } fun extractEmailTemplateValue(name: String): MessageTemplateID = TODO() val dataHubCommunicator: DataHubCommunicator = TODO() val messageTemplateAccessPoint: MessageTemplateAccessPoint = TODO() val onCallListToMailRecipient: OnCallListToMailRecipient = TODO() val emailSender: EmailSender = TODO()