Station Status Board – Task 5

The seven-HashMap solution from the previous task works, but as the chief engineer predicted, it has become a maintenance burden. When adding new subsystems to the monitoring system, engineers frequently forget to update all seven HashMaps, leading to incomplete data. When querying subsystems, the code is verbose and repetitive. The station's software review board has flagged this pattern as problematic and asked you to refactor it.

The chief engineer sits down with you to discuss a better approach. She explains that in object-oriented programming, when multiple pieces of data naturally belong together, you can define a class to group them. A class serves as a blueprint that describes what data a particular type of object contains. Once you define the class, you can create instances of it—individual objects that hold specific values for those data fields.

She sketches out an example on a whiteboard: "Think of a subsystem as a single entity with properties. It has a name, a current reading, a status, a minimum value, a maximum value, a critical threshold, a measurement count, and a last update time. Instead of storing these in seven separate HashMaps, we can create a SubsystemData class that holds all of these fields. Then we only need one HashMap that maps subsystem names to SubsystemData objects."

She pulls up an example from the station's inventory system to show you how classes work in practice. The inventory team tracks spare parts using a similar approach:

class InventoryItem {
    String partNumber;
    String description;
    int quantity;
    String location;
    
    InventoryItem(String partNumber, String description, int quantity, String location) {
        this.partNumber = partNumber;
        this.description = description;
        this.quantity = quantity;
        this.location = location;
    }
    
    void displayInfo() {
        System.out.println(partNumber + ": " + description);
        System.out.println("  Quantity: " + quantity);
        System.out.println("  Location: " + location);
    }
}

"See how all the information about a part is kept together?" she explains. "Your SubsystemData class will follow the same pattern, but with the diagnostic fields instead."

Your task is to create a class called SubsystemData that contains fields for all the diagnostic information. You'll then modify your program to use a single HashMap that stores SubsystemData objects, with subsystem names as keys.

The status file format remains unchanged:

ReactorCooling 42% NORMAL 35% 58% 35% 127 14:23
PowerDistribution 119V NORMAL 115V 124V 117V 134 14:23
LifeSupport 198000ppm NORMAL 195000ppm 205000ppm 195000ppm 128 14:23
Navigation 0.02deg WARNING 0.00deg 0.08deg 0.05deg 131 14:23
ThermalRegulation 18C NORMAL 16C 22C 15C 129 14:23
WasteRecycling 87% NORMAL 82% 95% 80% 126 14:23
CommArray 94% NORMAL 89% 98% 85% 133 14:23
DockingClamps 3201kPa NORMAL 3150kPa 3280kPa 3100kPa 130 14:23

When reading the file, you'll create a SubsystemData object for each line and add it to your HashMap. When a user queries a subsystem, you'll retrieve the SubsystemData object and access its fields to display the information.

The program's output should remain the same as Task 4:

Enter subsystem name (or 'quit' to exit): ReactorCooling
ReactorCooling: 42% [NORMAL]
  Range: 35% to 58%
  Critical threshold: 35%
  Measurements recorded: 127
  Last updated: 14:23

Enter subsystem name (or 'quit' to exit): quit
Session ended.

As you implement this, notice how much cleaner the code becomes. Reading a line from the file now creates one object and adds it to one HashMap, rather than adding seven separate entries. Querying a subsystem retrieves one object, and you can access all its data through that single reference. The relationship between the data fields is now explicit in the code—they're grouped together in a class because they describe the same thing.


Looking ahead: The chief engineer is pleased with this refactoring. She mentions that while all subsystems currently use identical data structures, some engineering teams have been requesting subsystem-specific features. The reactor team wants automatic emergency shutdown warnings. The power team wants voltage trend analysis. The life support team wants per-crew-member oxygen calculations. Adding these specialized behaviors to a single SubsystemData class would make it cluttered and complex, but there's a technique for handling this scenario that you'll learn in upcoming tasks.