Best way to shrink service class to smaller pieces - flutter

Currently making a large app with Flutter and I m stuck on the architecture of service class. There is a service class for the firestore CRUD operations.This class has many methods and I want split it into small pieces. I use an abstract class to protect methods.I find a way with mixins but don't know it's a good one or not.
https://gist.github.com/pMertDogan/fcd301d768f3980a898cec33a9acaa4f.
//Extend CRUDSERVICE rules aka abstract class => Test
mixin Update{
void updateSomething();
}
mixin Read{
void readSomething();
}
//BASE class for CRUDSERVICE
abstract class Test with Update,Read{
doSomeCreateOP(String x);
}
//
class CrudService extends Test with UpdateService , ReadService{
#override
doSomeCreateOP(String x) {
print('crated ' + x);
}
}
mixin UpdateService{
// #override
void updateSomething() {
print('updated');
}
}
mixin ReadService{
// #override
void readSomething() {
print('read');
}
}
void main() {
CrudService croudService = CrudService();
croudService.doSomeCreateOP(' dartSide');
croudService.updateSomething();
croudService.readSomething();
}
CreateService and UpdateService mixins are just sample.I am thinking like if I need update user information all methods are handed by UserServiceMix mixin if it's Friend then its hanled by FriendServiceMix so I can split them like a domain-based.Each mixin is responsible for specific operations.I can manage then on independent files and summary of them with the help of mixin.
Is it good way to go?

I believe it is a good way to go. It is a quite flexible approach. We use it for API versioning as well.
abstract class Service {
void method1();
void method2();
}
mixin Method1V1 {
void method1() {
print("method1");
}
}
mixin Method2V1 {
void method2() {
print("method2");
}
}
mixin Method2V2 {
void method2() {
print("method2 with changed logic");
}
}
class ServiceV1 extends Service with Method1V1, Method2V1 {
}
class ServiceV2 extends Service with Method1V1, Method2V2 {
}
void main() {
final version = 2;
final Service service = version == 1 ? ServiceV1() : ServiceV2();
service.method2();
}

Related

using "mixin" to factor out code to different files

I am trying to factor out some code(inspired from this)
part "game.dart":
part 'taps.dart';
class MyGame extends FlameGame with HasTappables {}
Trying to factor out to this file "taps.dart":
part of 'game.dart';
mixin Taps on MyGame {
#override
void onTapDown(int pointerId, TapDownInfo info) {
super.onTapDown(pointerId, info);
}
Problem is that "onTapDown" is not called?
Update:
This will not work:
class MainClass with OneMixin {
void test(){
helloOne();
}
}
mixin OneMixin on MainClass {
void helloOne() {
test();
}
}
Something like this would work:
abstract class FlameGame {
int? a;
}
class MyGame extends FlameGame with Taps {
int? b;
}
mixin Taps on FlameGame {
void method() {
print(a); // Possible
print(b); // Not possible
print((this as MyGame).b); // possible but unsave
}
}

How to override a Dart method on instantiation? [duplicate]

Is there way to overriding method in Dart like JAVA, for example:
public class A {
public void handleLoad() {
}
}
And when overriding:
A a = new A() {
#Override
public void handleLoad() {
// do some code
}
};
No, Dart does not have anonymous classes. You have to create a class that extends A and instantiate it.
No but it much less useful in Dart because you can just reassign function:
typedef void PrintMsg(msg);
class Printer {
PrintMsg foo = (m) => print(m);
}
main() {
Printer p = new Printer()
..foo('Hello') // Hello
..foo = ((String msg) => print(msg.toUpperCase()))
..foo('Hello'); //HELLO
}
However you will need some extra boilerplate to access instance.
Use type Function:
class A {
final Function h
A(this.h);
void handleLoad(String loadResult) { h(loadResult); }
}
Or
class A {
final Function handleLoad;
A(this.handleLoad);
}
A a = new A((String loadResult){
//do smth.
});

Dart & flutter : How can I pass an implementation of an abstract class to the constructor of another class? [duplicate]

Lets say that I have an abstract class
abstract class OnClickHandler {
void doA();
void doB();
}
I have a class
class MyClass {
OnClickHandler onClickHandler;
MyClass({
this.onClickHandler
})
void someFunction() {
onClickHandler.doA();
}
}
And I have a class
class Main implements onClickHandler {
// This throws me an error
MyClass _myClass = MyClass(onClickHandler = this); // <- Invalid reference to 'this' expression
#override
void doA() {}
#override
void doB() {}
}
How can I say that use the same implementations that the Main class has? or is there an easier/better way to do this?
Your problem is that this does not yet exists since the object are still being created. The construction of Dart objects is done in two phases which can be difficult to understand.
If you change you program to the following it will work:
abstract class OnClickHandler {
void doA();
void doB();
}
class MyClass {
OnClickHandler onClickHandler;
MyClass({this.onClickHandler});
void someFunction() {
onClickHandler.doA();
}
}
class Main implements OnClickHandler {
MyClass _myClass;
Main() {
_myClass = MyClass(onClickHandler: this);
}
#override
void doA() {}
#override
void doB() {}
}
The reason is that code running inside { } in the constructor are executed after the object itself has been created but before the object has been returned from the constructor.

What is the best way to mock 3rd party library's static method with Mockito in flutter

The approach I am following now is creating a wrapper around the class providing the static method, and then mocking this wrapper instead of mocking the real class, as in:
class TestClass {
final ThirdPartyClassWrapper _thirdPartyClassWrapper;
TestClass(this._thirdPartyClassWrapper);
void someMethod() {
_thirdPartyClassWrapper.doSomething();
}
}
class ThirdPartyClass {
static void doSomething() {}
}
class ThirdPartyClassWrapper {
void doSomething() {
ThirdPartyClass.doSomething();
}
}
//now I can mock the class and control the behaviour of the method
//but there is alot of boilerplate code
class MockThirdPartyClassWrapper extends Mock implements ThirdPartyClassWrapper{}
But as you see a lot of boilerplate is introduced.
So is there a better way to solve the problem?

Flutter, Dart. Create anonymous class

Maybe it's really dumb question. But I cannot believe there is no resources, where it's described. Even from the official documentation. What I'm trying to do, it's create Anonymous class for the next function.
How to create Anonymous class in Dart with custom function something like next in Kotlin?
Handler(Looper.getMainLooper()).post(Runnable() {
#override
open fun run() {
//...
}
private fun local() {
//....
}
})
Dart does not support creating an anonymous class.
What you're trying to do is not possible.
On the other hand, you can create anonymous functions. So you could use that to mimic an anonymous class.
The idea is to add a constructor of your abstract class, that defer its implementation to callbacks.
abstract class Event {
void run();
}
class _AnonymousEvent implements Event {
_AnonymousEvent({void run()}): _run = run;
final void Function() _run;
#override
void run() => _run();
}
Event createAnonymousEvent() {
return _AnonymousEvent(
run: () => print('run'),
);
}
It's not strictly the same as an anonymous class and is closer to the decorator pattern. But it should cover most use-cases.
This is an alternative way, but not fully equivalent:
Problem, e.g.:
I would like to implement OnChildClickListener inline in my code without class. For this method:
void setOnChildClickListener(OnChildClickListener listener) {
...
}
Instead of this:
abstract class OnChildClickListener {
bool onChildClick(int groupPosition, int childPosition);
}
use this:
typedef OnChildClickListener = Function(int groupPosition, int childPosition);
And in code you can implement it in this way:
listView.setOnChildClickListener((int groupPosition, int childPosition) {
// your code here
});
In other words do not use abstract class, but use typedef.