Easy Life with Kotlin 😇
somehow quarantine makes me feel not productive especially when I got a lot of projects and should be finished ASAP, so I create some sort of code which is usually used in my side project to simplify and reduce my repetitive code sometime 🤪
.
1.Kotlin Extension is function with steroid we can add some Type of data as receiver example
fun Int.multiplyBy(value : Int) : Int = this * valuehow to use :
val result = 9.mutiplyBy(8)
or we could enhance variable with lambda
val multiply : (Int , Int) -> Int = { x, y -> x * y}how to use :
val result = multiply(9,8)
another one used receiver 📡
val multiplyBy : Int.(Int) -> Int = { value -> this * value}how to use :
val result = 9.multiplyBy(8)
we can chaining one or more function into single LOC.
val plusBy : Int.(Int) -> Int = { value -> this +value}how to use :
val result = 2.plusBy(1).multiplyBy(10)
⚡ we can easily manipulate any list with high order function, one of my favorite is map
.
val orders : List<Order> = listOf(Order(1,”nasgor”,12000),Order(3,”cuangki”,10000)how to use :
val ordersPrice : List<Int> = orders.map { it.price }
Sealed Class 🦭
It’s like enum class but fancier, we can even make safe execute to guarantee your high-risk function will not get any runtime exception just use some of the try-catch but wrap with sealed class in it.
sealed class Try<out A> {
data class Failure<out A>(val exception: Throwable) : Try<A>()
data class Success<out A>(val value: A) : Try<A>()
}inline operator fun <A> invoke(func: () -> A): Try<A> = try {
Try.Success(func())
} catch (ex: Throwable) {
Try.Failure(ex)
}how to use :
invoke {
//just run your high risk function here
getInternalSensorStatus()
}
Create an extension of your repetitive unit test code it even makes your unit test more readable.
infix fun <T> Subscriber<T>.`hasValue`(value : T?) {
//add your repetitive code here
assertComplete()
assertNoError()
assertValueCount(1)
assertValue(value)
}how to use :
@Test
fun TestMySubsriberHasValue{
someSubscriber `hasValue` expectedValue
}
make webserver test more readable with kotlin extension stuff and of course reduce repetitive code.
enum class HttpMethod {
DELETE,GET,POST,PUT,PATCH
}enum class ContentType(val type : String) {
FORM_URL_ENCODED("xxx-form-url-encoded")
JSON("json-type")
}data class ExpectedRequest{
authorization : String?,
method : HttpMethod?,
contentType : ContentType?,
path : String?,
body : String?
}infix fun `received request`(expectedReq : ExpectedRequest){
val actualReq : MyRequest = this.takeRequest()
actualReq `is valid` actualReq.authorization
other checking value, etc...
}infix fun MyRequest.`is valid`(value : String){
this.getHeader("Authorization") `should equal` value
}infix fun <T> T.`should equal`(expected : T) : T = this.apply{
assertEqual(expected,this)
}how to use :
mockWebserver `received request` ExpectedRequest(
authorization = "BEARER SECURE_TOKEN",
method = POST,
contentType = JSON,
path = "/evm/search/query",
body = """{ "product" : "celana kulot cantik pisan", "size" :
"L"}"""
)
Operator Overloading
operator fun CompositeDisposable.plusAssign(disposable : Disposable{
add(disposable)
}how to use :
fun searchModel(query :String){
compositeDisposable += repository.searchModel(query).subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(::doAction)
}
Bundle Delegate it’s very useful for any lazy developer write key for fragment instance
class StringBundleDelegate{
operator fun getValue(
bundle : Bundle,
property : KProperty<*>
):String {
return bundle.getString(property.name)
} operator fun setValue(
bundle : Bundle,
property : KProperty<*>,
value : String?){
bundle.putString(property.name)
}
}
val Bundle.Title : String? by StringBundleDelegate()
val Bundle.Id : String? by StringBundleDelegate()fun newInstanceFragmentHome(title : String,catalogId : String) : HomeFragment{
val bundle = Bundle()
bundle.Title = title
bundle.Id = catalogId
return HomeFragment().also{
arguments = bundle
}
}override fun onViewCreated(view: View, savedInstanceState: Bundle?){
dataBinding.appbar.title = arguments?.Title
arguments?.Id?.let { id ->
viewModel.getCatalogId(id)
}
}
you can read more trick here : https://kotlinlang.org/docs/reference/android-overview.html