CodeBlanks Logo Icon CodeBlanks

Project design

Design the skeleton of the advanced final mini app.

Project design and the Task model

In this project we will build a small task API. First we define the Task model: id and title fields. With final we make the fields immutable; with required we make them mandatory in the constructor.

Then we write the abstract class TaskService interface; it declares the List<Task> list() method. The interface is the contract that concrete classes implement. This way in-memory, database or fake services can be swapped through the same interface. This is the basis of dependency injection and makes the code testable.

InMemoryTaskService

InMemoryTaskService is the in-memory service that implements the TaskService interface. It is declared with implements TaskService. The list() method returns a fixed list of tasks.

Example: class InMemoryTaskService implements TaskService { @override List<Task> list() => [Task(id: 1, title: 'task 1')]; }. @override says the interface method is overridden. This service is used for fast tests; the data is not persistent. In the next lessons we will add database and isolate based services to the same interface; the main code will keep working unchanged.

Practice Task model and service

Write the Task class: final int id and final String title fields, a Task({required this.id, required this.title}) constructor. Write abstract class TaskService declaring List<Task> list(). Write InMemoryTaskService implements TaskService with @override List<Task> list() => [Task(id: 1, title: 'task 1')]. In main add final svc = InMemoryTaskService(); and print('Design: ${svc.list().length} task').

Starter code

main.dart
// write the Task class (id, title)
// write abstract TaskService and InMemoryTaskService

void main() {
  // print the task count
}

Sample solution

main.dart
class Task {
  final int id;
  final String title;
  Task({required this.id, required this.title});
}

abstract class TaskService {
  List<Task> list();
}

class InMemoryTaskService implements TaskService {
  @override
  List<Task> list() => [Task(id: 1, title: 'task 1')];
}

void main() {
  final svc = InMemoryTaskService();
  print('Design: ${svc.list().length} task');
}

Expected output

Design: 1 task

Questions and answers

Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.

1 What does TaskService define?

  • Database
  • HTTP client
  • Service interface Correct answer
  • DOM

Explanation: TaskService defines a service interface (contract).

2 The implements interface

Question
class InMemoryTaskService implements ____ { @override List<Task> list() => []; }
Answer
class InMemoryTaskService implements TaskService { @override List<Task> list() => []; }

Explanation: InMemoryTaskService implements the TaskService interface.

3 Match the project parts

Term Meaning
Task Model
TaskService Interface
InMemoryTaskService Implementation
list List method

All lessons in Advanced