How to enforce that a parameter is of the same static concrete type as the object? - dart

I have a Flutter app connected to a Firestore database. I have a hierarchy of objects, let's say for example with abstract base class Vehicle, with subclasses such as Car, Truck, etc. Objects of these types are stored in the database. Due to how Firestore works, it is better to make these classes immutable, i.e. to make them essentially represent a snapshot of the conceptual object instead of the mutable object itself.
When I want to update a Vehicle object in the database, I don't want users of Vehicle (i.e. other parts of my code) to have to specify the update as a dynamic map, e.g. vehicle.update({"speed": 42, "color": "red"}), because this disables static checking of field names and types. Instead, I thought that the best way would be to make the users create the new snapshot they want, e.g. car.setInDB(updatedCar). Behind the scenes this just calls .set() on the corresponding document reference in Firestore. Since the implementation would be the same on all subclasses of Vehicle, one could think of adding the method to Vehicle:
abstract class Vehicle {
Future<void> setInDB(Vehicle updated)
=> database.set(this.dbLocation, updated)
}
However, users of this method shouldn't be setting a vehicle of some concrete type with a vehicle of some other concrete type. I.e., a truck can only be updated with another truck snapshot, not a car snaphot. This is already enforced at runtime through Firestore rules, but I'd rather have this checked statically.
These options occur to me:
Use the covariant keyword and make subclasses override the setInDB method with the corresponding type.
abstract class Vehicle {
Future<void> setInDB(covariant Vehicle updated)
=> database.set(this.dbLocation, updated)
}
class Car extends Vehicle {
#override
Future<void> setInDB(Car updated)
=> super.setInDB(updated)
}
The problem with this is I might forget to override the method if I add a new subclass. Also, users could do vehicle.setInDB(otherVehicle), where vehicle has static type Vehicle, and the correctness of otherVehicle would be checked at runtime again.
Only add the setInDB method to concrete subclasses of Vehicle, with the correct type:
abstract class Vehicle {
}
class Car extends Vehicle {
Future<void> setInDB(Car updated)
=> database.set(this.dbLocation, updated)
}
class Truck extends Vehicle {
Future<void> setInDB(Truck updated)
=> database.set(this.dbLocation, updated)
}
Etc. The problem with this approach is the code duplication, since the implementation is the same everywhere.
Are there other options?

Dart 2.19 adds analyzer support for a #mustBeOverridden annotation that you can add to a base class method. The analyzer then will emit a warning if a derived class neglects to override it. (However, as of writing, a new version of package:meta has not been published yet to add that annotation, but presumably it will be published soon.) For more details, see https://github.com/dart-lang/sdk/issues/30175.
Borrow the curiously recurring template pattern from C++ and apply it to Dart generics by making your derived classes extend (or mixin) a generic base class that is parameterized on the derived class. For example, I think that you could do:
abstract class Vehicle<DerivedVehicle extends Vehicle<DerivedVehicle>> {
Future<void> setInDB(DerivedVehicle updated)
=> database.set(this.dbLocation, updated)
}
class Car extends Vehicle<Car> {
}
class Truck extends Vehicle<Truck> {
}
and now Car().setInDB() should require a Car argument, and Truck().setInDB() should expect a Truck.

Related

How can I require that a class has fromJson in Dart? [duplicate]

Say I have the abstract class A
abstract class A {
A.someConstructor(Foo foo);
}
and all subclasses of A should then implement such constructor:
class B extends A {
#override
B.someConstructor(Foo foo) {
// ...
}
}
So basically what I want is some kind of abstract constructors.
Is there any way of achieving this (of course the above code does not work) or do I need a normal abstract method which then creates the object and sets its properties?
EDIT: Ok so it looks like the only way to create at least a similar behaviour would be something like this:
abstract class A {
A.someConstructor(Object foo);
}
class B extends A {
B.someConstructor(Object foo) : super.someConstructor(foo) {
// ...
}
}
This isn't exactly useful, and after some thinking about my problem I realized that in fact my original goal itself is not really neccessary, so this questions is now answered.
You want to enforce a pattern on the constructors of subclasses. The Dart language has no support for doing that.
Dart has types and interfaces which can be used to restrict values and class instance members.
If a class implements an interface, then its instance members must satisfy the signatures declared by the super-interface. This restricts instance members.
If a variable has a type, for example a function type, then you can only assign values of that type to it. This restricts values. Because a class is a subtype of its interfaces, the subclass restriction means that class typed variables can be used safely (the subtype can be used as its supertype because it has a compatible interface).
There is no way to restrict static members or constructors of classes, or members of libraries, because there is no way to abstract over them. You always have to refer directly to them by their precise name, so there is no need for them to match a particular pattern.
(Which may explain why you found the goal not necessary too).
In this situation, your subclasses must call the A.someConstructor constructor, but they are free to choose the signature of their own constructors. They can do:
class B extends A {
B.someConstructor(Object foo) : super.someConstructor(foo);
}
// or
class C extends A {
C.differentName(Object foo) : super.someConstructor(foo);
}
// or even
class D extends A {
D() : super.someConstructor(new Object());
}
Constructors aren’t inherited
Subclasses don’t inherit constructors from their superclass. A
subclass that declares no constructors has only the default (no
argument, no name) constructor.
Source

Dart - Hide method from parent class / call private method from parent class

I have a class that extends another. The parent class is not intended to be used directly by the API rather it implements basic methods that are helpers for child classes.
When I use the child class in a program I can see all method from said class but also the one from the parent class that are not intended to be called directly, they exist to be called by the methods of the child class.
I tried to make parents method private. This would work I believe as long as parent and child are declared in the same library. But I have an issue with the "library" notion. I understand part/part of are somewhat depreciated, and I want the parent class to be in a specific file. I can't figure a way to do it with import/export.
Is there a way to either hide a public method from the parent class from all child classes usage or to make a private method from the parent class callable from all child classes ?
Best regards ;
Exemple:
myLib.dart
export mainClass.dart;
mainClass.dar
import baseClass.dart;
class MainClass extends BaseClass {
publicFunc() => ... //Can't call _hiddenFunc, can call wantToHideFunc()
}
In a second file (for code reusability purposes)
class MainClass extends BaseClass {
_hiddenFunc() => ...
wantToHideFunc() => ...
}
Using myLib public API
import myLib.dart
main() {
class = Class();
class.publicFunc(); //Intended
class.wantToHideFunc() //Wants to avoid...
}
Dart does not have protected access like Java or C#.
You can't hide a public member, you can't access a private member from a different library, and there is no third option.
It sounds like you want members of the superclass which can be invoked only from subclasses, not from outside of the object. That's what's called protected in, e.g., Java, and Dart does not have anything similar to that.
The only level of privacy in Dart is library-private, which is chosen by starting the name with a _.
The reason that Dart has this design is that it was originally a very dynamic language. You can preform "dynamic invocations" on a value with static type dynamic, say dynVal.foo(42) and it will call the method of that name.
To make a name unreachable, it needed to be safe from dynamic invocation as well. Because of that, Dart privacy does not care where the code doing the invocation is, it only cares whether you know the name - and library private names are considered different names depending on which library they're from.
Using part is not discouraged for situations where it actually serves a purpose. If you can put the part into a library of its own, that's better because it allows it to have its own privacy and imports, but if you need the classes to share privacy, using part files to split up a large file is perfectly reasonable. It's a tool, there is nothing wrong with using it when it's the right tool for the job. A library is often a better tool for modularity, but not always.
Now, there is a hack you can use:
// Declare the base and provide extensions for "protected" members:
abstract class Base {
int get _someHiddenStuff => 42;
int get somePublicStuff => 37;
}
extension ProtectedBase on Base {
int get someHiddenStuff => _someHiddenStuff;
}
Then import that in another library and do:
import "base.dart";
export "base.dart" hide ProtectedBase;
class SubClass extends Base {
int doSomething => someHiddenStuff + somePublicStuff;
}
Then anyone importing "subclass.dart" will also get a version of Base, but they won't get the ProtectedBase extensions. Hiding the extensions from your package's public API will allow yourself to use it, but prevent your package's users from seeing the helper extensions.
(This is likely highly over-engineered, but it's an option. It's the evolution of the hack of having static/top-level helper functions that you don't export.)

How to implement a general class for singleton?

I've been trying to implement a state management project for my design patterns course. I have implemented the singleton because I know that's essential for keeping state of a class. What I would like to do is: Create a general class, so that others could use it in their projects. How do I do that? My code so far:
class StateManager{
static final StateManager _instance = StateManager._singleton();
StateManager._singleton();
factory StateManager(){
return _instance;
}
}
My other solution to try and make it general:
class AppProvider extends StateManager<AppProvider>{
int i = 10;
String data = "adas";
}
class StateManager<T extends AppProvider>{
static final StateManager _instance = StateManager._singleton();
StateManager._singleton();
factory StateManager(){
return _instance;
}
}
I want the AppProvider class to be the client class, and I want the StateManager to automatically handle the fact that AppProvider should be a singleton, and maintain the state of AppProvider.. I really don't know how to do that.
Forcing a class to be a singleton through inheritance alone is not going to work. That's not something that the language supports. Constructors are not inherited, neither are static members, and you need those to access the singleton.
In order to be able to create an instance of a class at all, the class needs a generative constructor.
That generative constructor will create a new instance every time it's invoked, because that's what generative constructors do.
For a subclass to be able to extend a class, the superclass must have an accessible generative constructor too, but at least the superclass can be made abstract.
In order to force a class to be a singleton (if you really want that, because a singleton is really something of an anti-pattern; it makes the class act like it's just a bunch of global variables, and that makes testing harder), each such class needs to have a public static way to access or create the instance, and a private generative constructor.
So, basically, your first approach does what is needed, and since the constructors are not inherited, you need to do that for every singleton class, and there is nothing useful to inherit.
So, there is nothing you can do with inheritance to make singleton-ness be inherited, and you can't even help because everything a singleton needs is static.
A different approach is to make the state classes entirely private, so you don't have to worry about someone else creating instances, and give them a constant generative constructor each, and then only refer to them using const _ThisState() or const _ThatState().
This puts the responsibility on the user (you!) to only create one instance of each state object, but it also gives a very easy way to do that, because const _ThisState() will provide the same instance every time.
Or use the enum pattern, and have:
abstract class State {
static const State thisState = const _ThisState();
static const State thatState = const _ThatState();
const State._();
void handle(Context context, Object argument);
}
class _ThisState implements State {
const _ThisState();
void handle(Context context, Object argument) { ... }
}
class _ThatState implements State {
const _ThatState();
void handle(Context context, Object argument) { ... }
}
and then just refer to the state instances as State.thisState. I find that more readable than creating instances of seemingly unrelated classes.

Getting Item_$$_javassist_165 from ins.getClass().getSimpleName()

I've three classes that implement the composite patter, Item, Cluster and Element.
class Item extends Locatable {
...
}
class Cluster extends Item {
static hasMany = [items:Item]
...
}
class Element extends Item {
...
}
My domain model is more complex than this, but it's just an example.
When I have an instance of Item and I want to know if it is a Cluster or a Element with ins.getClass().getSimpleName() I'm getting a weird class name: Item_$$_javassist_165, if I do a println ins.toString() I get the correct class name printed (the toString method returns this.getClass().getSimpleName()).
how to get the correct class name? What is this "Item_$$_javassist_165" class name?
What is this "Item_$$_javassist_165" class name?
It means that the object you have is a Hibernate lazy-loading proxy. The first time you try and access anything other than the id of that object, Hibernate will go to the database and load the real data, then delegate any future method calls to the real object.
The obvious approach of ins instanceof Cluster may not work correctly in the presence of proxies when you have one domain class that extends another, but GORM provides an injected instanceOf method that does what you need and will handle proxies correctly.
if(ins.instanceOf(Cluster)) { .... }
You can use GrailsHibernateUtil.unwrapIfProxy(object) to receive the original object instance from a proxy object. After unwrapping you should be able to get the real class name with getClass().getSimpleName(). Be aware that you loose features like lazy loading on the unwrapped object.
I find a method that give the real name:
org.hibernate.Hibernate.getClass(ins).getSimpleName()

Flash / ActionScript - application design question

Could someone share the way how this should be designed:
Let's say I have some data model, which is built using Entries.
Basically, I have one abstract class Entry (or interface IEntry - that's not so important for the case) and have several implementations of this class - MovieEntry, SoundEntry, FoodEntry, whatever...
Each of those is a wrapper for some data (url, description, number of calories, etc) and this data is grouped together in each corresponding class.
Now - if I wish to display the data for the entries on the screen (let's say movie posters and annotations for the MovieEntry) - how should I design that?
Obviously I could provide another interface / abstract class and call it DrawableEntry (and it would inherit Sprite) and then build a bunch of classes like DrawableMovieEntry and DrawableSoundEntry which could look like:
class DrawableMovieEntry extends DrawableEntry { // which also extends 'Sprite'
private movieEntry:MovieEntry;
public override function draw(backend:*) {
// Draw everything using the 'movieEntry' reference
// stored.
};
But this seems to be kind of an overkill for a small application.
Another approach is to make the MovieEntry, SoundEntry, ... extend sprite and provide the drawing implementations themselves - but this is obviously bad, because data becomes strongly coupled with it's visualization routines.
So - how should this be done? Maybe MVC approach has something to offer for this case?
Your use case seems to be the perfect example for the Strategy pattern or the Command pattern.
Strategy being the simpler one, here is an example:
Create an IDrawStrategy interface like this:
package {
public interface IDrawStrategy {
function draw( obj:Object ) : void;
}
}
Implement several DrawStrategies:
package {
public class SoundEntryDrawStrategy implements IDrawStrategy {
public function draw (obj:Object) : void {
// cast obj to SoundEntry and do all the drawing necessary,
// or fail if obj is null or not a SoundEntry
}
}
}
package {
public class MovieEntryDrawStrategy implements IDrawStrategy {
public function draw (obj:Object) : void {
// cast obj to MovieEntry and do all the drawing necessary
// or fail if obj is null or not a MovieEntry
}
}
}
etc.
Then add a new member to your base Entry class:
private var _drawStrategy:IDrawStrategy;
and create a setter:
public function set drawStrategy ( strat:IDrawStrategy ) : void {
_drawStrategy = strat;
}
and a draw method:
public function draw () : void {
_drawStrategy.draw( this );
}
You can now assign and execute the fitting strategies to each of your entries:
var mov:MovieEntry = new MovieEntry();
mov.drawStrategy = new MovieEntryDrawStrategy();
mov.draw();
BTW the Sprite you draw the information in can, but doesn't have to, be a member of the DrawStrategy class, but if you wanted to add a clear() method later, it would be better to keep a reference ;).
The entries you build your data model with are, among others, referred to as value objects (VO) or data value objects (DVO). To answer your last question first, I'd never have a VO extend something other than a base VO class, so don't extend Sprite, you'll regret it later.
Over to the hierarchy. You're extending the abstract class Entry to create concrete subclasses, but since you also mention a possible interface, I'm not sure you should use extend. Only use a common base class if your value objects actually share common properties. If every entry has a title property, fine, put that one in Entry and subclass it. If your abstract would be empty, I'd recommend using a marker (=empty) interface instead.
I have a common marker interface for value objects, that have more specific subinterfaces to add features like xml parsing or composition. Once you start using interfaces for this, it's easy to enhance.
Then the displaying. There's not one right answer to this one, the more because your example is still pretty broad. But I'd pass the VO to the object as a whole, through a method that states that it's going to store the VO and redraw itself.
interface IEntryDisplay {
redrawWithEntry(entry:IEntry):void;
}
Use the IEntry interface to pass the object as a whole. In your implementation, use an if cascade with is Type conditions to do the drawing.
public function redrawWithEntry(entry:IEntry):void {
this.entry = entry;
if (entry is MovieEntry) {
title.text = MovieEntry(entry).title;
} else if (entry is SoundEntry) {
title.text = "(Sound) "+SoundEntry(entry).fileName;
}
}
If you decide to use a base class for the Entry hierarchy, use that one instead of the interface. You want your methods asking for the value object type that is as close to the needed object as neccessary.
Because you store the entry in your display class, it's easy to pass along some time later when you click the display or when you want to have it do something else.
Does this help?

Resources