Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Code readability: Session 2 (ver. 2, En)

Code readability: Session 2 (ver. 2, En)

Munetoshi Ishikawa

May 11, 2023
Tweet

More Decks by Munetoshi Ishikawa

Other Decks in Programming

Transcript

  1. Brushup: Introduction and Principles Readability is for sustainable development The

    boy scout rule: Make code readable before changing it YAGNI: Implement only when required KISS: Choose a simple solution, beautiful != readable Single responsibility principle: Clarity the scope Premature optimization: Profile/estimate before optimization
  2. Contents of this lecture - Introduction and Principles - Natural

    language: Naming, Comments - Inner type structure: State, Function - Inter type structure: Dependency I, Dependency II - Follow-up: Review Naming > Introduction
  3. What we name - Class, interface, enum, struct, protocol, trait

    - Variable, property, field, parameter, constant value - Function, method, procedure, subroutine - Scope, package, module, namespace - Resource, file, directory, ID - etc. Naming > Introduction
  4. What constitutes a good name Accurate - isVisible should not

    be used for sound Descriptive - width/height rather than w/h - imageView/imageBitmap/imageUrl rather than image Naming > Introduction
  5. How to create a good name - Use correct grammar

    - Describe what rather than who/when - Choose words with narrow meanings - Avoid confusing abbreviations - Add words to explain type/unit - Use positive affirmation Naming > Introduction
  6. Topics - Use correct grammar - Describe what rather than

    who/when - Choose words with narrow meanings - Avoid confusing abbreviations - Add words to explain type/unit - Use positive affirmation Naming > Use correct grammar
  7. Why grammar is important Question 1: What is CallbackEventMessageClickViewText ?

    Answer 1?: A text of a click view (?) of a callback event message?? Question 2: What is MessageTextViewClickEventCallback ? Answer 2: A callback of click events on a message text view Naming > Use correct grammar
  8. Use correct grammar "Grammar" depends on language and convention Let

    us look at the case of Java/Kotlin Naming > Use correct grammar
  9. Types of names 1/2 - Noun: class, variable (including property

    function) imageView, HashSet, indexOf - Imperative: function findMessage, compareTo Naming > Use correct grammar
  10. Types of names 2/2 - Adjective, participle: interface, state type/constant

    Iterable , PLAYING , CONNECTED - Interrogative, third-person verb: boolean value/function isTextVisible , contains , equalsTo , may / shouldShow - Adverb phrase with preposition: converter, callback toInt , fromMemberId , onClickEvent Naming > Use correct grammar
  11. Grammar: Noun Place the essential word at the end (=

    the word telling what it is/does) ! : MessageEventHandler , buttonHeight ! : xyzHeightForPortrait (do not use for a class name) ! : HandlerMessageEvent (if it is a handler), heightPortrait Exception: Property function with a preposition e.g., indexOf(value) , maxValueIn(array) Naming > Use correct grammar
  12. Grammar: Imperative Place a verb at first "get X": !

    getX, " xGet "post Y": ! postY, " yPost "map to Z": ! mapToZ, " toZMap, zToMap Naming > Use correct grammar
  13. How a name in a wrong order is created class

    UserActionEvent class UserActionEventSwipe: UserActionEvent() class UserActionEventClickMessageText: UserActionEvent() class UserActionEventClickProfileImage: UserActionEvent() mutableListOf<UserActionEventClickProfileImage>() How the code looks on the caller side is important Do not focus only on superficial consistency Naming > Use correct grammar
  14. Grammar: Summary Types for a name Noun, imperative, adjective, interrogative

    (+ third person), adverb Word order is important Check how the name looks on the caller side Naming > Use correct grammar
  15. Topics - Use correct grammar - Describe what rather than

    who/when - Choose words with narrow meanings - Avoid confusing abbreviations - Add words to explain type/unit - Use positive affirmation Naming > Describe what rather than who/when
  16. Describe "what" rather than "who/when" A name must answer !

    What a class/variable is ! What a function does A name should not mention to the caller ! Who it calls/uses ! When/Where/Why/How it's called/used Naming > Describe what rather than who/when
  17. Function name example: Declaration side ! Describe what this function

    does class MessageRepository { fun storeReceivedMessage(data: MessageData) { ! Describe when this function should be called class MessageRepository { fun onMessageReceived(data: MessageData) { Naming > Describe what rather than who/when
  18. Function name example: Caller side ! We can know what

    happens by the calling code repository.storeReceivedMessage(messageData) presenter.showNewReceivedMessage(messageData) ! We are unable to know what happens repository.onMessageReceived(messageData) presenter.onMessageReceived(messageData) Naming > Describe what rather than who/when
  19. Function name example: Another bad reason The function responsibility is

    ambiguous class MessageViewPresenter { fun onMessageReceived(data: MessageData) { // View presentation code for new message ... repository.onMessageReceived(data) // !! May cause a duplicate call bug repository.onMessageReceived(messageData) presenter.onMessageReceived(messageData) Naming > Describe what rather than who/when
  20. Parameter name example: Declaration side ! We can know what

    happens if it is true fun showHistory(shouldShowDialogOnError: Boolean) ! We cannot know what happens if it is true fun showHistory(isCalledAtMainScreen: Boolean) Naming > Describe what rather than who/when
  21. Parameter name example: Drawbacks of "who" 1: The name easily

    becomes obsolete // ... from another screen requiring dialog showHistory(isCalledAtMainScreen = true) 2: The parameter will be used for other purposes if (isCalledAtMainScreen) { setScreenTitle("Main") ... Would causes a bug if 1 and 2 happen at the same time Naming > Describe what rather than who/when
  22. Describe what: Exception May need to name by "how/when" for

    an abstract callback - e.g., onClicked, onSwiped, onDestroyedɹ - Because "what" is not decided on the declaration We should name by "what" if possible even for a callback abstract fun toggleSelectionState() ... view.setClickCallback { toggleSelectionState() } Naming > Describe what rather than who/when
  23. Describe what: Summary Describe "what" it is/does = Should not

    mention to the caller (who/when/where/why/how) - Show code responsibility clearly - Make caller code readable Exception: Interface with no definition of "what" it does Naming > Describe what rather than who/when
  24. Topics - Use correct grammar - Describe what rather than

    who/when - Choose words with narrow meanings - Avoid confusing abbreviations - Add words to explain type/unit - Use positive affirmation Naming > Choose words with narrow meanings
  25. Ambiguous words: Example 1/2 Question: What does initializationFlag represent? -

    shouldInitialize - isInitializing - is/wasInitialized - isInitializable - isNotInitialized (!!) Choose one from the above options (except for the last one) Naming > Choose words with narrow meanings
  26. Ambiguous words: Example 2/2 Question: What does sizeLimit represent? -

    max, min? - height, width, byte, characters, length? Name maxHeight , for example. Naming > Choose words with narrow meanings
  27. Rewording options to consider - flag: is, was, should, can,

    may, will ... - check: is, query, verify, measure, filter, notify, update ... - good, fine: valid, completed, reliable, secure, satisfactory ... - old: previous, stored, expired, invalidated, deprecated ... - tmp, retval: actual name Use a dictionary or a thesaurus Naming > Choose words with narrow meanings
  28. Choose words with narrow meanings: Summary - Replace ambiguous words

    like flag or check - Use a dictionary or a thesaurus Naming > Choose words with narrow meanings
  29. Topics - Use correct grammar - Describe what rather than

    who/when - Choose words with narrow meanings - Avoid confusing abbreviations - Add words to explain type/unit - Use positive affirmation Naming > Avoid confusing abbreviations
  30. Abbreviations: Example 1/2 Question: What does im stand for? input

    method, illegal message, instance manager ... Do not create your own abbreviations - Recognizing is easier than recalling3 3 100 Things: Every Designer Needs to Know About People, Susan Weinschenk, 2011 Naming > Avoid confusing abbreviations
  31. Abbreviations: Example 2/2 Question: What does str stand for? string,

    structure, stream, streak, street, sorted transaction record Abbreviations may be acceptable if commonly used - Abbreviations like URL and TCP are totally fine - str for string is acceptable especially for a limited scope Naming > Avoid confusing abbreviations
  32. Product-specific abbreviation Some abbreviations are used product-wide Make them readable

    for a new team member - Write documentation for class, variable, or function - Prepare glossary Naming > Avoid confusing abbreviations
  33. Avoid confusing abbreviations: Summary - Your own abbreviations: Do not

    use them - Commonly used abbreviations: Acceptable for several cases - Product-specific abbreviations: Prepare document or glossary Naming > Avoid confusing abbreviations
  34. Topics - Use correct grammar - Describe what rather than

    who/when - Choose words with narrow meanings - Avoid confusing abbreviations - Add words to explain type/unit - Use positive affirmation Naming > Add words to explain type/unit
  35. Add words to explain type/unit Units and entities can be

    ambiguous in an integer type - timeout: timeoutInMillis, timeoutInSeconds - width: widthInPixels, widthInPoints, widthInInches - color: argbColorInt, colorResId - i, j, k: userIndex, row, col Naming > Add words to explain type/unit
  36. Add words to explain type/unit: Aside Consider creating a wrapper

    class of a unit class Inch(val value: Int) class Centimeter(val value: Int) fun setWidth(width: Inch) = ... setWidth(Centimeter(10)) // Compile error! - "value class" (Scala) or "inline class" (Kotlin) may help you - Consider encapsulating units in a class (e.g., Kotlin's Duration) Naming > Add words to explain type/unit
  37. Topics - Use correct grammar - Describe what rather than

    who/when - Choose words with narrow meanings - Avoid confusing abbreviations - Add words to explain type/unit - Use positive affirmation Naming > Use positive affirmation
  38. Use positive affirmation ! : Positive words, isEnabled ! :

    Negative words, isDisabled ! : Positive word with "not," "no," or "non," isNotEnabled ! : Negative word with "not," "no," or "non," isNotDisabled We can rename isNotDisabled → isEnabled, and isNotEnabled → isDisabled without any logic change Naming > Use positive affirmation
  39. Topics - Use correct grammar - Describe what rather than

    who/when - Choose words with narrow meanings - Avoid confusing abbreviations - Add words to explain type/unit - Use positive affirmation Naming > Adhere to language/platform/product conventions
  40. Language/platform/product conventions Adhere to convention/rule/manner of language/platform/project - Grammar: itemCount

    vs. numItem - Abbreviations: milliSeconds vs. millis vs. ms Refer to the standard libraries and APIs Create coding conventions of the product for ambiguous points Naming > Adhere to language/platform/product conventions
  41. Summary Use accurate and descriptive names - What to describe:

    "what" rather than "who/when" - Grammar: word order - Word selection: narrow meaning, non-abbreviated, affirmative Naming > Summary