Skip to content

leossmith/conf_app_bad_structure_example

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Flutter: The Bad Structure Example

This is a conference app for Open Conf 2025 Flutter workshop

⚠️ Disclaimer: This is an Anti-Pattern

This project is intentionally structured poorly to serve as an educational example of what not to do in a Flutter application. It is designed to highlight common pitfalls that new developers might fall into and to demonstrate the importance of a well-organized project structure.

DO NOT use this project as a template for your own applications.

*** You can grab the "The Better Structure Example"


About The Project

This is a simple conference application that displays information about:

  • A home screen with event details
  • A list of speakers
  • The event agenda
  • Conference sponsors

The app fetches data from local JSON files and displays it in various screens.

Why is This a "Bad" Example?

As a project grows, its structure becomes crucial for maintainability, scalability, and collaboration. This project violates several best practices:

1. Flat Directory Structure

All Dart files (main.dart, home.dart, speakers.dart, agenda.dart, sponsors.dart, speaker.dart, etc.) are located directly inside the lib/ directory.

  • Problem: This is manageable for a handful of files, but as the app grows to 20, 50, or 100+ files, it becomes incredibly difficult to find what you're looking for.
  • Better Approach: Group files by feature (e.g., lib/speakers/, lib/agenda/) or by layer (e.g., lib/models/, lib/ui/screens/, lib/data/services/).

2. Mixing UI, Business Logic, and Data Fetching

Each screen file (e.g., speakers.dart) contains everything related to that feature:

  • The data model (Speaker class)

  • The UI widget (SpeakersPage)

  • The data fetching logic (_getSpeakers())

  • State management (setState)

  • Problem: This tight coupling makes the code hard to read, test, and reuse. If you wanted to fetch speakers in another part of the app, you would have to duplicate the code. Testing the data logic requires rendering the entire UI.

  • Better Approach: Separate these concerns into different layers. For example:

    • Data Layer: A services or repositories directory to handle fetching data from APIs or local sources.
    • Model Layer: A models directory for your data structures.
    • UI Layer: A ui or presentation directory for your widgets, separated into screens and reusable widgets.

3. No Scalable State Management

The app exclusively uses StatefulWidget and setState() to manage its state.

  • Problem: While setState() is fine for simple, local state (like a checkbox being ticked), it becomes cumbersome for managing app-wide or complex state. It requires passing data down the widget tree, leading to rebuilds of widgets that don't need to change.
  • Better Approach: Use a dedicated state management solution like Provider, BLoC, Riverpod, or others. These solutions provide a more robust and scalable way to manage and access your application's state.

4. Lack of Reusability

Styling and widgets are often duplicated. For example, the Card and ListTile styling in speakers.dart and agenda.dart could be extracted into reusable widgets.

  • Problem: Duplicated code is harder to maintain. If you need to change a color or font size, you have to find and update it in multiple places.
  • Better Approach: Identify repeating UI patterns and extract them into their own reusable widgets. For example, you could create a StyledCard or SpeakerListItem widget.

What Would a "Good" Structure Look Like?

A much better, layered architecture would look something like this: https://github.com/SimpleAppsgr/flutter_skeleton

About

This is a bad example of Flutter structure used in workshops for Organizing code

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published