Live Coding Learnings - June 21, 2019 
Tags: todayilearned, java, unittesting, livecoding
Published: 2019-06-23 22:31:14

---
title: Live Coding Learnings - June 21, 2019 
published: true
description: Summary of what I learned in today's live coding stream at twitch.tv/jitterted
tags: TIL, Java, Unit Testing, Live Coding
series: Live Coding Lessons Learned
---

# Quizdown: Episode 20

The 20th episode of working on Quizdown, a Java+Spring-based app that uses a Markdown-like syntax to create coding quizzes.

## Stories Implemented

After a non-trivial refactoring (see **No Naked Data Structures** below),
I now have the ability to move back and forth between questions. The HTML generation now generates `checked` if that choice was previously selected. Next step is to load the user's responses from the database and send that to the UI controller.

## HTML: Use disabled Attribute for Button or Link

When I was looking for the proper CSS class to use to display a button as disabled, I found that instead of using, say, an `is-disabled` CSS class, HTML supports `disabled` as an attribute on both `button` and link (`<a>`). For example, to show the link as *disabled* instead of:

```html
<a class="is-disabled" href="/question/0">Previous Question</a>
```

you would use the `disabled` attribute like this:

```html
<a href="/question/0" disabled>Previous Question</a>
```

## No Naked Data Structures

One of my Java design heuristics is *No Naked Data Structures*, which means wrapping raw data structures (`List`, `Map`, etc.) in a type so you can pass it around and interact with it in a way that makes sense from a domain point of view.

> This is similar to the *No Stringly-Typed Code* heuristic: don't use `String` everywhere, instead use class and interface types. For details see [here](http://wiki.c2.com/?StringlyTyped) and [here](https://kamilszymanski.github.io/refactoring-stringly-typed-systems/).

When adding the feature to allow users to go back and forth through the questions, I needed to have the choices that the user made be available. Previously I was storing those choices as a `Set<String>`, as it was straightforward and it wasn't being used in many places. However, once I needed it in more places (pushing it back up to the front-end from the database), handing around a "naked" `Set` made the code a bit harder to read and work with. For example, with the `Set`, figuring out if it's correct depended on the type of question (`FIB` is a fill-in-the-blank and `MC` is multiple-choice):

```java
  public boolean isCorrectFor(@NonNull Set<String> response) {
    return switch (questionType) {
      case FIB -> correctChoices.containsAll(response);
      case MC -> correctChoices.equals(response);
    };
  }
```

This is pretty typical code, but unless you're familiar with the specifics of `Set`, you may have to do a bit of JavaDoc reading to ensure you understand it correctly. By replacing it with a `Response` type that _encapsulates_ the `Set`, the code above becomes:

```java
  public boolean isCorrectFor(Response response) {
    return switch (questionType) {
      case FIB -> response.matchesAny(correctResponse);
      case MC -> response.allMatch(correctResponse);
    };
  }
```

Now, this may not be such an amazing improvement (I'm still toying with the naming), but it leads to the next step (which I haven't done yet) of pushing the behavior that's specific to the question type into a subclass of Response, e.g., a `FibResponse` and `McResponse`, which would look like:

```java
  public boolean isCorrectFor(Response response) {
    return response.correctlyMatches(correctResponse);
  }
```

Completely delegating how responses are compared to the class that knows best how to do that comparison.

In my training and coaching of Java developers, the use of Stringly types and Naked Data Structures is the cause for much pain when things change, so always try and encapsulate Strings into Value Objects and wrap up your data structures into its own class.

## Exposing `asSet()` on Response: breaks Encapsulation?

By encapsulating the `Set<String>` inside of `Response` means that when I need to display the response choices or persist them to a database (i.e., hand the response across the _domain boundary_) I need to get those choices as a set, so the `Response` class has a method

```java
public Set<String> asSet() {
  return Set.copyOf(response); // return a copy of our internal field
}
```

That returns the choices as a `Set<String>`. I use this in the `GradedAnswerView` class to convert it to a comma-separated `String`:

  ```java
  private static String responseAsString(Answer answer) {
    return answer.response().asSet()
                 .stream()
                 .sorted()
                 .collect(Collectors.joining(", "));
  }
  ```

You might think: _oh no, this is breaking encapsulation by exposing the set_, but I'm not really doing that, because I'm returning a copy of my internal storage of the response choices. I never expose the field itself, so the only way to modify the internal `Response` data is only through its methods. Modifying the copy would have no effect.

## Empty varargs

I don't think I had realized this before, but calling a method defined with varargs (e.g., `createFrom(String... strings)`) means that you can call that method with _no_ arguments: `createFrom()`, and inside this method, the `strings` argument would be an empty array.

This means I didn't have to special-case turning varargs into an empty Set, because calling `Set.of()` with no arguments will turn into an empty Set (technically an `ImmutableCollections.emptySet()` as of Java 9), which is what I'd want. 

## Collaboration Tests

Most of my tests are unit tests, in that they are testing code in a class by working with that class as closely as possible. For example, the [`Choice` class](https://github.com/jitterted/quizdown/blob/7b9c120604fa3957e464b0f965fef1ab339de1fe/src/main/java/com/jitterted/quizdown/adapter/web/MultipleChoiceTransformer.java#L45) can be directly tested without any other objects. However, the `QuestionTransformer` can't be tested on its own as its job is mostly to collaborate with more specific transformers to do its job, i.e., its job is to integrate or collaborate with the other objects. This means that I don't need to comprehensively test all of the behavior of all of the classes that are involved, just a test or two that would ensure that `QuestionTransformer` is _correctly_ collaborating with (in this case, propagating the response to) other objects.

You can see a clip from my stream where I do this: https://www.twitch.tv/videos/443315061.


----

Be sure and tune in to my next live coding stream: https://twitch.tv/jitterted.

Want to support me? Become a Patron at https://patreon.com/jitterted