David Cordero

iOS and tvOS developer at @Zattoo. Amateur Triathlete. Passionate about coding and lifelong learning.

Danshari Oriented Development

15 Aug 2016 » iOS, SoftwareDevelopment, CleanCode

Despite of that title I am not going to speak here about any new paradigm, or about any new programming pattern, but about an attitude, and about how we applied that attitude to improve our iOS App in Zattoo.

If you don’t know the concept of Danshari, it is a Japanese made up word consisting of three kanji, meaning in sequence: refusal, disposal and separation.

image

I discovered this concept a couple of years ago, when traveling around Japan. I really felt in love with the concept of Danshari, and I try to follow it as much as I can in my daily life.

Danshari in a nutshell could be defined as the idea of avoiding any emotional connection with objects, about detachment from possesions and getting rid of clutter in your life. Objects can be seen as tools which can be helpful, during a period of time in your life and then be thrown away.

Once they are not longer needed, it is over. You don’t have to keep those tools any more, consuming a huge amount of your space, reducing your freedom of movement or in some cases, if you have expensive possessions, increasing the fear to be stolen.

As you can imagine, It is indeed really hard to apply the concept of Danshari living in a capitalist world, where everybody wants to have the biggest car, the biggest house and the latests devices on the market. Which is not bad of course if those object are really needed and they solve problem in your life.

Danshari as a Developer

As I said, I try to follow the principles of Danshari as much as I can, and it also means that I try to apply this concept to the part of my life that I spend working as a Software Developer.

And what exactly does it mean to apply Danshari as a developer?

Easy, just remove any unneeded component from your project, be austere in your code and resources.

Code and resources are tools to solve problems. And, due to the evolution of the projects, some of these tools can eventually be turned redundant.

You must be wondering now, what do I mean, and what you could actually remove from your project. After all, everything was added for a reason, wasn’t it?

To make it clearer I will provide a list of examples based on my personal experiences, but please consider it as a reference and don’t be shy, I am sure that once you start, you will find more and more situations to apply Danshari in your code.

  • Commented code in the middle of no where, pieces of code kept for no reason, probably as result of some refactor, that no one dares to remove just because who knows if someday this code could be useful…

  • Unused classes and methods not longer needed, App Code is a great IDE to discover all these redundant elements in your App.

  • Redundant imports that are actually never used. App Code can also help here.

  • Unused dependencies added to the Podfile that are not longer used by the App.

  • Default implementations, usually with commented code inside. They were added for a reason, but they were never removed from the project once its behaviour turned back to the default one.

override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    return 1 // 4
}
 override func viewDidLoad() {
    super.viewDidLoad
     
    // debugLog(">>> DidLoad")
}
- (id)init {
  self = [super init];
  if (self) {
    // [self setUp]
  }
}
  • Predefined templates, doing absolutely nothing. Does the following code look familiar to you?
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?


    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        // Override point for customization after application launch.
        return true
    }

    func applicationWillResignActive(application: UIApplication) {
        // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
        // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
    }

    func applicationDidEnterBackground(application: UIApplication) {
        // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
        // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
    }

    func applicationWillEnterForeground(application: UIApplication) {
        // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
    }

    func applicationDidBecomeActive(application: UIApplication) {
        // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
    }

    func applicationWillTerminate(application: UIApplication) {
        // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
    }
}
  • Unused strings, no longer used strings should also be removed from the Localizable.strings

  • Unused images, same as before, are all the xcassets being used by the last version of the App?

  • Definition with inferable datatypes or default modifiers

internal let property: String = Danshari Danshari !!!

// vs 

let property = Danshari Danshari !!!
@property (nonatomic, strong, readwrite) NSString *property;

// vs

@property (nonatomic) NSString *property;
  • Not longer needed scripts that were probably useful in the past to do certain tasks, tasks that nobody does anymore.

  • Huge license headers, added to every single file of the project. Headers which apart from feeding the ego don’t add any value at all. In some cases you can even find files with fewer code than license.

//
//  File.m
//  MySuperSecretProject
//
//  Created by David Hasselhof on 09/08/16.
//  Copyright © 2016 MySuperCompany. All rights reserved.
//
// *******************************************************
// * Copyright (C) 2010-2011 MySuperCompany info@mysupercompany.com
// *
// * This file is part of MySuperSecretProject.
// *
// * MySuperSecretProject can not be copied and/or distributed without the express
// * permission of MySuperCompany
//
// * NOTICE:  All information contained herein is, and remains
// * the property of MySuperCompany and its suppliers,
// * if any.  The intellectual and technical concepts contained
// * herein are proprietary to MySuperCompany
// * and its suppliers and may be covered by U.S. and Foreign Patents,
// * patents in process, and are protected by trade secret or copyright law.
// * Dissemination of this information or reproduction of this material
// * is strictly forbidden unless prior written permission is obtained
// * from MySuperCompany
// *******************************************************

func debugLog(@autoclosure message: () -> String) {
    #if DEBUG
    print(message())
    #endif
}

Disclaimer: Because of legal issues these headers are actually needed in certain cases, like when working on frameworks exposing public APIs.

  • Redundant and wrong comments adding obvious or even wrong information to the code
    // Fuction that shows the menu
    // params: None
    // returns: None
    func showMenu() {
        
        // Check first if the menu is already visible
        if !menu.hidden {
            // Check if we really have to show the menu
            if shouldMenuBeShown() {
                
                // Show the menu
                menu.hidden = false
            }
        }
    }
    
    func numberOfElements() {
        // Always return 4
        return 3
    }
  • Old code that is not longer needed because of the evolution of the language. Synthesize properties, predefinition of private methods, etc…

  • Conditional code for not longer supported devices. Like the following code that nobody removed once the deployment target was bumped to iOS8 (which indirectly means that only iPhone 4 or higher is supported)

func setupView() {
   if Device.iPhone4OrHigher {
      setupRetinaView()
   }
   else {
      setupLowResView()
   }
}

As I said this is just a list of a few examples based on my personal experiences, but I am sure you will have the chance to apply Danshari in more situations.

Remember that in case of doubt, if you find unused resources or unused code that you don’t know wether could be useful in the future…delete it, aren’t you using Git? Everything will be there if it is really needed in the future. If you don’t use Git or a equivalent, using it should be your first step before removing anything.

But wait… don’t be too brave either. I am not speaking at all about Refactoring in this post. I am speaking about deleting unused code and resources from your App, but I didn’t say anything about improving the implementation and its behaviour. In this case, you should be more cautious and to follow a different way of working.

And in case of doubt about if something is being used, keep it and consider it as a refactor. Take care as well of inheritance when removing code, because removing code, apparently unneeded, could have some impact due to inheritance.

Daily Danshari

Same as in real life, Danshari doesn’t mean that one day you wake up and you sell everything that you don’t need. It is actually a daily attitude, it is an attitude to avoid increasing and increasing your redundant possessions.

Danshari as a developer doesn’t mean either that one day you delete every redundant component from your App, but also having a daily attitude to avoid increasing the number of redundant components.

This is why applying Danshari as a developer doesn’t finish once you delete all this redundant code and resources, it never finishes. You should always keep it as a daily attitude, paying attention to pull requests making redundant some any of your components.

As an example of what exactly does it mean to apply Danshari to a real project, please take a look to these stats of the iOS App of Zattoo in which I have being working for a few months already…

image

image

As you can see, we reduced the number of lines of code in more than 50%, getting back the levels of 2011. It is also true that we are also doing a quite important refactor in parallel that also helped to reduce the code significantly, but the main reduction was without question coming from applying a bit of Danshari to the project.

I would like to send thanks here to my colleague Mr Chris Goldsby who did a great job in this housekeeping period.

As conclusion, either if you apply Danshari to your project or not, I am sure that you will remember this word the next time you have to move to a new apartment :D

Happy Dansharing !!!