$30 off During Our Annual Pro Sale. View Details »

The source of all technical debt

The source of all technical debt

Indebted code is any code that is hard to scan. Technical debt is anything that increases the difficulty of reading code. As software engineers we spend most of the time reading code, and our job is to understand it and modify it in order to do more things with it. If we can’t understand the code, or we can’t even find it, the amount of technical debt accumulated will be over the roof.

David González

March 22, 2017
Tweet

More Decks by David González

Other Decks in Programming

Transcript

  1. The source of all
    technical debt

    View Slide

  2. Indebted code is any code
    that is hard to scan.
    Technical debt is anything that
    increases the difficulty
    of reading code.

    View Slide

  3. Programmers spend around
    60-70%
    of their entire programming
    time reading code.
    Completely made up number based on my last month

    View Slide

  4. Cyclomatic complexity
    Software metric (measurement),
    used to indicate the complexity of a program.
    It is a quantitative measure of the number of
    linearly independent paths through
    a program's source code.

    View Slide

  5. Reducing technical debt
    Look at
    something
    Have an
    insight
    Write it down
    Check it in

    View Slide

  6. Reducing technical debt
    Have an
    insight

    View Slide

  7. Reducing technical debt
    Decide where
    to look
    Reading
    things,
    usually names
    In a name or
    assertion
    Name your
    commit

    View Slide

  8. 7 stages of naming

    View Slide

  9. Nonsense
    preloadDetails();

    View Slide

  10. Honest
    doSomethingEvilToTheDatabaseAndDisplayTheResult();

    View Slide

  11. Not just for functions
    public class DataManager
    public class DataProvider
    public class DataRepository
    public class DataOperations

    View Slide

  12. Honest and Complete
    parseXmlAndStoreFlightToDatabaseAndLocalCacheAndBeginBackgroundProcessing();

    View Slide

  13. View Slide

  14. Does the right thing
    storeFlightToDatabaseAndStartProcessing();

    View Slide

  15. Intent
    beginTrackingFlight();

    View Slide

  16. Domain abstraction
    MonitoringPanel.add(new Flight());

    View Slide

  17. Define your language

    View Slide

  18. De!ne your language
    presenter.loadFolders();
    presenter.getFolders();
    presenter.fetchFolders();
    view.presentFolders();
    view.showFolders();
    view.renderFolders();

    View Slide

  19. De!ne your language

    View Slide

  20. De!ne your language
    view.showFolders(boolean isOnline);
    presenter.loadFolders(boolean fromCache);

    View Slide

  21. De!ne your language
    presenter.loadFolders(boolean fromCache);
    view.showFolders();
    view.notifyOffline();

    View Slide

  22. Name by what it does, not by what it is
    @BindView(R.id.password_text_input_layout)
    TextInputLayout passwordTextInputLayout;
    @BindView(R.id.password_edit_text)
    EditText etPassword;
    @BindView(R.id.password)
    EditText passwordInput;

    View Slide

  23. Just say mNo to
    Hungarian Notation
    http://jakewharton.com/just-say-no-to-hungarian-notation/

    View Slide

  24. Say mNo to hungarian notation

    View Slide

  25. Your strict naming
    conventions are a
    liability
    https://publicobject.com/2016/01/20/strict-naming-conventions-are-a-liability/

    View Slide

  26. Rest API don’t de!ne your language
    {
    "files": {
    "Hello.txt": {
    "type": "text/plain",
    "content": "Hello World!\n"
    }
    },
    "created_at": "2014-05-27T02:31:35Z",
    "updated_at": "2015-08-29T14:01:51Z"
    }

    View Slide

  27. Rest API don’t de!ne your language
    public final class Gist {
    Map files;
    @SerializedName("created_at") Date createdAt;
    @SerializedName("updated_at") Date updatedAt;
    }

    View Slide

  28. Let’s talk about
    testing

    View Slide

  29. Naming your tests
    @Test
    public void
    testDraftDialogPresenterShowsMessageAfterClickingSaveButtonAndReloadsData()
    DraftDialogPresenter.java

    View Slide

  30. Naming your tests
    DraftDialogPresenter.java
    @Test
    public void
    testDraftDialogPresenterShowsMessageAfterClickingSaveButtonAndReloadsData()

    View Slide

  31. Naming your tests
    @Test
    public void draftDialogShowsMessageAfterClickingSaveButtonAndReloadsData()
    DraftDialogPresenter.java
    @Test
    public void
    testDraftDialogPresenterShowsMessageAfterClickingSaveButtonAndReloadsData()

    View Slide

  32. Naming your tests
    DraftDialogPresenter.java
    @Test
    public void
    testDraftDialogPresenterShowsMessageAfterClickingSaveButtonAndReloadsData()
    @Test
    public void draftDialogShowsMessageAfterClickingSaveButtonAndReloadsData()

    View Slide

  33. Naming your tests
    DraftDialogPresenter.java
    @Test
    public void showsMessageWhenDraftIsSavedAndReloadsData()
    @Test
    public void
    testDraftDialogPresenterShowsMessageAfterClickingSaveButtonAndReloadsData()
    @Test
    public void draftDialogShowsMessageAfterClickingSaveButtonAndReloadsData()

    View Slide

  34. Naming your tests
    DraftDialogPresenter.java
    @Test
    public void
    testDraftDialogPresenterShowsMessageAfterClickingSaveButtonAndReloadsData()
    @Test
    public void draftDialogShowsMessageAfterClickingSaveButtonAndReloadsData()
    @Test
    public void showsMessageWhenDraftIsSavedAndReloadsData()

    View Slide

  35. Naming your tests
    DraftDialogPresenter.java
    @Test
    public void showsMessageWhenDraftIsSaved()
    @Test
    public void
    testDraftDialogPresenterShowsMessageAfterClickingSaveButtonAndReloadsData()
    @Test
    public void draftDialogShowsMessageAfterClickingSaveButtonAndReloadsData()
    @Test
    public void showsMessageWhenDraftIsSavedAndReloadsData()

    View Slide

  36. Naming your tests
    DraftDialogPresenter.java
    @Test
    public void
    testDraftDialogPresenterShowsMessageAfterClickingSaveButtonAndReloadsData()
    @Test
    public void draftDialogShowsMessageAfterClickingSaveButtonAndReloadsData()
    @Test
    public void showsMessageWhenDraftIsSavedAndReloadsData()
    @Test
    public void showsMessageWhenDraftIsSaved()

    View Slide

  37. Naming your tests
    DraftDialogPresenter.java
    @Test
    public void showsSuccessMessageWhenDraftIsSaved()
    @Test
    public void
    testDraftDialogPresenterShowsMessageAfterClickingSaveButtonAndReloadsData()
    @Test
    public void draftDialogShowsMessageAfterClickingSaveButtonAndReloadsData()
    @Test
    public void showsMessageWhenDraftIsSavedAndReloadsData()
    @Test
    public void showsMessageWhenDraftIsSaved()

    View Slide

  38. Naming your tests
    DraftDialogPresenter.java
    @Test
    public void
    testDraftDialogPresenterShowsMessageAfterClickingSaveButtonAndReloadsData()
    @Test
    public void draftDialogShowsMessageAfterClickingSaveButtonAndReloadsData()
    @Test
    public void showsMessageWhenDraftIsSavedAndReloadsData()
    @Test
    public void showsMessageWhenDraftIsSaved()
    @Test
    public void showsSuccessMessageWhenDraftIsSaved()

    View Slide

  39. Naming your tests
    DraftDialogPresenter.java
    @Test
    public void showsErrorMessageWhenDraftIsNotSaved()
    @Test
    public void
    testDraftDialogPresenterShowsMessageAfterClickingSaveButtonAndReloadsData()
    @Test
    public void draftDialogShowsMessageAfterClickingSaveButtonAndReloadsData()
    @Test
    public void showsMessageWhenDraftIsSavedAndReloadsData()
    @Test
    public void showsMessageWhenDraftIsSaved()
    @Test
    public void showsSuccessMessageWhenDraftIsSaved()

    View Slide

  40. Naming your tests
    DraftDialogPresenter.java
    @Test
    public void
    testDraftDialogPresenterShowsMessageAfterClickingSaveButtonAndReloadsData()
    @Test
    public void draftDialogShowsMessageAfterClickingSaveButtonAndReloadsData()
    @Test
    public void showsMessageWhenDraftIsSavedAndReloadsData()
    @Test
    public void showsMessageWhenDraftIsSaved()
    @Test
    public void showsSuccessMessageWhenDraftIsSaved()
    @Test
    public void showsErrorMessageWhenDraftIsNotSaved()

    View Slide

  41. Naming your tests
    DraftDialogPresenter.java
    @Test
    public void shows_error_mesage_when_draft_is_not_saved()
    @Test
    public void
    testDraftDialogPresenterShowsMessageAfterClickingSaveButtonAndReloadsData()
    @Test
    public void draftDialogShowsMessageAfterClickingSaveButtonAndReloadsData()
    @Test
    public void showsMessageWhenDraftIsSavedAndReloadsData()
    @Test
    public void showsMessageWhenDraftIsSaved()
    @Test
    public void showsSuccessMessageWhenDraftIsSaved()
    @Test
    public void showsErrorMessageWhenDraftIsNotSaved()

    View Slide

  42. Naming your tests
    DraftDialogPresenter.java
    @Test
    public void
    testDraftDialogPresenterShowsMessageAfterClickingSaveButtonAndReloadsData()
    @Test
    public void draftDialogShowsMessageAfterClickingSaveButtonAndReloadsData()
    @Test
    public void showsMessageWhenDraftIsSavedAndReloadsData()
    @Test
    public void showsMessageWhenDraftIsSaved()
    @Test
    public void showsSuccessMessageWhenDraftIsSaved()
    @Test
    public void showsErrorMessageWhenDraftIsNotSaved()
    @Test
    public void shows_error_mesage_when_draft_is_not_saved()

    View Slide

  43. Naming your tests
    DraftDialogPresenter.java
    // Groovy
    def "Should show success message after successfully saved a draft"()
    // Kotlin
    fun `Should show success message after successfully saved a draft`()

    View Slide

  44. Naming your tests
    @Test
    public void showsErrorMessageWhenDraftIsNotSaved()
    {}
    @Test
    public void
    shows_error_mesage_when_draft_is_not_saved() {}
    // Groovy
    def "Should show success message after
    successfully saved a draft"()
    // Kotlin
    fun `Should show success message after
    successfully saved a draft`()

    View Slide

  45. Android package
    structure

    View Slide

  46. View Slide

  47. helpscout
    api
    app
    database

    View Slide

  48. app
    common
    data
    domain
    injection

    View Slide

  49. domain
    conversations
    folders
    mailboxes
    session
    search
    settings

    View Slide

  50. mailboxes
    model
    usecases
    view
    MailboxesMVP
    MailboxesPresenter

    View Slide

  51. Android resource
    management

    View Slide

  52. Styles

    View Slide

  53. Styles
    android:id="@+id/conversations_list_subject_name"
    style="@style/Widget.Subject.Pending"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    tools:text="Customer Name" />
    view-convo-preview.xml

    View Slide

  54. Styles
    <br/><item name="android:textSize">@dimen/convo_subject_text</item><br/><item name="android:ellipsize">end</item><br/><item name="android:maxLines">1</item><br/>
    <br/><item name="android:textColor">@color/convo_preview_pending</item><br/>
    convo-preview-styles.xml

    View Slide

  55. Colors
    <br/><item name="android:textColor">@color/convo_preview_pending</item><br/>
    convo-preview-styles.xml
    @color/charcoal_300
    convo-preview-colors.xml
    #72808e
    colors.xml

    View Slide

  56. Dimensions
    <br/><item name="android:textSize">@dimen/convo_preview_text</item><br/><item name="android:ellipsize">end</item><br/><item name="android:maxLines">1</item><br/> convo-preview-styles.xml
    @dimen/text_subhead
    convo-preview-dimens.xml
    11sp
    dimens.xml

    View Slide

  57. Strings


    @string/convo_archived
    @string/convo_restored

    convo-preview-strings.xml
    Conversation archived.
    Conversation status restored.
    strings-translatable.xml

    View Slide

  58. View Slide

  59. Files

    View Slide

  60. We are talking about
    conventions
    and we should share them with the team

    View Slide

  61. https://google.github.io/styleguide/javaguide.html#s5.1-identifier-names

    View Slide

  62. http://s.android.com/source/code-style.html#follow-field-naming-conventions

    View Slide

  63. View Slide

  64. View Slide

  65. Enforce those
    conventions

    View Slide

  66. Enforce conventions

    View Slide

  67. Enforce conventions

    ...

    ...





    ...

    View Slide

  68. Enforce conventions







    value="Variable ''{0}'' should be in ALL_CAPS (if it is a constant) or be private
    (otherwise)." />


    team-props/checkstyle/modules.xml





    View Slide

  69. Enforce conventions












    team-props/pmd/ruleset.xml

    View Slide

  70. Enforce conventions
    static-analysis.gradle
    apply plugin: 'checkstyle'
    def rulesDir = new File(project.teamPropsDir, 'rules')
    task checkstyleMain(type: Checkstyle) {
    description 'Checks whether Java source code complies with coding rules.'
    ...
    }
    staticAnalysis.dependsOn checkstyleMain
    task verifyNoCheckstyleWarnings {
    doLast {
    File warningsFile = file('buildMessage/reports/checkstyle/main.xml')
    if (warningsFile.exists() && warningsFile.text.contains("throw new GradleException("There were checkstyle warnings!
    For more info check $warningsFile")
    }
    }
    }

    View Slide

  71. Enforce conventions
    static-analysis.gradle
    apply plugin: 'findbugs'
    task findbugsMain(type: FindBugs) {
    description 'Uses static analysis to look for bugs in Java code.'
    ...
    }
    staticAnalysis.dependsOn findbugsMain
    apply plugin: 'pmd'
    task pmdMain(type: Pmd) {
    description 'Finds common programming flaws throw static analysis of code.'
    }
    staticAnalysis.dependsOn pmdMain
    check.dependsOn staticAnalysis

    View Slide

  72. Static analysis

    View Slide

  73. Good naming is a process, not a single step
    - http://arlobelshee.com/good-naming-is-a-process-not-a-single-step/
    1
    Resources
    Just say hNo to hungarian notation
    - http://jakewharton.com/just-say-no-to-hungarian-notation/
    How We Rethought our Complete Package Structure for Buffer on Android and
    the Awesome Effect It’s Had on Our Workflows
    - https://overflow.buffer.com/2016/09/26/android-rethinking-package-structure/
    Share the settings with the whole team
    - https://tips.seebrock3r.me/share-settings-with-the-team-a-year-later-
    e28c24fc07aa#.sihndb3f3

    View Slide

  74. Novoda IDE Settings
    - https://github.com/novoda/novoda/tree/master/ide-settings
    1
    Resources
    Buffer’s Android Guidelines
    - https://github.com/bufferapp/android-guidelines
    Vincent Brison’s Static Analysis with Gradle
    - https://github.com/vincentbrison/vb-android-app-quality

    View Slide

  75. Questions?
    David González
    @dggonzalez
    [email protected]

    View Slide