Senior-Project-CSE-3213 / sp_flutter_app

iOS/Android app built with Flutter using MVVM architecture
3 stars 1 forks source link

Design flaw with services #26

Closed JustinASmith closed 3 years ago

JustinASmith commented 4 years ago

Currently our services do not follow the architecture design. This was a mistake on my part 🤦‍♂️ ...

This is main.dart (entry point of our View)

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  runApp(MultiProvider(
      providers: [
        Provider<AuthService>(create: (_) => AuthService()),
      ],
      child: MaterialApp(initialRoute: eventMapScreenRoute, routes: {
        eventMapScreenRoute: (_) => Wrapper(child: EventMap()),
        profileScreenRoute: (_) => ProfileScreen(),
        helpScreenRoute: (_) => HelpScreen(),
        settingScreenRoute: (_) => SettingScreen(),
      })));
}

The services are being used directly in the View using a MultiProvider. This was done to establish a singleton instance of the service class and that is the right idea, but the services aren't supposed to be directly used in the UI (View). This needs to be refactored slightly to use the services in the ViewModels and the ViewModels can be in the MultiProvider or directly used in a widget/screen.

Here's a Solution

Take the service instance inside of the MutliProvider and move it to a ViewModel and use that ViewModel inside of the MultiPorivder (Would have to see this in code to see if this scales well).

One thing we will have to do is convert our service classes to be a true singleton by doing something like:

class Singleton {
  static final Singleton _singleton = Singleton._internal();

  factory Singleton() {
    return _singleton;
  }

  Singleton._internal();
}

so that we can still do (inside of ViewModel)

var s1 = Singleton();
var s2 = Singleton();
print(identical(s1, s2));  // true
print(s1 == s2);           // true

This approach would allow us to create an object like s1 and s2 inside of ViewModels to use our service. This takes away the tight coupling between View and Service.

Lastly, this brings a few things to mind. How will we listen for user being signed in and out like we are currently? Will we still have that ability through a ViewModel? To answer my own question, I would say yes. I just have to see what this looks like after a refactor.

JustinASmith commented 4 years ago

@ElijahBenMagee @Monterius @CalebDoucet @SamBoggs1337 @Schweinsei007 Can you guys read over this to see if this makes sense to you?

SamBoggs1337 commented 4 years ago

So to my understanding, this is simply restricting the instantiation to one single instance to be used, hence the definition of singleton? Or am I missing something?