Eliminate Boilerplate using Kotlin Extensions

Allan Caine
2 min readDec 25, 2017

--

Kotlin’s extensions can be used to reduce boiler-plate in your code. To illustrate, let’s consider a simple custom View. The custom view, MyView, subclasses TextView. Let us suppose that the custom view has an associated styleable xml

The custom view can be incorporated into a layout xml using the attribute theText:

The process of getting an attribute from an xml is generally done in the same way every time:

  1. The TypedArray is obtained fromContext.obtainStyledAttributes(…)
  2. Methods of the TypedArray are used to assign attribute’s values to class properties in a try block
  3. The TypedArray is recycled in a finally block

Without simplification using Kotlin extensions, the implementation of MyView is

Line 5 corresponds to Step 1; line 8 step 2; and line 10 step 3.

We can begin simplification by observing that only line 8 in the try/finally block is truly unique to MyView. The rest is boiler plate. We can relegate the try/finally block to a Kotlin extension of TypedArray:

We can simplify the MyView class as

The line which reads

text = getString(R.styleable.MyView_theText)

is the block mentioned in lines 1 and 3 of the ViewCreateUtils. The code which is unique to MyView is passed to TypedArray.use(block: TypedArray.() -> Unit) as a lambda function.

Further simplification is possible. Obtaining the TypedArray from the Context is done in the same way for custom views. We can define an extension on Context.

The final simplification of MyView is

Remarkably, the TypedArray is not directly mentioned in the simplified code. The extension function getStyledAttributes does the work of obtaining the TypedArray for us. The try/finally block is not mentioned either. The use extension function runs line 6 above for us in a try block. Finally, the TypedArray is recycled in a finally block for us.

By using extension functions and lambdas, our initializer has gone from

init {
val typedArray = context.obtainStyledAttributes(attributeSet, R.styleable.MyView, 0, 0)

try {
text = typedArray.getText(R.styleable.MyView_theText)
} finally {
typedArray.recycle()
}

to

init {
context.getStyledAttributes(attributeSet, R.styleable.MyView) {
text = getString(R.styleable.MyView_theText)
}

All of the boiler plate code has been eliminated. The simplified init block only contains the essential code.

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

--

--

Allan Caine
Allan Caine

Written by Allan Caine

Senior Android Developer, TD Bank (Canada) (Opinions are my own)

No responses yet

Write a response