app-shell

1 posts

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.