1. No Global State Guarantee
JudgeAnalytics is a plain class. Any code can create one with new JudgeAnalytics().
- The Issue: Each caller gets its own instance. Run counts and submit counts end up spread across different objects.
- The Impact: No one object knows the "total runs" or "total submits" for the whole system. One component may see 5 runs while another sees 2, depending on which instance it holds.
2. No Single Place for "Global" Data
Analytics that describe the whole system (e.g., total submissions to a judge) should keep that state in exactly one place.
- The Issue: The design allows any number of instances. Each class that needs analytics creates its own
JudgeAnalytics, so the "global" picture is never right. - The Impact: Reports, dashboards, or rate limits that need total run/submit counts have no single source of truth to read.
3. Wasted Resources and Inconsistency
Creating a new JudgeAnalytics in every service or controller leads to:
- The Issue: Extra objects that each keep their own counters. Nothing links them.
- The Scenario:
Main(or several services) each callnew JudgeAnalytics(). A click counted in one place does not show up in another. You cannot answer "how many runs happened in total?".
4. Testing and Predictability
With many instances, tests and production code have no shared state to rely on.
- The Issue: You cannot pass in "the" analytics object (inject it) or check a global count, because no single instance exists.
- The Impact: System-wide metrics are harder to test and to reason about.
Summary of the "Smell"
Some classes must be one system-wide resource (logger, config, connection pool, or global analytics). If anyone can still call new on them, make them a Singleton. Then only one instance ever exists, and all callers share it.