No description
Find a file
2023-07-21 23:29:37 +02:00
CSharp/Kata Add C# starting point with failing example test 2023-02-08 18:54:06 +01:00
Java Add usage example in main method 2023-01-26 21:36:40 +01:00
Kotlin Remove files accidentally tracked due to mislocated gitignore 2023-01-25 22:27:12 +01:00
LICENSE Initial commit 2023-01-03 13:37:40 +01:00
README.md Link to kata repository from solution README 2023-07-21 23:29:37 +02:00

This is an example solution.

Make sure to try solving the kata yourself first and check out the example solution afterwards. The provided solution is of course only an example of what your solution could look like.

Temperature Kata

A coding kata that focuses on encapsulation and simple design.


Thought Process: Designing a Type

Consider this code:

float temperature = 36.7f;

Any problems with this? Discuss with your peers.

Reveal answer

Being roughly the average body temperature (in °C) we might assume that it represents a measurement on the Celsius scale, but we might be misled. Could it be Fahrenheit? Or wouldn't the most appropriate technical temperature scale be Kelvin?

Let's use a clearer name:

float temperatureInCelsius = -300.0f;

That's pretty cold. Any problems with this code?

Reveal answer

Temperatures below roughly -273,15 °C are physically impossible. Let's write some code that tells us whether a temperature is physically possible, since we don't control where the measurements come from:

public class TemperatureUtils {

    private static final float CELSIUS_TO_KELVIN_OFFSET = 273.15f;

    public static boolean isPhysicallyPossible(float temperatureInCelsius) {
        return toKelvin(temperatureInCelsius) >= 0.0f;
    }

    public static float toKelvin(float temperatureInCelsius) {
        return temperatureInCelsius + CELSIUS_TO_KELVIN_OFFSET;
    }
}

Now we can easily filter out impossible measurements, if needed. Any problems with this code?

Reveal answer

If it's a simple program that only deals with temperatures, this might be simple enough. But now imagine a more complex domain where not only temperatures, but many more concepts, are represented as a primitive type with public static methods scattered around. At that point, the difference between Java and C becomes negligible.

What are legal/meaningful operations on a temperature? Addition? Multiplication?

Imagine you had an object that represents the concept of a certain temperature:

  • It does not imply any specific representation (Celsius, Fahrenheit, Kelvin).
  • It hides the internal representation and data type.
  • It has a small surface area, allowing only meaningful operations and preventing misuse.
  • Conversions are replaced with representations.
  • It is easily extensible: There are many more temperature scales (although much rarer in practice).

Requirements

  • Measurements in Celsius, Fahrenheit, and Kelvin are supported (i.e. they might be provided by different (hypothetical) external APIs on those 3 scales).

  • From the caller's perspective, there are no conversions, only representations of the same temperature on the 3 supported scales.

  • Temperatures can be formatted on all 3 supported scales.

  • Immutable: No getters and setters.

    Hint

    You might be tempted to name some read-only methods get...(). What's a better naming scheme in this context? Discuss! Remember: We are not accessing internals, but requesting representations.

  • Common temperatures (e.g. absolute zero) can be accessed exactly where they would be expected.
    Note: You might be tempted to create a (static) class like TemperatureConstants. What would be a more idiomatic approach? How would you expect the standard library to do it?

    Hint

    We are looking for static factory methods in the Temperature type. Note: We should probably define them as constants, since they are immutable and can thus easily be reused, but that's an implementation detail. PUBLICLY_EXPOSING_THE_CONSTANTS breaks encapsulation.


Example Values

You can use these values to test your implementation. You can of course look up the formulas, but if you don't fear a challenge, try remapping the scales yourself based on these example values.

I want to try it myself, but I need a hint.

Remap algorithm:

  1. Normalize the value within the range of the current scale.
  2. Place it on the target scale by multiplying it with the target scale's range.
  3. Offset it by the lower of the 2 known values of the target scale.
Kelvin Celsius Fahrenheit
Absolute zero 0 K 273.15 °C 459.67 °F
Freezing point of water 273.15 K 0 °C 32 °F
Boiling point of water 373.1339 K 99.9839 °C 211.97102 °F

© 2023 Raimund Krämer - Use with attribution.

Links to third party sites are included for convenience only and I am not responsible for their contents.