Design an EventExporter that records analytics events and renders them in different output formats. Every supported format must follow the same validation step before applying its own formatting rules.
The provided EventExporter class supports these operations:
EventExporter() creates an exporter holding no events.boolean addEvent(String name) records an event and returns true. If name is empty, it records nothing and returns false.String exportAs(String format) returns the recorded events rendered in format:"csv" joins the names with commas: signup,login."summary" includes the count and separates names with pipes: 2 events: signup | login."json" returns a compact JSON array of names: ["signup","login"]."UNSUPPORTED", even when no events have been recorded."INVALID" when there are no events to export.int eventCount() returns how many events have been recorded.Adding another format later must not require repeating the empty-event validation or modifying the decision logic inside exportAs.
Your task is to implement the ExportFormat abstraction and the concrete CsvFormat, SummaryFormat, and JsonFormat classes. Do not modify the provided EventExporter. Put the shared validation in the abstraction so every registered format follows it automatically.
Input:
Output:
Explanation: The same three events are passed through three format implementations. CSV joins the names, Summary adds a count, and JSON produces a compact array. Each exporter preserves insertion order.
Input:
Output:
Explanation: The empty name is rejected, leaving the exporter with no events. Because json is supported but has nothing to render, the shared validation returns INVALID.
0 <= name.length <= 40name consists only of lowercase English letters.format is a lowercase word.100 calls will be made across all methods.Full marks when there is an exporter abstraction declaring the format-specific step, with CSV, Summary and JSON as separate implementations. Lose points heavily when exportAs contains an if or switch over the format string that also performs formatting inline.
Full marks when the emptiness check runs once, in shared code that every format goes through, so no format can produce output from no events. Lose points when the check is duplicated per format or can be bypassed by adding a new one.
Full marks for descriptive names, the INVALID and UNSUPPORTED responses handled deliberately rather than as fallthrough, and no dead code. Lose points for printing to stdout or for format strings compared in more than one place.
Passing every test is not enough on its own. A submission is accepted only when the design also clears the bar.
| Call | Returns |
|---|---|
| new EventExporter() | null |
| addEvent("signup") | true |
| addEvent("login") | true |
| addEvent("purchase") | true |
| exportAs("csv") | "signup,login,purchase" |
| exportAs("summary") | "3 events: signup | login | purchase" |
| exportAs("json") | "[\"signup\",\"login\",\"purchase\"]" |
CSV joins the names, Summary includes the count, and JSON returns a compact array. All three preserve insertion order.
Run checks these cases. Submit also runs a larger hidden set.

