# Yiming Sun

Published articles for Yiming Sun.

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

## 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()

## 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