我对函数风格编程相当新,我在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")
}
此函数的作用类似于它检索的聚合器,并从其他函数调用相应的值/状态。 我不喜欢这个方法是在任何地方声明变量(val / var)来存储值以传递给其他方法。
为了便于阅读,我不能这样做
onCallListToMailRecipient.buildMailRecipientFromOnCalls(dataHubCommunicator
.listOfOnCallToSendNotificationFromDataHub(time))
是否有任何声明方式来编写此方法。我可以做些什么更改以使其更具说明性/功能性。
答案 0 :(得分:1)
您可以合并一些计算并减少本地变量的数量。另外,两个let
的最后一个序列相当无用,只需使用局部变量调用该函数即可。我添加了一些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")
}
答案 1 :(得分:1)
您可以尝试这样的事情
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)
}
答案 2 :(得分:1)
如果val临时变量仅在下一个语句中使用,则可以省略它们,而是在每个连续行上使用let
。应用该经验法则,您的示例可能如下所示:
val messageTemplate = extractEmailTemplateValue("retrieveNextOnCallAndSendMail")
?.let(messageTemplateAccessPoint::findByID)
dataHubCommunicator.listOfOnCallToSendNotificationFromDataHub(time)
?.let(onCallListToMailRecipient::buildMailRecipientFromOnCalls)
?.let {
messageTemplate?.let {
emailSender.sendNotificationToOnCallPersons(it, messageTemplate, trial)
}
}
它可能不是更易读,但它不那么笨重。
答案 3 :(得分:1)
如果您喜欢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显示提示,因此您可以获得自动变量+一些免费类型信息:
注意:总的来说,我会坚持?.
那里的一切真的可以在那里筑巢吗?如果我们需要指定it1
来区分it
,因为嵌套也可能很好地命名变量。
类型安全测试的声明存根的附录(我假设非空,但可以在任何地方添加问号):
interface OnCall
interface MessageTemplate
interface MessageTemplateID
interface MailRecipient
interface MessageTemplateAccessPoint {
fun findByID(it: MessageTemplateID): MessageTemplate
}
interface DataHubCommunicator {
fun listOfOnCallToSendNotificationFromDataHub(time: LocalDateTime): List<OnCall>
}
interface OnCallListToMailRecipient {
fun buildMailRecipientFromOnCalls(oncalls: List<OnCall>): 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()