From 001f6444fec8fcd5312028cfdae90f4f93424559 Mon Sep 17 00:00:00 2001 From: Kostya Date: Fri, 14 Aug 2026 20:32:49 +0000 Subject: Collapse console I/O interfaces into InputProcessor, drop unneeded atomics InputProvider/OutputProvider each had one implementation and no test exercised the seam, so fold Console{Input,Output}Provider straight into InputProcessor and update Menu/MenuCommand call sites accordingly. Account and Event both use AtomicInteger for a ledger/trade id counter that's only ever touched next to a plain, non-thread-safe ArrayList add in the same method - the atomic bought no real thread-safety. Swapped both to plain int with ++. --- .../src/main/java/market/guess/ui/console/App.java | 6 ---- .../main/java/market/guess/ui/console/Menu.java | 19 +++++----- .../guess/ui/console/command/ExitMenuCommand.java | 10 +++--- .../ui/console/command/ListEventsMenuCommand.java | 20 +++++------ .../ui/console/command/LoadFileMenuCommand.java | 17 ++++----- .../guess/ui/console/io/ConsoleInputProvider.java | 17 --------- .../guess/ui/console/io/ConsoleOutputProvider.java | 24 ------------- .../market/guess/ui/console/io/InputProcessor.java | 41 +++++++++++++++------- .../market/guess/ui/console/io/InputProvider.java | 5 --- .../market/guess/ui/console/io/OutputProvider.java | 11 ------ 10 files changed, 58 insertions(+), 112 deletions(-) delete mode 100644 ui-console/src/main/java/market/guess/ui/console/io/ConsoleInputProvider.java delete mode 100644 ui-console/src/main/java/market/guess/ui/console/io/ConsoleOutputProvider.java delete mode 100644 ui-console/src/main/java/market/guess/ui/console/io/InputProvider.java delete mode 100644 ui-console/src/main/java/market/guess/ui/console/io/OutputProvider.java (limited to 'ui-console/src/main/java/market/guess/ui/console') diff --git a/ui-console/src/main/java/market/guess/ui/console/App.java b/ui-console/src/main/java/market/guess/ui/console/App.java index 34638ac..3d42e9b 100644 --- a/ui-console/src/main/java/market/guess/ui/console/App.java +++ b/ui-console/src/main/java/market/guess/ui/console/App.java @@ -14,11 +14,7 @@ import market.guess.service.repository.UserRepository; import market.guess.ui.console.command.ExitMenuCommand; import market.guess.ui.console.command.ListEventsMenuCommand; import market.guess.ui.console.command.LoadFileMenuCommand; -import market.guess.ui.console.io.ConsoleInputProvider; -import market.guess.ui.console.io.ConsoleOutputProvider; import market.guess.ui.console.io.InputProcessor; -import market.guess.ui.console.io.InputProvider; -import market.guess.ui.console.io.OutputProvider; import org.picocontainer.DefaultPicoContainer; import org.picocontainer.behaviors.Caching; @@ -38,8 +34,6 @@ public class App { pico.addComponent(ListEventsMenuCommand.class); pico.addComponent(ExitMenuCommand.class); - pico.addComponent(InputProvider.class, ConsoleInputProvider.class); - pico.addComponent(OutputProvider.class, ConsoleOutputProvider.class); pico.addComponent(InputProcessor.class); pico.addComponent(Menu.class); diff --git a/ui-console/src/main/java/market/guess/ui/console/Menu.java b/ui-console/src/main/java/market/guess/ui/console/Menu.java index c1762dc..18b72b7 100644 --- a/ui-console/src/main/java/market/guess/ui/console/Menu.java +++ b/ui-console/src/main/java/market/guess/ui/console/Menu.java @@ -3,32 +3,29 @@ package market.guess.ui.console; import java.util.List; import market.guess.ui.console.command.MenuCommand; import market.guess.ui.console.io.InputProcessor; -import market.guess.ui.console.io.OutputProvider; import org.picocontainer.Startable; public final class Menu implements Startable { - private final OutputProvider out; - private final InputProcessor in; + private final InputProcessor io; private final List commands; - public Menu(List commands, OutputProvider out, InputProcessor in) { + public Menu(List commands, InputProcessor io) { this.commands = commands; - this.out = out; - this.in = in; + this.io = io; } @Override public void start() { var max = commands.stream().mapToInt(MenuCommand::getIndex).max().orElse(0); - out.splashScreen(); + io.splashScreen(); while (true) { printMenu(); - var selection = in.readInt("Choose a command: ", 1, max); + var selection = io.readInt("Choose a command: ", 1, max); var commandOptional = commands.stream().filter(c -> c.getIndex() == selection).findFirst(); if (commandOptional.isEmpty()) { - out.println("There is no command %d.".formatted(selection)); + io.println("There is no command %d.".formatted(selection)); continue; } var command = commandOptional.get(); @@ -45,9 +42,9 @@ public final class Menu implements Startable { } private void printMenu() { - out.newLine(); + io.newLine(); for (var command : commands) { - out.println(" [%d]->> %s".formatted(command.getIndex(), command.getName())); + io.println(" [%d]->> %s".formatted(command.getIndex(), command.getName())); } } } diff --git a/ui-console/src/main/java/market/guess/ui/console/command/ExitMenuCommand.java b/ui-console/src/main/java/market/guess/ui/console/command/ExitMenuCommand.java index 372c686..23ed9c9 100644 --- a/ui-console/src/main/java/market/guess/ui/console/command/ExitMenuCommand.java +++ b/ui-console/src/main/java/market/guess/ui/console/command/ExitMenuCommand.java @@ -1,13 +1,13 @@ package market.guess.ui.console.command; -import market.guess.ui.console.io.OutputProvider; +import market.guess.ui.console.io.InputProcessor; public final class ExitMenuCommand implements MenuCommand { - private final OutputProvider out; + private final InputProcessor io; - public ExitMenuCommand(OutputProvider out) { + public ExitMenuCommand(InputProcessor io) { super(); - this.out = out; + this.io = io; } @Override @@ -32,6 +32,6 @@ public final class ExitMenuCommand implements MenuCommand { @Override public void execute() { - out.println("Goodbye."); + io.println("Goodbye."); } } diff --git a/ui-console/src/main/java/market/guess/ui/console/command/ListEventsMenuCommand.java b/ui-console/src/main/java/market/guess/ui/console/command/ListEventsMenuCommand.java index 6e6ace9..bad621d 100644 --- a/ui-console/src/main/java/market/guess/ui/console/command/ListEventsMenuCommand.java +++ b/ui-console/src/main/java/market/guess/ui/console/command/ListEventsMenuCommand.java @@ -2,16 +2,16 @@ package market.guess.ui.console.command; import market.guess.api.CommissionTiming; import market.guess.api.GuessMarketContext; -import market.guess.ui.console.io.OutputProvider; +import market.guess.ui.console.io.InputProcessor; public final class ListEventsMenuCommand implements MenuCommand { private final GuessMarketContext context; - private final OutputProvider out; + private final InputProcessor io; - public ListEventsMenuCommand(GuessMarketContext context, OutputProvider out) { + public ListEventsMenuCommand(GuessMarketContext context, InputProcessor io) { super(); this.context = context; - this.out = out; + this.io = io; } @Override @@ -34,14 +34,14 @@ public final class ListEventsMenuCommand implements MenuCommand { var events = context.listEvents(); for (var event : events) { - out.newLine(); - out.println(" %s".formatted(event.name())); - out.println(" %s".formatted(event.description())); - out.println( + io.newLine(); + io.println(" %s".formatted(event.name())); + io.println(" %s".formatted(event.description())); + io.println( " Commission: %d%% (%s)" .formatted(event.commissionPercent(), timing(event.commissionTiming()))); - out.println(" Options: " + String.join(" | ", event.optionNames())); - out.println(" Status: " + event.status()); + io.println(" Options: " + String.join(" | ", event.optionNames())); + io.println(" Status: " + event.status()); } } diff --git a/ui-console/src/main/java/market/guess/ui/console/command/LoadFileMenuCommand.java b/ui-console/src/main/java/market/guess/ui/console/command/LoadFileMenuCommand.java index 4a56483..7005632 100644 --- a/ui-console/src/main/java/market/guess/ui/console/command/LoadFileMenuCommand.java +++ b/ui-console/src/main/java/market/guess/ui/console/command/LoadFileMenuCommand.java @@ -3,17 +3,14 @@ package market.guess.ui.console.command; import java.nio.file.Path; import market.guess.api.GuessMarketContext; import market.guess.ui.console.io.InputProcessor; -import market.guess.ui.console.io.OutputProvider; public final class LoadFileMenuCommand implements MenuCommand { private final GuessMarketContext context; - private final OutputProvider out; - private final InputProcessor in; + private final InputProcessor io; - public LoadFileMenuCommand(GuessMarketContext context, InputProcessor in, OutputProvider out) { + public LoadFileMenuCommand(GuessMarketContext context, InputProcessor io) { this.context = context; - this.out = out; - this.in = in; + this.io = io; } @Override @@ -33,18 +30,18 @@ public final class LoadFileMenuCommand implements MenuCommand { @Override public void execute() { - var path = in.readPath("Pleae enter the full file path to the XML file: "); + var path = io.readPath("Pleae enter the full file path to the XML file: "); var result = context.loadEvents(Path.of(path)); if (result.success()) { - out.println("Loaded %d event(s) from %s.".formatted(result.eventsLoaded(), result.source())); + io.println("Loaded %d event(s) from %s.".formatted(result.eventsLoaded(), result.source())); return; } - out.println( + io.println( "The file was not loaded. %d problem(s) were found: ".formatted(result.issues().size())); for (var issue : result.issues()) { - out.println(" - %s: %s".formatted(issue.location(), issue.humanizedMessage())); + io.println(" - %s: %s".formatted(issue.location(), issue.humanizedMessage())); } } } diff --git a/ui-console/src/main/java/market/guess/ui/console/io/ConsoleInputProvider.java b/ui-console/src/main/java/market/guess/ui/console/io/ConsoleInputProvider.java deleted file mode 100644 index 5c93f71..0000000 --- a/ui-console/src/main/java/market/guess/ui/console/io/ConsoleInputProvider.java +++ /dev/null @@ -1,17 +0,0 @@ -package market.guess.ui.console.io; - -import java.util.Scanner; - -public class ConsoleInputProvider implements InputProvider { - private final Scanner scanner = new Scanner(System.in); - - @Override - public void close() throws Exception { - scanner.close(); - } - - @Override - public String nextLine() { - return scanner.hasNextLine() ? scanner.nextLine() : null; - } -} diff --git a/ui-console/src/main/java/market/guess/ui/console/io/ConsoleOutputProvider.java b/ui-console/src/main/java/market/guess/ui/console/io/ConsoleOutputProvider.java deleted file mode 100644 index 6fa7595..0000000 --- a/ui-console/src/main/java/market/guess/ui/console/io/ConsoleOutputProvider.java +++ /dev/null @@ -1,24 +0,0 @@ -package market.guess.ui.console.io; - -public class ConsoleOutputProvider implements OutputProvider { - - @Override - public void print(Object object) { - IO.print(object); - } - - @Override - public void println(Object object) { - IO.println(object); - } - - @Override - public void newLine() { - IO.println(""); - } - - @Override - public void splashScreen() { - IO.println("<<-- GUESS MARKET -->>"); - } -} diff --git a/ui-console/src/main/java/market/guess/ui/console/io/InputProcessor.java b/ui-console/src/main/java/market/guess/ui/console/io/InputProcessor.java index 9f03acb..4889c36 100644 --- a/ui-console/src/main/java/market/guess/ui/console/io/InputProcessor.java +++ b/ui-console/src/main/java/market/guess/ui/console/io/InputProcessor.java @@ -1,41 +1,52 @@ package market.guess.ui.console.io; +import java.util.Scanner; + public final class InputProcessor { - private final OutputProvider out; - private final InputProvider in; + private final Scanner scanner = new Scanner(System.in); + + public void print(Object object) { + IO.print(object); + } + + public void println(Object object) { + IO.println(object); + } - public InputProcessor(InputProvider in, OutputProvider out) { - super(); - this.in = in; - this.out = out; + public void newLine() { + IO.println(""); + } + + public void splashScreen() { + IO.println("<<-- GUESS MARKET -->>"); } public String readLine(String prompt) { - out.print(prompt); - var line = in.nextLine(); + print(prompt); + var line = nextLine(); return line.trim(); } public int readInt(String prompt, int min, int max) { while (true) { - var raw = in.nextLine(); + var raw = nextLine(); if (raw.isBlank()) { - out.println("Please enter a number between %d and %d.".formatted(min, max)); + println("Please enter a number between %d and %d.".formatted(min, max)); continue; } try { var value = Integer.parseInt(raw); if (value > max || value < min) { - out.println( + println( "%d is out of range, please enter a number between %d and %d." .formatted(value, min, max)); continue; } return value; } catch (NumberFormatException e) { - out.println( + println( "%s in not a number, please enter a number between %d and %d." .formatted(raw, min, max)); continue; @@ -48,11 +59,15 @@ public final class InputProcessor { var raw = readLine(prompt); if (raw.isBlank()) { - out.println("Please enter a file path."); + println("Please enter a file path."); continue; } return raw; } } + + private String nextLine() { + return scanner.hasNextLine() ? scanner.nextLine() : null; + } } diff --git a/ui-console/src/main/java/market/guess/ui/console/io/InputProvider.java b/ui-console/src/main/java/market/guess/ui/console/io/InputProvider.java deleted file mode 100644 index 9404bb7..0000000 --- a/ui-console/src/main/java/market/guess/ui/console/io/InputProvider.java +++ /dev/null @@ -1,5 +0,0 @@ -package market.guess.ui.console.io; - -public interface InputProvider extends AutoCloseable { - String nextLine(); -} diff --git a/ui-console/src/main/java/market/guess/ui/console/io/OutputProvider.java b/ui-console/src/main/java/market/guess/ui/console/io/OutputProvider.java deleted file mode 100644 index e419351..0000000 --- a/ui-console/src/main/java/market/guess/ui/console/io/OutputProvider.java +++ /dev/null @@ -1,11 +0,0 @@ -package market.guess.ui.console.io; - -public interface OutputProvider { - void print(Object object); - - void newLine(); - - void splashScreen(); - - void println(Object object); -} -- cgit v1.2.3