Writing Maintainable Android Code

Writing code is an art and writing maintainable code is teamwork.

The essence of writing maintainable code is to keep it stupidly simple, hey I said it as simple as possible not inefficient! The more simpler you will write it the more easier your life will be. If you are thinking that something you are writing is really complex, you should better think about changing your logic! Developers often try to hack the systems or break the conventions where making changes to existing code is difficult.

So what is maintainable code? I have a counter question to answer this. How many times it happens, when you try to edit someone else code and unknowingly inject a bug? or at least you have no confidence that it will not create any new bug? Well if you don’t want this happen to your code then you are talking about writing maintainable code.

Okie, ¬†programmers hate long texts and so they hate writing too ūüėČ lets jump directly to what this article has to offer. I will be dividing the¬†maintainability¬†of code into following sections,

  • Coding conventions
  • Using constants
  • Art of commenting
  • Refactoring
  • Reducing dependencies
  • Code organization

Coding Conventions

  • All class and interfaces names should be in PascalCase (PascalCase is often called UpperCamelCase, where 1st letter is also capitalized)
  • Class name should be a singular noun. i.e. representing single object!
  • All functions and variables should be in camelCase.
  • Avoid very concise names that doesn’t mean anything, use as many characters as you need to name it properly.
  • Method names should start with verb or helping verb to define the functionality.
  • Constants should be all caps, separated by underscore.
  • Constant name should start with the type or functional group, it helps you use the IDE’s code hinting feature effectively, for example STATUS_DRAFT, STATUS_PUBLISHED.
  • Try avoiding names like temp, foo, value1, arg1, tempResult etc even for temporary calculations.

Some good examples can be

 

Using Constants

Using raw integers or strings in the code not only makes maintenance difficult as you need to change it on all the instances in case when a change occurred, but it also make it very difficult to understand whats going on in the code.

Consider the following example

Did you get a clue what its trying to do? Yes its some sort of validation, but what exactly its doing here? Any suggestions how to make it more readable? Adding comments? what about this!

Do I need to do anything else to explain this?

When it comes to constants, not only integer but String constants also make strong case to avoid unintentional logical errors, consider the following example.

It will never tell you that you made a spelling mistake, and can potentially cost lots of man hours to find this logical bug! Rather you cannot misspell a defined constant in java! May be you can think that you will never made a spelling mistake by copy pasting the string instead of typing it manually, but can you guarantee the same thing for future maintainer of your code?

Art of Commenting

Myth: Well my code is pretty! its self-explanatory and you should understand it when you read it the first time! Why should I bother writing comments?

Reality: Even with most good quality code, a new developer have to go from line to line in order to know whats going on, some lines of quick comments can make him jump directly to his desired areas.

Here are some quick points that can make writing comments more effective,

  • If you are writing a library, following some standard documentation conventions can help you generate the documents for your code¬†automatically.
  • Every public function should quickly describe what its trying to do, what are the parameters and what type of return values / error you may expect from the method, its very important if you are writing a helper class or some library.
  • If you are writing some logic, that you think you may feel trouble if you will open it again when you will get back from vocations after two weeks, you should better write comments here.
  • Avoid too long comments that can distract user from reading the code.
  • Avoid writing comments on every line! unless absolute necessary due to some complex¬†algorithm.
  • Avoid writing too obvious comments like “increasing the counter”, “adding b into a” etc
  • Must write comments if you think your code looks like a bug but you are doing it intentionally! (otherwise some sweet colleague may try to fix this bug without¬†embarrassing¬†you :p)

Here goes some examples, (parentheses contain discussion over comments)

Refactoring

Its a detailed topic and you can find books on the topic of effective refactoring. I will be discussing it in more details under Reducing dependencies topic, here are some quick tips to make your code looks better, easy to understand and less fragile.

  • All your methods should follow the single responsibility principle! i.e. they must perform only a single atomic task!
  • Method name should exactly define what its doing, and it shouldn’t do anything else internally.
  • Shouldn’t write more then two, three line under click handler. Thats only fine if you are trying to open some new activity. Otherwise create functions and call them appropriately.
  • If your method is doing more then one thing, create multiple methods (could be private) and call them appropriately.
  • Avoid Stamp Coupling: When passing the values to function, avoid passing the whole object when it only needs one or two¬†primitive¬†values. It makes the function really opaque when seeing signature as you are not sure what this function might be doing with this object, also you are taking risk of modifying the object within function.
  • If your function takes few inputs and return some value without affecting any of class or global variables or doing anything else, and its output only depends upon the input you are passing, make it a static function (and may be in some helper class). I m not a big fan of static functions, but functionally you have already created one!

Example: TBD

Reducing Dependencies

Still editing this section, majorly several types of decouplings, already discussed stamp decoupling above, some basic ideas are

  • Avoid inner classes where ever you can. Yes including that LoginAsyncTask that you create in LoginActivity ūüėČ
  • Avoid passing a¬†decision¬†making parameter to function, like passing a boolean flag.
  • Follow MVC structure, its here to separate the code, not mix up!
    • Avoid creating views from within code, if you will ever get a layout change what will be the first place that you will look for?
    • Avoid making coding¬†decisions¬†based on some state of view.. i.e.
    • Avoid sequential dependency between functions, i.e. function A( ) must be called before function B( ), if two functions are always supposed to be called together then at least you should have these both functions as private and wrap them with proper public function which indicate the proper functionality (big picture).
    • Avoid some global variable or data sharing source thats only created to communicate some data between two methods. There must be some way around to complete your logic without this, in other case you are running a risk of that global¬†variable being modified between two calls. This design will easily break when you will need concurrency.¬†¬†Two methods reading / modifying a common class level variable is a different case and its not considered as a bad design as far as that attribute make sense in the object model (though even in this case you need to handle multi-threading).

Example: TBD

Code Organization

Its about how you can organize your classes into proper packages. There are two common ways to organize classes into packages.

  1. By Features / Modules
  2. By Function

The former way is useful for some enterprise applications where each module is big enough that it has its own functional groups and usually don’t share the functional classes or¬†data-structure¬†with other modules. While for smaller systems like android apps the 2nd option is a popular choice. A common android app should contain the following packages, where the names are self explanatory.

  • com.example.app (for application screens)
  • com.example.app.adapter (for adapters, usually used for list-views & fragments)
  • com.example.app.custom_view (any custom views you might have created)
  • com.example.app.database (database related classes, content providers)
  • com.example.app.helper (static helper classes)
  • com.example.app.model (data models, some people tend to name this package as ‘pojo’)

 

Comments
Share