SOLID Principles for Kids: Flutter Edition?

Ahmed Taha ElElemy
2 min readAug 28, 2023

--

Hello, young coders! Today we’re going to learn about a big idea in programming called the SOLID principles. Don’t worry, it’s not as hard as it sounds! Imagine you’re building a LEGO castle. There are certain rules you follow, right? The same goes for coding. The SOLID principles are like our LEGO building rules for making our code neat, strong, and flexible.

There are five parts to SOLID, but today we’re going to focus on the last one, the ‘D’ which stands for Dependency Inversion Principle (DIP).

What is Dependency Inversion Principle?

Let’s imagine you have two LEGO blocks, a red one and a blue one. The red one always needs the blue one to do its job. This is called ‘dependency’. Now, if we change the blue block, we might affect the red block, right? That’s a problem! DIP helps us avoid this problem.

Understanding DIP with an example

Let’s think of a Flutter app as a big LEGO castle.

Imagine we have a part of our app that shows a list of your favorite toys. We have a ToyList class that fetches data from a ToyDatabase.

class ToyDatabase {
List<String> getToys() {
// Fetches the toy data...
return ['Teddy Bear', 'Doll', 'Car', 'Dinosaur'];
}
}
class ToyList {
final ToyDatabase database;
ToyList(this.database); void displayToys() {
final toys = database.getToys();
toys.forEach((toy) => print('Toy: $toy'));
}
}

Here, ToyList is like the red LEGO block and ToyDatabase is the blue one. ToyList depends on ToyDatabase. But, what if we want to change our database or get our toys from the Internet instead? We'd have to change ToyList and that could lead to bugs!

Using DIP to solve our problem

To use DIP, we make an ‘agreement’ or ‘contract’ that both ToyList and ToyDatabase can follow. This contract is an interface.

abstract class ToyProvider {
List<String> getToys();
}

Now, ToyDatabase can promise to follow this contract:

class ToyDatabase implements ToyProvider {
@override
List<String> getToys() {
// Fetches the toy data...
return ['Teddy Bear', 'Doll', 'Car', 'Dinosaur'];
}
}

And ToyList can depend on the contract instead of depending directly on ToyDatabase.

class ToyList {
final ToyProvider provider;
  ToyList(this.provider);  void displayToys() {
final toys = provider.getToys();
toys.forEach((toy) => print('Toy: $toy'));
}
}

Now, if we want to change where we get our toys from, we can create a new class that follows the ToyProvider contract and ToyList won't be affected!

DIP is like saying, “Hey, I don’t need to know where you get the toys from, just promise me you’ll give me a list of toys when I ask for it!”

Wrapping Up

Just like building a LEGO castle, coding is all about creating something amazing step by step. The SOLID principles, including DIP, are our building rules that help us create code that is strong and easy to change, just like a well-built LEGO castle.

Keep building, little coders!

--

--

Ahmed Taha ElElemy

Passionate Flutter dev & tech enthusiast. Collaborative problem-solver, eager to create innovative solutions. Let's code and build together!