# Code Health

Published articles for Code Health.

This is one page of public article previews, not the complete archive. Follow Next page to continue. Summaries are not the original full articles.

## Arrange Your Code to Communicate Data Flow

DevFeed: [Arrange Your Code to Communicate Data Flow](<https://devfeed.tech/articles/arrange-your-code-to-communicate-data-flow-23863.md>)

Original publisher: [Read original article](<http://testing.googleblog.com/2025/01/arrange-your-code-to-communicate-data.html>)

Author: Google Testing Bloggers (noreply@blogger.com)

Published: 2025-01-07T13:59:00Z

Content type: tutorial

Language: en

Sources: [Google Testing Blog](<https://devfeed.tech/sources/google-testing-blog.md>)

Topics: [Code](<https://devfeed.tech/topics/code.md>)

Tags: [article](<https://devfeed.tech/tags/article.md>), [code](<https://devfeed.tech/tags/code.md>), [code-health](<https://devfeed.tech/tags/code-health.md>), [cognitive-load](<https://devfeed.tech/tags/cognitive-load.md>), [readability](<https://devfeed.tech/tags/readability.md>), [sebastian-dorner](<https://devfeed.tech/tags/sebastian-dorner.md>), [tott](<https://devfeed.tech/tags/tott.md>)

### AI overview

The article explains how arranging adjacent lines of code to follow data flow can improve readability and reduce cognitive load. It uses sandwich-making examples to show grouping related operations, adding blank lines between code blocks, and handling values reused for logging.

### Source excerpt

This article was adapted from a Google Tech on the Toilet (TotT) episode. You can download a printer-friendly version of this TotT episode and post it in your office. By Sebastian Dörner We often read code linearly, from one line to the next. To make code easier to understand and to reduce cognitive load for your readers, make sure that adjacent lines of code are coherent. One way to achieve this is to order your lines of code to match the data flow inside your method: fun getSandwich( bread: Bread, pasture: Pasture ): Sandwich { // This alternates between milk- // bread-related code. val cow = pasture.getCow() val slicedBread = bread.slice() val milk = cow.getMilk() val toast = toastBread(slicedBread) val cheese = makeCheese(milk) return Sandwich(cheese, toast) } fun getSandwich( bread: Bread, pasture: Pasture ): Sandwich { // Linear flow from cow to milk // to cheese. val cow = pasture.getCow() val milk = cow.getMilk() val cheese = makeCheese(milk) // Linear flow from bread to slicedBread // to toast. val slicedBread = bread.slice() val toast = toastBread(slicedBread) return Sandwich(cheese, toast) } To visually emphasize the grouping of related lines, you can add a blank line between each code block. Often you can further improve readability by extracting a method, e.g., by extracting the first 3 lines of the function on the above right into a getCheese method. However, in some scenarios, extracting a method isn't possible or helpful, e.g., if data is used a second time for logging. If you order the lines to match the data flow, you can still increase code clarity: fun getSandwich(bread: Bread, pasture: Pasture): Sandwich { // Both milk and cheese are used below, so this can't easily be extracted into // a method. val cow = pasture.getCow() val milk = cow.getMilk() reportFatContentToStreamz(cow.age, milk) val cheese = makeCheese(milk) val slicedBread = bread.slice() val toast = toastBread(slicedBread) logWarningIfAnyExpired(bread, toast, milk, cheese) return Sand

## Write Change-Resilient Code With Domain Objects

DevFeed: [Write Change-Resilient Code With Domain Objects](<https://devfeed.tech/articles/write-change-resilient-code-with-domain-objects-23860.md>)

Original publisher: [Read original article](<http://testing.googleblog.com/2024/09/write-change-resilient-code-with-domain.html>)

Author: Google Testing Bloggers (noreply@blogger.com)

Published: 2024-09-04T12:56:00Z

Content type: tutorial

Language: en

Sources: [Google Testing Blog](<https://devfeed.tech/sources/google-testing-blog.md>)

Topics: [Code](<https://devfeed.tech/topics/code.md>), [implementation](<https://devfeed.tech/topics/implementation.md>), [maintenance](<https://devfeed.tech/topics/maintenance.md>), [interfaces](<https://devfeed.tech/topics/interfaces.md>)

Tags: [amy-fu](<https://devfeed.tech/tags/amy-fu.md>), [code](<https://devfeed.tech/tags/code.md>), [code-health](<https://devfeed.tech/tags/code-health.md>), [implementation](<https://devfeed.tech/tags/implementation.md>), [interfaces](<https://devfeed.tech/tags/interfaces.md>), [maintenance](<https://devfeed.tech/tags/maintenance.md>), [tott](<https://devfeed.tech/tags/tott.md>), [writing-code](<https://devfeed.tech/tags/writing-code.md>)

### AI overview

This Google Code Health article explains how domain objects--classes and interfaces that model a product's fundamental ideas--can make code more resilient to changing requirements. A gPizza example shows how modeling shared concepts can reduce the maintenance burden caused by adding requirement-specific methods.

### Source excerpt

This is another post in our Code Health series. A version of this post originally appeared in Google bathrooms worldwide as a Google Testing on the Toilet episode. You can download a printer-friendly version to display in your office. By Amy Fu Although a product's requirements can change often, its fundamental ideas usually change slowly. This leads to an interesting insight: if we write code that matches the fundamental ideas of the product, it will be more likely to survive future product changes. Domain objects are building blocks (such as classes and interfaces) in our code that match the fundamental ideas of the product. Instead of writing code to match the desired behavior for the product's requirements ("configure text to be white"), we match the underlying idea ("text color settings"). For example, imagine you're part of the gPizza team, which sells tasty, fresh pizzas to feed hungry Googlers. Due to popular demand, your team has decided to add a delivery service. Without domain objects, the quickest path to pizza delivery is to simply create a deliverPizza method: public class DeliveryService { public void deliverPizza(List<Pizza> pizzas) { ... } } Although this works well at first, what happens if gPizza expands its offerings to other foods? You could add a new method: public void deliverWithDrinks(List<Pizza> pizzas, List<Drink> drinks) { ... } But as your list of requirements grows (snacks, sweets, etc.), you'll be stuck adding more and more methods. How can you change your initial implementation to avoid this continued maintenance burden? You could add a domain object that models the product's ideas, instead of its requirements: A use case is a specific behavior that helps the product satisfy its business requirements. (In this case, "Deliver pizzas so we make more money".) A domain object represents a common idea that is shared by several similar use cases. To identify the appropriate domain object, ask yourself: What related use cases does the produc

## Less Is More: Principles for Simple Comments

DevFeed: [Less Is More: Principles for Simple Comments](<https://devfeed.tech/articles/less-is-more-principles-for-simple-comments-23859.md>)

Original publisher: [Read original article](<http://testing.googleblog.com/2024/08/less-is-more-principles-for-simple.html>)

Author: Google Testing Bloggers (noreply@blogger.com)

Published: 2024-08-21T12:38:00Z

Content type: article

Language: en

Sources: [Google Testing Blog](<https://devfeed.tech/sources/google-testing-blog.md>)

Topics: [Code](<https://devfeed.tech/topics/code.md>), [Documentation](<https://devfeed.tech/topics/documentation.md>), [Testing](<https://devfeed.tech/topics/testing.md>)

Tags: [code](<https://devfeed.tech/tags/code.md>), [code-comments](<https://devfeed.tech/tags/code-comments.md>), [code-health](<https://devfeed.tech/tags/code-health.md>), [cognitive-load](<https://devfeed.tech/tags/cognitive-load.md>), [david-bendory](<https://devfeed.tech/tags/david-bendory.md>), [improvements](<https://devfeed.tech/tags/improvements.md>), [reduce](<https://devfeed.tech/tags/reduce.md>), [tott](<https://devfeed.tech/tags/tott.md>), [writing](<https://devfeed.tech/tags/writing.md>)

### AI overview

This article presents principles for writing simple, maintainable code comments. It recommends reviewing comments separately from code, making them self-contained, including only essential information, and using links to bugs or documentation for follow-up context.

### Source excerpt

This is another post in our Code Health series. A version of this post originally appeared in Google bathrooms worldwide as a Google Testing on the Toilet episode. You can download a printer-friendly version to display in your office. By David Bendory Simplicity is the ultimate sophistication. -- Leonardo da Vinci You're staring at a wall of code resembling a Gordian knot of Klingon. What's making it worse? A sea of code comments so long that you'd need a bathroom break just to read them all! Let's fix that. Adopt the mindset of someone unfamiliar with the project to ensure simplicity. One approach is to separate the process of writing your comments from reviewing them; proofreading your comments without code context in mind helps ensure they are clear and concise for future readers. Use self-contained comments to clearly convey intent without relying on the surrounding code for context. If you need to read the code to understand the comment, you've got it backwards! Not self-contained; requires reading the code Suggested alternative // Respond to flashing lights in // rearview mirror. // Pull over for police and/or yield to // emergency vehicles. while flashing_lights_in_rearview_mirror() { if !move_to_slower_lane() { stop_on_shoulder(); } } Include only essential information in the comments and leverage external references to reduce cognitive load on the reader. For comments suggesting improvements, links to relevant bugs or docs keep comments concise while providing a path for follow-up. Note that linked docs may be inaccessible, so use judgment in deciding how much context to include directly in the comments. Too much potential improvement in the comment Suggested alternative // The local bus offers good average- // case performance. Consider using // the subway which may be faster // depending on factors like time of // day, weather, etc. // TODO: Consider various factors to // present the best transit option. // See issuetracker.fake/bus-vs-subway commute_by_lo

## In Praise of Small Pull Requests

DevFeed: [In Praise of Small Pull Requests](<https://devfeed.tech/articles/in-praise-of-small-pull-requests-23858.md>)

Original publisher: [Read original article](<http://testing.googleblog.com/2024/07/in-praise-of-small-pull-requests.html>)

Author: Google Testing Bloggers (noreply@blogger.com)

Published: 2024-07-16T13:00:00Z

Content type: article

Language: en

Sources: [Google Testing Blog](<https://devfeed.tech/sources/google-testing-blog.md>)

Topics: [pull-requests](<https://devfeed.tech/topics/pull-requests.md>), [Code review](<https://devfeed.tech/topics/code-review.md>), [engineering-culture](<https://devfeed.tech/topics/engineering-culture.md>)

Tags: [code-health](<https://devfeed.tech/tags/code-health.md>), [code-review](<https://devfeed.tech/tags/code-review.md>), [elliotte-rusty-harold](<https://devfeed.tech/tags/elliotte-rusty-harold.md>), [merge](<https://devfeed.tech/tags/merge.md>), [pull-requests](<https://devfeed.tech/tags/pull-requests.md>), [review](<https://devfeed.tech/tags/review.md>), [tott](<https://devfeed.tech/tags/tott.md>), [version-control](<https://devfeed.tech/tags/version-control.md>)

### AI overview

This Google Testing on the Toilet Code Health post explains why pull requests should be small and focused on one self-contained change. It says smaller pull requests are easier and faster to review, make mistakes easier to detect, simplify debugging and rollback, reduce merge conflicts, improve pull request descriptions and revision history, and can increase code coverage.

### Source excerpt

This is another post in our Code Health series. A version of this post originally appeared in Google bathrooms worldwide as a Google Testing on the Toilet episode. You can download a printer-friendly version to display in your office. By Elliotte Rusty Harold Note: A "pull request" refers to one self-contained change that has been submitted to version control or which is undergoing code review. At Google, this is referred to as a"CL", which is short for "changelist". Prefer small, focused pull requests that do exactly one thing each. Why? Several reasons: Small pull requests are easier to review. A mistake in a focused pull request is more obvious. In a 40 file pull request that does several things, would you notice that one if statement had reversed the logic it should have and was using true instead of false? By contrast, if that if block and its test were the only things that changed in a pull request, you'd be a lot more likely to catch the error. Small pull requests can be reviewed quickly. A reviewer can often respond quickly by slipping small reviews in between other tasks. Larger pull requests are a big task by themselves, often waiting until the reviewer has a significant chunk of time. If something does go wrong and your continuous build breaks on a small pull request, the small size makes it much easier to figure out exactly where the mistake is. They are also easier to rollback if something goes wrong. By virtue of their size, small pull requests are less likely to conflict with other developers' work. Merge conflicts are less frequent and easier to resolve. If you've made a critical error, it saves a lot of work when the reviewer can point this out after you've only gone a little way down the wrong path. Better to find out after an hour than after several weeks. Pull request descriptions are more accurate when pull requests are focused on one task. The revision history becomes easier to read. Small pull requests can lead to increased code coverage becau

## Don't DRY Your Code Prematurely

DevFeed: [Don't DRY Your Code Prematurely](<https://devfeed.tech/articles/don-t-dry-your-code-prematurely-23856.md>)

Original publisher: [Read original article](<http://testing.googleblog.com/2024/05/dont-dry-your-code-prematurely.html>)

Author: Google Testing Bloggers (noreply@blogger.com)

Published: 2024-05-28T14:20:00Z

Content type: opinion

Language: en

Sources: [Google Testing Blog](<https://devfeed.tech/sources/google-testing-blog.md>)

Topics: [Code](<https://devfeed.tech/topics/code.md>), [Testing](<https://devfeed.tech/topics/testing.md>)

Tags: [code](<https://devfeed.tech/tags/code.md>), [code-health](<https://devfeed.tech/tags/code-health.md>), [dan-maksimovich](<https://devfeed.tech/tags/dan-maksimovich.md>), [series](<https://devfeed.tech/tags/series.md>), [tott](<https://devfeed.tech/tags/tott.md>)

### AI overview

The article explains why applying DRY principles too rigidly can create premature abstractions. It recommends distinguishing truly redundant code from superficially similar code whose behavior may need to evolve independently.

### Source excerpt

This is another post in our Code Health series. A version of this post originally appeared in Google bathrooms worldwide as a Google Testing on the Toilet episode. You can download a printer-friendly version to display in your office. By Dan Maksimovich Many of us have been told the virtues of "Don't Repeat Yourself" or DRY. Pause and consider: Is the duplication truly redundant or will the functionality need to evolve independently over time? Applying DRY principles too rigidly leads to premature abstractions that make future changes more complex than necessary. Consider carefully if code is truly redundant or just superficially similar. While functions or classes may look the same, they may also serve different contexts and business requirements that evolve differently over time. Think about how the functions' purpose holds with time, not just about making the code shorter. When designing abstractions, do not prematurely couple behaviors that may evolve separately in the longer term. When does introducing an abstraction harm our code? Let's consider the following code: # Premature DRY abstraction assuming # uniform rules, limiting entity- # specific changes. class DeadlineSetter: def __init__(self, entity_type): self.entity_type = entity_type def set_deadline(self, deadline): if deadline <= datetime.now(): raise ValueError( "Date must be in the future") task = DeadlineSetter("task") task.set_deadline( datetime(2024, 3, 12)) payment = DeadlineSetter("payment") payment.set_deadline( datetime(2024, 3, 18)) # Repetitive but allows for clear, # entity-specific logic and future # changes. def set_task_deadline(task_deadline): if task_deadline <= datetime.now(): raise ValueError( "Date must be in the future") def set_payment_deadline( payment_deadline): if payment_deadline <= datetime.now(): raise ValueError( "Date must be in the future") set_task_deadline( datetime(2024, 3, 12)) set_payment_deadline( datetime(2024, 3, 18)) The approach on the right seems to violate the

## Avoid the Long Parameter List

DevFeed: [Avoid the Long Parameter List](<https://devfeed.tech/articles/avoid-the-long-parameter-list-23855.md>)

Original publisher: [Read original article](<http://testing.googleblog.com/2024/05/avoid-long-parameter-list.html>)

Author: Google Testing Bloggers (noreply@blogger.com)

Published: 2024-05-20T13:42:00Z

Content type: tutorial

Language: en

Sources: [Google Testing Blog](<https://devfeed.tech/sources/google-testing-blog.md>)

Topics: [Code](<https://devfeed.tech/topics/code.md>), [Java](<https://devfeed.tech/topics/java.md>), [C++](<https://devfeed.tech/topics/c-plus-plus.md>), [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [Python](<https://devfeed.tech/topics/python.md>)

Tags: [c-plus-plus](<https://devfeed.tech/tags/c-plus-plus.md>), [class](<https://devfeed.tech/tags/class.md>), [code](<https://devfeed.tech/tags/code.md>), [code-health](<https://devfeed.tech/tags/code-health.md>), [data-class](<https://devfeed.tech/tags/data-class.md>), [gene-volovich](<https://devfeed.tech/tags/gene-volovich.md>), [google](<https://devfeed.tech/tags/google.md>), [java](<https://devfeed.tech/tags/java.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [language](<https://devfeed.tech/tags/language.md>), [list](<https://devfeed.tech/tags/list.md>), [parameter](<https://devfeed.tech/tags/parameter.md>), [post](<https://devfeed.tech/tags/post.md>), [python](<https://devfeed.tech/tags/python.md>), [series](<https://devfeed.tech/tags/series.md>), [tott](<https://devfeed.tech/tags/tott.md>)

### AI overview

This Google Code Health article explains how long parameter lists make method calls difficult to understand and maintain. It recommends grouping related parameters into meaningful value objects, with language-specific options including Java records, Kotlin data classes, C++ option structs, Python keyword arguments and defaults, and the Java Builder pattern.

### Source excerpt

This is another post in our Code Health series. A version of this post originally appeared in Google bathrooms worldwide as a Google Testing on the Toilet episode. You can download a printer-friendly version to display in your office. By Gene Volovich Have you seen code like this? void transform(String fileIn, String fileOut, String separatorIn, String separatorOut); This seems simple enough, but it can be difficult to remember the parameter ordering. It gets worse if you add more parameters (e.g., to specify the encoding, or to email the resulting file): void transform(String fileIn, String fileOut, String separatorIn, String separatorOut, String encoding, String mailTo, String mailSubject, String mailTemplate); To make the change, will you add another (overloaded) transform method? Or add more parameters to the existing method, and update every single call to transform? Neither seems satisfactory. One solution is to encapsulate groups of the parameters into meaningful objects. The CsvFile class used here is a "value object" -- simply a holder for the data. class CsvFile { CsvFile(String filename, String separator, String encoding) { ... } String filename() { return filename; } String separator() { return separator; } String encoding() { return encoding; } } // ... and do the same for the EmailMessage class void transform(CsvFile src, CsvFile target, EmailMessage resultMsg) { ... } How to define a value object varies by language. For example, in Java, you can use a record class, which is available in Java 16+ (for older versions of Java, you can use AutoValue to generate code for the value object); in Kotlin, you can use a data class; in C++, you can use an option struct. Using a value object this way may still result in a long parameter list when instantiating it. Solutions for this vary by language. For example, in Python, you can use keyword arguments and default parameter values to shorten the parameter list; in Java, one option is to use the Builder pattern, wh

## Simplify Complex Boolean Expressions with Meaningful Intermediate Variables

DevFeed: [Simplify Complex Boolean Expressions with Meaningful Intermediate Variables](<https://devfeed.tech/articles/isbooleantoolongandcomplex-23853.md>)

Original publisher: [Read original article](<http://testing.googleblog.com/2024/04/isbooleantoolongandcomplex.html>)

Author: Google Testing Bloggers (noreply@blogger.com)

Published: 2024-04-25T13:14:00Z

Content type: tutorial

Language: en

Sources: [Google Testing Blog](<https://devfeed.tech/sources/google-testing-blog.md>)

Topics: [Code](<https://devfeed.tech/topics/code.md>), [Testing](<https://devfeed.tech/topics/testing.md>)

Tags: [code](<https://devfeed.tech/tags/code.md>), [code-health](<https://devfeed.tech/tags/code-health.md>), [expression](<https://devfeed.tech/tags/expression.md>), [intermediate](<https://devfeed.tech/tags/intermediate.md>), [post](<https://devfeed.tech/tags/post.md>), [quality](<https://devfeed.tech/tags/quality.md>), [series](<https://devfeed.tech/tags/series.md>), [tott](<https://devfeed.tech/tags/tott.md>), [yiming-sun](<https://devfeed.tech/tags/yiming-sun.md>)

### AI overview

This Code Health article explains how to make complex Boolean expressions easier to understand. It recommends extracting conditions into well-named variables and then grouping details into intermediate Booleans that represent single, well-defined qualities, without changing the business logic.

### Source excerpt

This is another post in our Code Health series. A version of this post originally appeared in Google bathrooms worldwide as a Google Testing on the Toilet episode. You can download a printer-friendly version to display in your office. By Yiming Sun You may have come across some complex, hard-to-read Boolean expressions in your codebase and wished they were easier to understand. For example, let's say we want to decide whether a pizza is fantastic: // Decide whether this pizza is fantastic. if ((!pepperoniService.empty() || sausages.size() > 0) && (useOnionFlag.get() || hasMushroom(ENOKI, PORTOBELLO)) && hasCheese()) { ... } A first step toward improving this is to extract the condition into a well-named variable: boolean isPizzaFantastic = (!pepperoniService.empty() || sausages.size() > 0) && (useOnionFlag.get() || hasMushroom(ENOKI, PORTOBELLO)) && hasCheese(); if (isPizzaFantastic) { ... } However, the Boolean expression is still too complex. It's potentially confusing to calculate the value of isPizzaFantastic from a given set of inputs. You might need to grab a pen and paper, or start a server locally and set breakpoints. Instead, try to group the details into intermediate Booleans that provide meaningful abstractions. Each Boolean below represents a single well-defined quality, and you no longer need to mix && and || within an expression. Without changing the business logic, you've made it easier to see how the Booleans relate to each other: boolean hasGoodMeat = !pepperoniService.empty() || sausages.size() > 0; boolean hasGoodVeggies = useOnionFlag.get() || hasMushroom(ENOKI, PORTOBELLO); boolean isPizzaFantastic = hasGoodMeat && hasGoodVeggies && hasCheese(); Another option is to hide the logic in a separate method. This also offers the possibility of early returns using guard clauses, further reducing the need to keep track of intermediate states: boolean isPizzaFantastic() { if (!hasCheese()) { return false; } if (pepperoniService.empty() && sausages.size()

## Naming Code Clearly: Practical Tips for More Readable Identifiers and APIs

DevFeed: [Naming Code Clearly: Practical Tips for More Readable Identifiers and APIs](<https://devfeed.tech/articles/what-s-in-a-name-23851.md>)

Original publisher: [Read original article](<http://testing.googleblog.com/2024/03/whats-in-name.html>)

Author: Google Testing Bloggers (noreply@blogger.com)

Published: 2024-03-26T12:34:00Z

Content type: tutorial

Language: en

Sources: [Google Testing Blog](<https://devfeed.tech/sources/google-testing-blog.md>)

Topics: [Code](<https://devfeed.tech/topics/code.md>), [Computer science](<https://devfeed.tech/topics/computer-science.md>)

Tags: [abstraction](<https://devfeed.tech/tags/abstraction.md>), [adam-raider](<https://devfeed.tech/tags/adam-raider.md>), [code](<https://devfeed.tech/tags/code.md>), [code-health](<https://devfeed.tech/tags/code-health.md>), [identifier](<https://devfeed.tech/tags/identifier.md>), [implementation](<https://devfeed.tech/tags/implementation.md>), [interface](<https://devfeed.tech/tags/interface.md>), [tips](<https://devfeed.tech/tags/tips.md>), [tott](<https://devfeed.tech/tags/tott.md>)

### AI overview

This Code Health post explains why unclear identifiers and interfaces increase cognitive load and make code harder to read. It offers naming guidance, including describing behavior, considering the cost of renaming, revealing intent, and preferring precise names.

### Source excerpt

This is another post in our Code Health series. A version of this post originally appeared in Google bathrooms worldwide as a Google Testing on the Toilet episode. You can download a printer-friendly version to display in your office. by Adam Raider "There are only two hard things in computer science: cache invalidation and naming things." --Phil Karlton Have you ever read an identifier only to realize later it doesn't do what you expected? Or had to read the implementation in order to understand an interface? These indirections eat up our cognitive bandwidth and make our work more difficult. We spend far more time reading code than we do writing it; thoughtful names can save the reader (and writer) a lot of time and frustration. Here are some naming tips: Spend time considering names--it's worth it. Don't default to the first name that comes to mind. The more public the name, the more expensive it is to change. Past a certain scale, names become infeasible to change, especially for APIs. Pay attention to a name in proportion to the cost of renaming it later. If you're feeling stuck, consider running a new name by a teammate. Describe behavior. Encourage naming based on what functions do rather than when the functions are called. Avoid prefixes like "handle" or "on" as they describe when and provide no added meaning: button.listen('click', handleClick) button.listen('click', addItemToCart) Reveal intent with a contextually appropriate level of abstraction: High-abstraction functions describe the what and operate on high-level types. Lower-abstraction functions describe the how and operate on lower-level types. For example, logout might call into clearUserToken, and recordWithCamera might call into parseStreamBytes. Prefer unique, precise names. Are you frequently asking for the UserManager? Manager, Util, and similar suffixes are a common but imprecise naming convention. What does it do? It manages! If you're struggling to come up with a more precise name, consider sp

## How to Write Code Comments That Improve Readability

DevFeed: [How to Write Code Comments That Improve Readability](<https://devfeed.tech/articles/let-code-speak-for-itself-23849.md>)

Original publisher: [Read original article](<http://testing.googleblog.com/2023/12/let-code-speak-for-itself.html>)

Author: Google Testing Bloggers (noreply@blogger.com)

Published: 2023-12-12T16:06:00Z

Content type: tutorial

Language: en

Sources: [Google Testing Blog](<https://devfeed.tech/sources/google-testing-blog.md>)

Topics: [Code](<https://devfeed.tech/topics/code.md>), [Documentation](<https://devfeed.tech/topics/documentation.md>), [implementation](<https://devfeed.tech/topics/implementation.md>)

Tags: [api-documentation](<https://devfeed.tech/tags/api-documentation.md>), [code](<https://devfeed.tech/tags/code.md>), [code-health](<https://devfeed.tech/tags/code-health.md>), [documentation](<https://devfeed.tech/tags/documentation.md>), [francois-aube](<https://devfeed.tech/tags/francois-aube.md>), [guide](<https://devfeed.tech/tags/guide.md>), [readability](<https://devfeed.tech/tags/readability.md>), [shiva-garg](<https://devfeed.tech/tags/shiva-garg.md>), [tott](<https://devfeed.tech/tags/tott.md>)

### AI overview

The article offers practical guidance for writing maintainable code: use comments to explain why an approach is taken, choose descriptive identifiers, document function purpose and meaning, and avoid comments about implementation details that may change.

### Source excerpt

This is another post in our Code Health series. A version of this post originally appeared in Google bathrooms worldwide as a Google Testing on the Toilet episode. You can download a printer-friendly version to display in your office. by Shiva Garg and Francois Aube Comments can be invaluable for understanding and maintaining a code base. But excessive comments in code can become unhelpful clutter full of extraneous and/or outdated detail. Comments that offer useless (or worse, obsolete) information hurt readability. Here are some tips to let your code speak for itself: Write comments to explain the "why" behind a certain approach in code. The comment below has two good reasons to exist: documenting non-obvious behavior and answering a question that a reader is likely to have (i.e. why doesn't this code render directly on the screen?): // Eliminate flickering by rendering the next frame off-screen and swapping into the // visible buffer. RenderOffScreen(); SwapBuffers(); Use well-named identifiers to guide the reader and reduce the need for comments: // Payout should not happen if the user is // in an ineligible country. std::unordered_set<std::string> ineligible = {"Atlantis", "Utopia"}; if (!ineligible.contains(country)) { Payout(user.user_id); } if (IsCountryEligibleForPayout(country)) { Payout(user.user_id); } Write function comments (a.k.a. API documentation) that describe intended meaning and purpose, not implementation details. Choose unambiguous function signatures that callers can use without reading any documentation. Don't explain inner details that could change without affecting the contract with the caller: // Reads an input string containing either a // number of milliseconds since epoch or an // ISO 8601 date and time. Invokes the // Sole, Laces, and ToeCap APIs, then // returns an object representing the Shoe // available then or nullptr if none were. Shoe* ModelAvailableAt(char* time); // Returns the Shoe that was available for // purchase at `time`

## Exceptional Exception Handling

DevFeed: [Exceptional Exception Handling](<https://devfeed.tech/articles/exceptional-exception-handling-23848.md>)

Original publisher: [Read original article](<http://testing.googleblog.com/2023/12/exceptional-exception-handling.html>)

Author: Google Testing Bloggers (noreply@blogger.com)

Published: 2023-12-05T13:19:00Z

Content type: tutorial

Language: en

Sources: [Google Testing Blog](<https://devfeed.tech/sources/google-testing-blog.md>)

Topics: [Exception](<https://devfeed.tech/topics/exception.md>), [Java](<https://devfeed.tech/topics/java.md>), [debugging](<https://devfeed.tech/topics/debugging.md>), [Code](<https://devfeed.tech/topics/code.md>)

Tags: [code](<https://devfeed.tech/tags/code.md>), [code-health](<https://devfeed.tech/tags/code-health.md>), [debugging](<https://devfeed.tech/tags/debugging.md>), [exception-handling](<https://devfeed.tech/tags/exception-handling.md>), [exceptions](<https://devfeed.tech/tags/exceptions.md>), [java](<https://devfeed.tech/tags/java.md>), [tott](<https://devfeed.tech/tags/tott.md>), [yiming-sun](<https://devfeed.tech/tags/yiming-sun.md>)

### AI overview

This article explains how oversized exception-handling blocks can obscure program logic, catch unintended exceptions, and lose root-cause information. Using Java examples, it recommends narrowing the try block, catching the specific exception, and preserving the original cause when rethrowing.

### Source excerpt

This is another post in our Code Health series. A version of this post originally appeared in Google bathrooms worldwide as a Google Testing on the Toilet episode. You can download a printer-friendly version to display in your office. by Yiming Sun Have you ever seen huge exception-handling blocks? Here is an example in Java, although you may have seen similar problems in Python, TypeScript, Kotlin, or any language that supports exceptions. Let's assume we are calling bakePizza() to bake a pizza, and it can be overbaked, throwing a PizzaOverbakedException. class PizzaOverbakedException extends Exception {}; void bakePizza () throws PizzaOverbakedException {}; try { // 100+ lines of code to prepare pizza ingredients. ... bakePizza(); // Another 100+ lines of code to deliver pizza to a customer. ... } catch (Exception e) { throw new IllegalStateException(); // Root cause ignored while throwing new exception. } Here are the problems with the above code: Obscuring the logic. The method bakePizza(), is obscured by the additional lines of code of preparation and delivery, so unintended exceptions from preparation and delivery may be caught. Catching the general exception. catch (Exception e) will catch everything, despite that we might only want to handle PizzaOverbakedException here. Rethrowing a general exception, with the original exception ignored. This means that the root cause is lost - we don't know what exactly goes wrong with pizza baking while debugging. Here is a better alternative, rewritten to avoid the problems above. class PizzaOverbakedException extends Exception {}; void bakePizza () throws PizzaOverbakedException {}; // 100+ lines of code to prepare pizza ingredients. ... try { bakePizza(); } catch (PizzaOverbakedException e) { // Other exceptions won't be caught. // Rethrow a more meaningful exception; so that we know pizza is overbaked. throw new IllegalStateException("You burned the pizza!", e); } // Another 100+ lines of code to deliver pizza to a cu