Singleton pattern in Dart to make to make shared object - flutter

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.

Related

How to build Null Factory Constructors with Null Safety?

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.

Different field instances in class and parent/Call super constructor with method

I am trying to call the super constructor from a class using a method. The whole setup looks like this:
class Straight(hand: Hand) extends Combination(Straight.makeHandAceLowIfNeeded(hand), 5)
object Straight {
private def makeHandAceLowIfNeeded(hand: Hand): Hand = {
...
}
}
While this does compile, it has some rather odd runtime behaviour. While debugging, I noticed that the Straight instances have the "hand" property defined twice. Can somebody tell me what is going on, and what the proper way is to call the super constructor with different arguments?
In my use case, I want to call the super constructor with a modified hand in which I replaced a card compared to the original constructor argument.
Debugger screenshot with duplicate field:
.
It's a perfectly fine way to call the superclass constructor. These are two private fields and they don't conflict, though you can rename one of them to avoid confusion during debugging (or if you want to access the superclass' value from the subclass). However, the field should only be generated for a class parameter if it's used outside a constructor, and in your case it doesn't appear to be. Did you simplify the definition of Straight?

Constructor and Unit Testing

I have a class XmlRecord. This class will deal with reading/writing to an xml file. At the moment, I have the following for that class:
class XmlRecord {
private val _file = new File("file.xml")
}
I want this class to somehow create the file if it doesn't exist. I know how to achieve this but I'm unsure how to design it in an Object Orientated way. I think I have two options:
Do I add a code to the constructor (or a call to a private method) that will create this file automatically if it doesn't exist. My problem with this method is that how do I unit test this as this code is effectively private code? Would I have to inject the File dependency so it could be mocked during testing?
Do I get the constructor to return an exception or implement a public method for the class so that the caller can use it to check if a file needs to be created? If so, the caller would then call another public method that would create the file. Again I think I would need to inject the dependency.
I hope that makes sense. I'm just trying to get a better grasp on designing my classes.
The presence of abstractions to accomplish DIP have other design
implications in an Object Oriented program:
All member variables in a class must be interfaces or abstracts.
All concrete class packages must connect only through interface/abstract classes packages.
No class should derive from a concrete class.
No method should override an implemented method.[5]
All variable instantiation requires the implementation of a Creational pattern as the Factory Method or the Factory pattern, or the more complex use of a Dependency Injection framework.
Dependency inversion principle

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.

Error when inheriting from Ektron.Cms.Content.Targeting.Rules.RuleTemplate

I have a C# class called MyCustomRuleTemplate which is inherited from Ektron.Cms.Content.Targeting.Rules.RuleTemplate class. In that I have added a constructor such as below
public MyCustomRuleTemplate(): base("someKey")
{
//Some code here
}
Its working fine without any error. If I given it as
public MyCustomRuleTemplate()
{
//Some code here
}
Im getting error like 'Ektron.Cms.Content.Targeting.Rules.RuleTemplate' does not contain a constructor that takes 0 arguments.
Can anybody help me to know why it is?
The reason you are seeing "does not contain a constructor that takes 0 arguments" when instantiating your class object using the second constructor is because when you call your constructor, c# tries to call the constructor on the base class as well, which in this case takes a parameter.
See this post on msdn:
http://msdn.microsoft.com/en-us/library/ms173115%28v=vs.80%29.aspx
Key parts:
"In this example, the constructor for the base class is called before the block for the constructor is executed. The base keyword can be used with or without parameters. Any parameters to the constructor can be used as parameters to base, or as part of an expression. For more information, see base.
In a derived class, if a base-class constructor is not called explicitly using the base keyword, then the default constructor, if there is one, is called implicitly."
And: "If a base class does not offer a default constructor, the derived class must make an explicit call to a base constructor using base."