How to build Null Factory Constructors with Null Safety? - flutter

A common Dart pattern before null safety for creating static method holder classes was the following:
class MyMethodScope {
/// Prevents instantiation of this class.
factory MyMethodScope._() => null;
static void noop() {}
}
This is not possible with null safety because the return type of a factory constructor is not nullable apparently.

Based on https://github.com/dart-lang/language/issues/604, it looks expected that factory constructors can no longer return null, so you can't do it.
You alternatively could just use a private constructor (whether factory or not) that returns a non-null object. That would still prevent the class from being instantiated outside of the library. (Of course, it wouldn't prevent the class from being instantiated within the library, but you could just avoid doing that since you control your own library. You could move the class into a separate library if you're still concerned about accidental instantiation.)
Or just declare the class as abstract, which is the normal and direct way to prevent a class from being instantiated.
Besides, Effective Dart says to avoid such classes.

Related

Singleton pattern in Dart to make to make shared object

What does this code do? There is no such function _sharedInstance(), at least I didn't find it. Why the code line LoadingScreen._sharedInstance(); used again to define _shared ? Why to use factory there? I.e. this code seems incomprehensible...
class LoadingScreen {
LoadingScreen._sharedInstance();
static final LoadingScreen _shared = LoadingScreen._sharedInstance();
factory LoadingScreen.instance() => _shared;
...
This is a Singleton pattern.
_sharedInstance() is just a private named constructor for LoadingScreen, after defining it the class no longer has a default constructor. You can name it anything and it will be private as long as it starts with _. Check out Named Constructors.
_shared is used to hold the only instance of LoadingScreen, and it gets it's value from invoking the _sharedInstance() private named constructor.
If you call LoadingScreen.instance() in your code, you will always get the same object that is stored in _shared. Check out Factory Constructors.
This is a way to build Singleton. Thanks to Dart's factory constructors, it's easy to build a singleton:
I suggest it needs a couple of points of explanation. There's the weird syntax LoadingScreen. _sharedInstance() that looks like a method call bu actually it's really a constructor definition. There's the _sharedInstance name. And there's the nifty language design point that Dart lets you start out using an ordinary constructor and then if needed, change it to a factory method without changing all the callers.

how to write a meaningful test for `extending a class`?

what is the correct way to write a meaningful test for extending a class with the super keyword?
class FooBase<T> {
final T data;
const FooBase(this.data);
}
class Foo<T> extends FooBase<T> {
const Foo(T data)
: super(data);
}
I suppose super(data) ist passing the constructor parameter to the constructor of the base class (I do not know a lot about dart).
You can only test if super was called by observing its behavior. You have to check the base classes constructor for what it is doing with the parameter and then see if you can observe if that happened (if possible). Example: If the base class constructor is assigning the parameter to a field that you can access from the outside, you can assert on that parameter being set. This only works if
You can access the field from your test code. Access in this context does not mean to access it directly or via a getter. Any means of observing that the field has been set should be sufficient.
The class under test is not setting the field itself (there is probably no way to decide which constructor set the field).

Why should we use the 'override' key word in Kotlin for abstact class members?

If the base class has an abstract method or property, than these members must be overriden in the child class. The documentation says that i must use key word 'override' every time for such members, because i must implement methods or initialize properties in the child class. For example:
abstract class Dwelling {
abstract val buildingMaterial: String
abstract fun hasRoom() : Boolean
}
class RoundHut : Dwelling() {
override val buildingMaterial = "Stone"
override fun hasRoom() : Boolean {
return true
}
}
If an abstract method and a property must be overriden and implemented in child class any way (and compiler know this), than why we should write 'override' key word every time?
When you find yourself reading and understanding the implementing class, you have the explicit information that you're currently investigating an overridden one as it's explicitly marked as such. Kotlin likes to make things explicit and the documentation states
[...] we stick to making things explicit in Kotlin. So, Kotlin requires explicit modifiers for overridable members (we call them open) and for overrides
Java has an #Override annotation that is optional and not used by everyone although it has been considered a best practice (even as per Effective Java). Kotlin goes one step further by making it a compiler-enforced requirement.

Can one declare a static method within an abstract class, in Dart?

In an abstract class, I wish to define static methods, but I'm having problems.
In this simple example
abstract class Main {
static String get name;
bool use( Element el );
}
class Sub extends Main {
static String get name => 'testme';
bool use( Element el ) => (el is Element);
}
I receive the error:
function body expected for method 'get:name' static String get name;
Is there a typo in the declaration, or are static methods incompatible with abstract classes?
Dart doesn't inherit static methods to derived classes. So it makes no sense to create abstract static methods (without implementation).
If you want a static method in class Main you have to fully define it there and always call it like Main.name
== EDIT ==
I'm sure I read or heard some arguments from Gilad Bracha about it but can't find it now.
This behaviour is IMHO common mostly in statically typed languages (I don't know many dynamic languages). A static method is like a top level function where the class name just acts as a namespace. A static method has nothing to do with an instantiated object so inheritance is not applicable. In languages where static methods are 'inherited' this is just syntactic sugar. Dart likes to be more explicit here and to avoid confusion between instance methods and static methods (which actually are not methods but just functions because they don't act on an instance). This is not my primary domain, but hopefully may make some sense anyways ;-)
Looks like you are trying to 'override' a static method. I'm not sure what you are trying to achieve there. I'm not aware of any OO languages that support that (and not sure how they could).
A similar question in Java might help clarify Polymorphism and Static Methods
Note also that it is considered bad practice to refer to statics from an instance of the class in Java (and other OO languages). Interestingly I noticed Dart does not let you do this so is in effect removing this bad practice entirely.
So you couldn't even fool yourself into thinking it would behave polymorphically in Dart because you can't call the static from the instance.

Injecting with Gin into instance created by GWT.create

I have a custom deferred binder (rebind implementation) that instantiates objects. I would like to have some dependencies (#Inject annotated setter methods) within the instance returned by GWT.create() fulfilled by GIN. Is this possible?
So, given code such as:
Foo foo = GWT.create(Foo.class);
if foo's final implementation has:
#Inject
public void setBar(Bar bar) {
...
}
how do I get bar injected into the returned foo instance automatically by GIN?
Your Ginjector can have methods added to it for the purpose of injecting objects created in some other way. These must take one argument, and should specify the most specific type possible. For example, if MyViewImpl extends BaseView, and both types have dependencies to inject, but you declare
void injectBaseView(BaseView view);
in your ginjector, only the fields/setters declared on BaseView will be dealt with.
EDIT: Also, if no binding is declared, GWT.create will be used to create an instance, so you can have your cake and eat it to. One exception to that as far as I can recall, is when you want to GWT.create one type, but return another (see RPC interfaces for an example).