Preface
Messaging friends, booking airplane tickets, ordering a grocery delivery, checking bank accounts, buying metro tickets... this is just a short list of tasks we accomplish today with the help of mobile and web applications. Apps are omnipresent, and someone must develop them. If you are holding this book, there is a high chance that you are one of these developers.
In recent years, Flutter has become a stable and widely used framework for building apps. And not just mobile apps, as it also supports building for web, desktop, and beyond. However, to thrive in the modern world, apps need to be more than just functional - they must be beautiful, fast, and reliable. These qualities are achieved through the approaches used to build the apps. A scalable, flexible, maintainable, and testable architecture is essential to help businesses stand out and to provide users with the high-quality experience they expect. This is where design patterns and best practices come into play.
Design patterns are proven blueprints for solutions to common problems that arise in software design. They provide standard terminology and are specific to particular scenarios, making the development process more efficient and reliable. For instance, patterns such as Singleton, Observer, and Factory Method offer templates for solving issues related to object creation, communication between objects, and more.
Best practices, on the other hand, are guidelines or methodologies that have been shown through experience and research to lead to optimal results. These practices include coding standards, architectural principles, and development processes that ensure high-quality software. They help to maintain code readability, performance, security, and scalability.
This book dives into the details of Flutter's inner workings, teaches various design patterns to build Flutter apps, and explores the best practices for developing robust applications. Understanding these fundamentals is crucial for making informed decisions about which practices and guidelines to follow and which to adapt or skip.
This knowledge is built on the experience of developing over 50 apps of various scales in industry-leading mobile development agencies and companies. However, it's important to remember that there is always room for individual opinions and adjustments.
It is a great time to be a Flutter developer, and this book will help you become one who is highly skilled and competitive.
Who this book is for
Mobile developers of any level can gain practical insights into how to craft Flutter apps according to best practices. You are especially likely to benefit from this book if you belong to one of the following groups:
- Flutter developers: If you have already built some projects with Flutter and want to enhance your skills to build scalable, maintainable, and stable applications that follow the best practices, this book will show you how.
- Mobile developers from other tech stacks: If you have already built mobile apps in other frameworks, such as React Native or Xamarin, or for native platforms, and want to transition to Flutter, this book will teach you how to apply your existing knowledge to Flutter.
- Aspiring Flutter developers: If you have not yet built apps in any tech stacks but have some programming experience in other stacks, this book can be used to navigate the Flutter framework alongside more beginner-friendly resources.
What this book covers
Chapter 1, Best Practices for Building UIs with Flutter, discusses the difference between imperative and declarative approaches to UI building and why modern frameworks prefer the latter. We will explore the details of the Flutter widget tree system, and practical advice on how to build performant interfaces.
Chapter 2, Responsive UI for All Devices, provides an overview of the Flutter layout algorithm, dives into the best practices and available options for building responsive interfaces, and covers accessibility best practices.
Chapter 3, Vanilla State Management, opens the topic of state management in Flutter. It provides the definition of state and its different types. In this chapter, we start building the Candy Store app, which we will continue building throughout the book, and learn how to implement state management patterns in the vanilla Flutter way. You will also see an overview of the InheritedWidget class details, and practical tips on working with BuildContext in Flutter.
Chapter 4, State Management Patterns and Their Implementations, continues the topic of state management, introducing popular industry patterns such as MVVM and MVI, the rationale behind using them, and their implementation in Flutter with and without third-party libraries.
Chapter 5, Creating Consistent Navigation, provides an overview of navigation patterns in Flutter, going into details on how to implement imperative style navigation and declarative style navigation. We will see some examples of building complex navigation scenarios and when to choose which approach.
Chapter 6, The Responsible Repository Pattern, introduces the Repository pattern and its benefits for scalable app architecture. The chapter goes deep into implementation details and explores practices for building flexible data sources.
Chapter 7, Implementing the Inversion of Control Principle, explores various approaches to implementing the Inversion of Control principle, via practices such as dependency injection and the Service Locator pattern, and demonstrates their practical application with the help of different libraries.
Chapter 8, Ensuring Scalability and Maintainability with Layered Architecture, provides an overview of how to structure the code that we have built up to this point according to layered architecture principles. The chapter also highlights how we have been following the SOLID and other best software design principles all along.
Chapter 9, Mastering Concurrent Programming in Dart, introduces concepts related to concurrent programming in general and provides an overview of asynchronous APIs in Dart. The chapter goes into details of how to work efficiently with the Future APIs, as well as how to handle parallel operations with the Isolates API.
Chapter 10, A Bridge to the Native Side of Development, provides an overview of the Flutter app architecture from the perspective of the SDK and hosting platforms. The chapter goes into details of working with platform channels, a mechanism used to communicate with the host platform, as well as demonstrating the shortcomings of this API. We then explore a type-safe way to implement that communication via the pigeon code generation library.
Chapter 11, Unit Tests, Widget Tests, and Mocking Dependencies, provides an overview of the automated testing approaches in Flutter. You will learn how to write unit tests and go into the details of widget testing. The chapter showcases the mocking dependencies technique and how to implement it with the Mockito library.
Chapter 12, Static Code Analysis and Debugging Tools, discusses the topic of static analysis in Flutter and why it's important to establish coding conventions and follow them consistently. We then see how this can be automated by setting up a robust static analysis system. The chapter also explores debugging practices and their applications, such as logging, assertions, breakpoints, and Flutter DevTools.
To get the most out of this book
You will need to download an IDE that supports development with Flutter and Dart, and the Flutter SDK itself.
Software covered in the book
Operating system requirements
Flutter SDK 3.22.0+
Windows, macOS, Linux, or ChromeOS
Dart 3.4.0+
Windows, macOS, Linux, or ChromeOS
You may use any IDE of your choice, but some popular ones that support Flutter are Android Studio, VS Code, and IntelliJ IDEA. Up-to-date details for installation can always be viewed at the official website: https://docs.flutter.dev/get-started/install.
If you are using the digital version of this book, we advise you to type the code yourself or access the code from the book's GitHub repository (a link is available in the next section). Doing so will help you avoid any...