Another programming language!

During the last year while searching and exploring code examples of Android’s new technologies like Jet pack architecture components our team noticed that more and more code on the git hub is posted only in Kotlin – the new programming language for Android platform. And that raised a question in our team, is this new kid on the block something that can speed up our app development even more and we should start to prepare for another transition? And as usually we started to explore and see what benefits the new language can bring. But for me all this recalled my own experience with programming languages and how I was switching between different languages.

My first encounter with programming happened at high school and the first language I learned was BASIC. The friendship with BASIC lasted only a year. When I started to study at university I switched to Pascal. Yes, that was quite long time ago. At that time most of the software I was producing was dealing with mathematics and were command line utilities. I didn’t see a much difference between those two languages except that now in Pascal along the variables I had to declare their types. The course at university was organised so that students had to start with some high level language and gradually switching to C/C++. So far in the length of time I was switching from simple to more complex languages, and at that point of time it didn’t seem that switching to more complex language would ease the programming process, on the contrary the C/C++ comparing with BASIC made it harder to write software that solve mathematical problems. And that was the first time when I learned about the Programming domain. C/C++ gave me the ability to write software for almost any domain. But at the same time for some tasks more high level languages were preferable. After C/C++ followed SQL and Java, then C# and JavaScript. When I switched from C++ to Java the same task could take 10-25% less coding. Now the operations with text were easier and all pointers were gone. When I learned C# and that was the time when Microsoft released C# version 2.0, but Oracle had Java 1.5 I noticed in cases where callbacks and events where used in C# I could type 5-10% less code. But this increase in productivity was only in certain programming domains, like Windows applications. In other areas like embedded systems or OS C was still the main option, and the arise of new languages didn’t really affect those fields. The main conclusion I made for myself was that if a new language emerges, then most likely it speeds up development only in certain domain.

And what about Kotlin? The creators of Kotlin JetBrains claim that replacing Java with Kotlin will allow developers be more productive. After playing with Kotlin little bit and converting some existing Android classes into Kotlin we saw that it could really be the case. Then we looked at oficial Kotlin’s documentation where Kotlin is compared with Java and although some of the features we are really missing in Java like Data classes, Null-safety and Extensions we didn’t really see anything groundbreaking. And we were about to put Kotlin aside for this project since :

  • our team doesn’t feel yet so comfortable with Kotlin that we could produce code that is easy readable and follow best practices. To master the language requires time.
  • The productivity we would gain would not outweigh the time we would spent on learning the new language

We assumed if we want to switch to the new language we have to convert the whole application code base to the new language and keep coding in Kotlin, but then we noticed this tutorial saying that we can mix Java and Kotlin in one project. And we saw this as a good opportunity some of the files write in Kotline. And one of the first candidates for Kotlin we chose entities and DTO. It requires to learn very few new syntax and classes can be made much smaller thanks to getting rid of getters and setters. We decided to spend some time on learning Kotlin and once we learn the feature that really reduces the number of code lines and brings something valuable in code comparing with Java we will write that peace of code in Kotlin. In such way we hope we can keep the same development speed while learning new language and at some point of time start to reduce the development time comparing with Java. It worked well in time when I switched from C/C++ to Java and now it looks like it is time to switch from Java to Kotlin.

http://fitradar.me/

Migrating to the new navigation system

In my last article I mentioned that we migrated to the new Android’s navigation system that is a part of Android Jetpack components. This time I want to share some implementation details. Usually in my posts I don’t really like to share the actual code, but only concepts, since there are plenty of implementation examples for the particular concept, and I don’t want to repeat what the others already wrote, I rather prefer to explain the reasoning behind the one or another decision. But while migrating to the new navigation system our team has faced a few challenges, that was not possible to resolve just by reading available documentation and copying code examples, therefore I think some implementation details we came up with might help someone who is striving to master the new navigation system.

Problem

After all our Fragment and Activity analysis we came to conclusion that we should have several activities In our application which would serve as hosts for set of Fragments. And the features we used to group by the fragments were:

  • common master layout
  • common UI logic
  • common use case

So we started to explore the documentation and look for code examples, that would help us to understand how to implement the navigation from one navigation graph to the other graph hosted in different activities. And very quickly we realized that the documentation and examples available on the Internet are heavily focused around a single Activity application and navigation between the fragments hosted in one navigation graph. Although official Android documentation mentions that the new navigation system supports Activities as destinations. The biggest challenge was to find a way how to assign the start destination to navigation graph at runtime depending on various parameters. In our app user should be able to create a sport event and later edit it or delete it. All fragments related to sport event we decided to put in one navigation graph. But the start destination in this graph depends on whether user wants to create a new sport event, edit previously created sport event or see other user’s sport event. So we could not assign the start destination at design time in navigation graph but we had to do it at runtime. Since we could not find enough information how to do it, we started to consider other solutions.

Solution

Spending hours on reading documentation and exploring examples we started to think maybe we should use only one Activity. And put all UI logic from the other Activities in this one and show/hide the parts in UI which are needed/not needed for active fragment. But very soon it became clear that this universal hosting activity is getting very big and it is hard to read it and we have to add additional logic for hiding and showing views in Activity. The hosting activity became something opposite we were striving for – smaller and more manageable classes. So we dropped this idea and started to consider moving the views from Activities to Fragments, that Fragments would contain all the necessary views and UI logic and hosting Activity would be left only with NavHostFragment. That would mean that views like BottomNavigationView and Toolbar now would be located in several Fragments. We could ofcourse use include tag but that still would not remove the need to repeat the same include tags in several fragments. So we didn’t really like this idea either, since it looked like we are violating the DRY (Don’t Repeat Yourself) principle. And we got back to the idea about several activities. This time in order to find a solution we started to dig in to the navigation components source code, and after awhile we came up with the following implementation that allows assign a start destination to a navigation graph at runtime:


private void initNavGraph() {
    NavHostFragment navHostFragment = (NavHostFragment) getSupportFragmentManager()
            .findFragmentById(R.id.sport_activity_nav_fragment);
    NavInflater inflater = navHostFragment.getNavController().getNavInflater();
    NavGraph graph = inflater.inflate(R.navigation.nav_sport_event);
    String sportEventId = getIntent().getStringExtra(EXTRA_SPORT_EVENT_ID);
    long calendarEventId = getIntent().getLongExtra(CalendarContract.Events._ID, -1);
    if (calendarEventId == -1 && sportEventId == null) {
        graph.setStartDestination(R.id.editMySportEventFragment);
    } else {
        graph.setStartDestination(R.id.bookSportEventFragment2);
    }
    this.mNavController = navHostFragment.getNavController();
    graph.addDefaultArguments(getIntent().getExtras());
    this.mNavController.setGraph(graph);
}

The above method creates new navigation graph and sets the needed start destination, and passes arguments we set in Intent when started the hosting Activity. In such way we can pass needed arguments further to the start destination. And finally we set this new navigation graph with defined start destination and arguments in navigation controller.

Striving for better code

Recently we refactored our Android’s application navigation system – we replaced fragment transactions with Android Jetpack navigation component. We already had a good experience with migrating from Model View Presenter architecture to Model View View Model architecture (using Android Jetpack Architecture software components). During refactoring we had to convert our existing presenters and views into viewmodels and views with binding expressions. There was a risk of loosing time due doing unplanned activity, therefore before making the decision of migration we carefully estimated the risks related to refactoring. And the main question we were facing with was: will we see a benefit of a refactoring before the app’s release? (We already saw the benefit in a long term, but were not sure about the immediate gain). Calculations showed that even doing refactoring we would gain in development speed. And indeed it turned out that within a month our invested time started to pay off and we started faster implement new use cases even spending additional time on refactoring the existing use cases.

So we started to wonder if it is a worthwhile endeavor to switch to new navigation system. While estimating time for refactoring and immediate benefits I started to think why we started to consider this idea at all. What exactly drives us in making such decisions as going back to already written code and refactor it? And I decided to put some thoughts in this blog about the motivation behind the desire for better code.

I already wrote about clean architecture and design. And in this blog I will return to this topic but from a different angle. Let me first mention that in my experience clean code is very opinionated term because it is not strictly defined by rules but rather by feelings – if the given code is easy to read, perceive, extend, test and maintain it must be a clean code. And different developers this feeling can achieve by different coding approaches. Therefore there will always be disputes about the best language, framework or paradigm. And quite often different developers perceive the same code differently – the one might be convinced that the code is clean because from his perspective it is easy to understand and extend and at the same time another developer will claim that taking a different approach would lead to better code.

Therefore from my point of view it is pointless to argue only about the approaches in coding, but the languages, frameworks or paradigms should be discussed together with the measurable results these different approaches yield. And only then we can talk about the clean code.

And one such measurable indicator that we looked at, while were considering migration to the new Jetpack components, was overall development speed.

And here I want to emphasize the word overall, because initially coding in dirty way is much faster than structuring code and only after awhile the well written code starts to shine and only then the terms testable, extendable, maintainable really start to make sense for you. Actually I don’t see anything wrong in writing one big chunk of spaghetti code if all developers who work now and will work on such code in the future can understand it, test it and extend it as fast as very well structured code. But this is never the case, unless the developer is some kind of genius, and even then you need to make sure that every developer in a team is a same level genius. So that is why the abstraction levels were raised, that we don’t have to write mathematical expressions and well known business logic in machine code. That is why different paradigms were invented that we faster and easier grasp the problems we are coding. And that is why patterns and best practices are used that we can solve the problems faster and every developer can understand the solution. From the other hand the computer or the phone that runs our software doesn’t care about the code we wrote because it doesn’t use our code but the code produced by compiler or interpreter. The very bad code (from developers point of view) can be converted to the same machine code, that is produced from very well written code. Unfortunately in most cases the only people who care about the code quality are developers. No one else really care about it – stake holders, managers and users care only about the end result. As long as the application meets the requirements it is good enough to use it. But for us developers the well written code can greatly shorten development time and bring a peace in our mind.

But how come we get so much code which doesn’t follow the clean code principles? One obvious reason is lack of experience. At some point of time we developers all have written poor code, just because we didn’t now how to write it better, but along the time we learned and reached a certain level of mastery. Shouldn’t we write now only a clean code? Unfortunately no, and there are several reasons for it. The one we learned while migrating to Jetpack components is: it doesn’t matter how good the code is now there is always a room for improvement, we just don’t know yet how to do it.