woowahan

Considerations for Adopting Flutter into (opens in new tab)

To efficiently manage millions of daily orders across a diversifying device ecosystem including Windows, Android, macOS, and iOS, the Baedal Minjok Order Reception team adopted Flutter combined with Clean Architecture. This transition moved the team from redundant platform-specific development to a unified codebase approach that balances high development productivity with a consistent user experience. By focusing on "Write Once, Adapt Everywhere," the team successfully integrated complex platform-specific requirements while maintaining a scalable architectural foundation.

Strategic Shift to Flutter and Multi-Platform Adaptation

  • Business Efficiency: Moving to a single codebase allowed the team to support Android, macOS, and Windows simultaneously, reducing the need for platform-specific developers and accelerating feature parity across devices.
  • Adaptation over Portability: The team shifted from the "Run Everywhere" ideal to "Adapt Everywhere," recognizing that different OSs require unique implementations for core features like app updates (Google Play In-App Updates for Android vs. Sparkle for macOS).
  • Unified UX: Providing a consistent interface across all devices lowered the learning curve for restaurant partners and reduced support issues arising from UI discrepancies between operating systems.

Pragmatic Abstraction Strategy

  • Abstraction Criteria: To avoid over-engineering and excessive boilerplate, the team only applied abstractions when implementations varied by platform, relied on external libraries prone to change, or required mocking for tests.
  • Infrastructure Isolation: Technical implementations like AppUpdateManager and LocalNotification were hidden behind interfaces, allowing the business logic to remain independent of the underlying technology.
  • Case Study (MQTT to SSE): Because real-time communication was abstracted via a ServerEventReceiver interface, the team successfully transitioned from MQTT to Server-Sent Events (SSE) by simply swapping the implementation class without modifying any business logic.

Clean Architecture and BLoC Implementation

  • Layered Design: The project follows a strict separation into Data (Repository Impl, DTO), Domain (Entity, UseCase, Interfaces), and Presentation (UI, BLoC) layers, with an additional Infrastructure layer for hardware-specific tasks like printing.
  • Explicit State Management: The BLoC (Business Logic Component) pattern was chosen for its stream-based approach, which provides a clear audit trail of events and states (e.g., tracking an order list from InitializeListEvent to LoadedOrderListState).
  • Reliability over Conciseness: Despite the boilerplate code required by BLoC, the team prioritized the ability to trace state changes and debug complex business flows in a high-traffic production environment.

Evolution Toward an App Shell Model

  • Rapid Deployment: To further increase agility, the team is transitioning toward a WebView-based "App Shell" container, which allows for immediate web-based feature updates that bypass lengthy app store review processes.
  • Hybrid Approach: While the core "Shell" remains in Flutter to handle system-level permissions and hardware integration, the business features are increasingly delivered via web technologies to maintain high update frequency.

By establishing a robust foundation with Flutter and Clean Architecture, the team has successfully balanced the need for cross-platform development speed with the technical rigor required for a mission-critical order reception system. Their pragmatic approach to abstraction ensures the system remains maintainable even as underlying communication protocols or platform requirements evolve.