mwwm 0.1.0

  • Readme
  • Changelog
  • Example
  • Installing
  • 73

#

Software architectural pattern for Flutter apps.

Description #

MWWM is based on principles of Clean Architecture and is a variation of MVVM.

It consists of three parts: Widget, WidgetModel and Model.

Widget — a representation layer that contains only UI related code.

WidgetModel - handles and accumulates all data needed for Widget: objects of the domain layer, scroll position, text fields values, animation state, etc. WidgetModel uses Model for interaction with various data sources.

Model - a link between WidgetModel and "the external world": data sources, services or other abstraction layers. It allows to develop both separately and have a possibility to modify one layer with no need for changing the other. Model is represented by two components: Change (a signal to model which means what we want to achieve) and Performer (that knows how to achieve it).

Why? #

This architecture completely separates design and logic. Adds the ability to work on independent layers by different developers. Adds autonomy to work, like HTML and CSS.

How to use #

Create a WidgetModel class by extending [WidgetModel].

class RepositorySearchWm extends WidgetModel {

  RepositorySearchWm(
    WidgetModelDependencies baseDependencies, //1
    Model model, //2
    ) : super(baseDependencies, model: model); //3

}

1 - WidgetModelDependencies is a bundle of required dependencies. Default there is ErrorHandler, which give possibility to place error handling logic in one place. You must provide an implementation of handler.

2 - Model is contract with service layer. For now, it is optional feature. It is possible to use services directly but not recommended.

3 - don't forgive about provide model to superclass if you wont to use Model.

Add Widget simply by creating StatefulWidget and replace parent class with CoreMwwmWidget

class RepositorySearchScreen extends CoreMwwmWidget {

  //...

  @override
  State<StatefulWidget> createState() {
    return _RepositorySearchScreenState();
  }
}

By convention create a same constructor:

  RepositorySearchScreen({
    WidgetModelBuilder wmBuilder, // need to testing
  }) : super(
          widgetModelBuilder: wmBuilder ??
              (ctx) => RepositorySearchWm(
                    // provide args,
                  ),
        );

Change parent of State of StatefulWidget to WidgetState:

class _RepositorySearchScreenState extends WidgetState<RepositorySearchWm>

All done! You create your presentation.

FAQ #

Where can I place UI? #

Simply in build method in WidgetState. No difference with Flutter framework.

How can I obtain a WM? #

WidgetState has WidgetModel after initState() called. There is a getter - wm - to get your WidgetModel in your Widget.

Where should I place navigation logic? #

Only in WidgetModel. But we don't hardcodea way to do this, yet.

Sercice(bussines) Layer #

It is optional paragraph. You can write connection with services your favorite way.

To work with business logic need to decribe a contract which consists of two parts: Change and Performer.

Change - is an intention to do something on service layer. Change can has data. Formally, it is an arguments of some function.

Performer<R, Change> - is a functional part of this contract. It is so close to UseCase. Performer, in ideal world, do only one thing. It is small part og logic which needed to perform Change.

We recomend following structure:

  • ./
    • data/
    • model/
      • services(repository)/
      • changes.dart // can split
      • performer.dart // can split
    • ui/
      • screen(widget)/
        • wm.dart
        • route.dart
        • screen(widget).dart

Feature RoadMap #

  • Coordinator - abstraction to place navigation logic
  • Code generation (may be)
  • Somthing else ? Create an issue with request to feature.

[0.1.0] - beta release

  • Update CoreMwwmWidget. Change API
  • Update docs

[0.0.4] - Add logo

[0.0.3] - Update docs

  • README update
  • fix some class docs

[0.0.2] - Released

  • Software architectural pattern for flutter apps.

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:mwwm/mwwm.dart';
import 'package:mwwm_github_client/model/database/database.dart';
import 'package:mwwm_github_client/model/repository/favorites_repository.dart';
import 'package:mwwm_github_client/model/repository/github_repository.dart';
import 'package:mwwm_github_client/ui/app.dart';
import 'package:mwwm_github_client/ui/common/error_handler.dart';
import 'package:provider/provider.dart';

void main() {
  runApp(
    Provider(
      create: (_) => Database(),
      child: MultiProvider(
        providers: [
          Provider(
            create: (_) => WidgetModelDependencies(
              errorHandler: DefaultErrorHadler(),
            ),
          ),
          Provider(
            create: (_) => GithubRepository(),
          ),
          Provider(
            create: (context) => FavoritesRepository(Database()),
          ),
        ],
        child: App(),
      ),
    ),
  );
}

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:


dependencies:
  mwwm: ^0.1.0

2. Install it

You can install packages from the command line:

with Flutter:


$ flutter pub get

Alternatively, your editor might support flutter pub get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:


import 'package:mwwm/mwwm.dart';
  
Popularity:
Describes how popular the package is relative to other packages. [more]
46
Health:
Code health derived from static analysis. [more]
99
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
100
Overall:
Weighted score of the above. [more]
73
Learn more about scoring.

We analyzed this package on May 23, 2020, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.8.1
  • pana: 0.13.8-dev
  • Flutter: 1.17.0

Health suggestions

Fix lib/src/model/changes/changes.dart. (-0.50 points)

Analysis of lib/src/model/changes/changes.dart reported 1 hint:

line 9 col 13: Avoid using braces in interpolation when not needed.

Fix lib/src/model/model.dart. (-0.50 points)

Analysis of lib/src/model/model.dart reported 1 hint:

line 22 col 29: The exception variable 'e' isn't used, so the 'catch' clause can be removed.

Format lib/mwwm.dart.

Run flutter format to format lib/mwwm.dart.

Format lib/src/model/performer/performer.dart.

Run flutter format to format lib/src/model/performer/performer.dart.

Format lib/src/widget_state.dart.

Run flutter format to format lib/src/widget_state.dart.

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.6.0 <3.0.0
flutter 0.0.0
Transitive dependencies
collection 1.14.12
meta 1.1.8
sky_engine 0.0.99
typed_data 1.1.6
vector_math 2.0.8
Dev dependencies
flutter_test
pedantic ^1.8.0+1