Amber Doctor
Senior Software Engineer
in Kotlin
Amber Doctor
May 25, 2018
class EmailSender (private val ApiKey: String,
private val useSandbox: Boolean) {
fun sendEmail(emailContent: EC): String {
val emailer = Emailer(ApiKey)
emailer.addRequestHeader(
useSandbox,
"Bearer $ApiKey")
val request = buildEmail(emailContent)
println("Sent ${request.subjectText}")
return emailer.api(request)
}
}
fun getEmailSender(ApiKey: String, useSandbox: Boolean):
(emailContent: EC) -> String {
return {
emailContent: EC ->
val emailer = Emailer(ApiKey)
emailer.addRequestHeader(
useSandbox,
"Bearer $ApiKey")
val request = buildEmail(emailContent)
println("Sent ${request.subjectText}")
emailer.api(request)
}
}
fun main(args: Array<String>){
// some data - same for both
val myEmailContent = EC("First Email", "World", "Hello")
val myEmailContent2 = myEmailContent.copy(subjectText = "Second Email")
// with functions
// You can do this 1 time in the whole project
val myEmailSender = getEmailSender("ValidApiKey", true)
myEmailSender(myEmailContent) // Sent First Email
myEmailSender(myEmailContent2) // Sent Second Email
// with class
val myClassEmailSender = EmailSender("ValidApiKey", true)
myClassEmailSender.sendEmail(myEmailContent) // Sent First Email
myClassEmailSender.sendEmail(myEmailContent2) // Sent Second Email
}
class EmailSenderOT (private val ApiKey: String,
private val useSandbox: Boolean) {
private val emailer = Emailer(ApiKey)
init {
emailer.addRequestHeader(
useSandbox,
"Bearer $ApiKey")
}
fun sendEmail(emailContent: EC): String {
val request = buildEmail(emailContent)
println("Sent ${request.subjectText}")
return emailer.api(request)
}
}
fun getEmailSenderOT(ApiKey: String, useSandbox: Boolean):
(emailContent: EC) -> String {
val emailer = Emailer(ApiKey)
emailer.addRequestHeader(
useSandbox,
"Bearer $ApiKey")
return {
emailContent: EC ->
val request = buildEmail(emailContent)
println("Sent ${request.subjectText}")
emailer.api(request)
}
}
class EmailSenderOT (private val ApiKey: String,
private val useSandbox: Boolean) {
private val emailer = Emailer(ApiKey)
init {
emailer.addRequestHeader(
useSandbox,
"Bearer $ApiKey")
}
fun sendEmail(emailContent: EC): String {
// uses ApiKey & useSandbox
}
fun buildEmail(emailContent: EC): EC {
// uses none of the constructor params
// do stuff
return emailContent
}
}
fun buildEmail(emailContent: EC): EC {
// uses none of the constructor params
// do stuff
return emailContent
}
Easier testing - don't have to create:
Use buildEmail w/out class overhead (same testing bullets)
Variables in a closure have perfect encapsulation.
Side effects are more explicit.
class Counter(private var currentNumber: Int) {
init {
currentNumber -= 2
}
fun countByTwo(): Int {
currentNumber += 2
return currentNumber
}
}
fun main(args: Array<String>){
val myClassCounter = Counter(0)
println(myClassCounter.countByTwo()) // 2
println(myClassCounter.countByTwo()) // 4
println(myClassCounter.countByTwo()) // 6
println(myClassCounter.countByTwo()) // 8
}
fun getCountByTwo(startNumber: Int): ()-> Int {
var currentNumber = startNumber - 2
return {
currentNumber += 2
currentNumber
}
}
fun main(args: Array<String>){
val myCounter = getCountByTwo(0)
println(myCounter()) // 2
println(myCounter()) // 4
println(myCounter()) // 6
println(myCounter()) // 8
}
For full code examples:
https://github.com/amberdoctor/functional-patterns
For questions:
amberdoctor+functional.patterns.demo@gmail.com
By Amber Doctor