Dartlero – a simple domain model framework

We will now discuss Dartlero to get an idea of what a domain model framework is all about and how you can build upon it. Dartlero is a limited model framework used in teaching and learning basic data structures in Dart. Get your copy of Dartlero from Pub or from GitHub with the following command:

git clone git://github.com/dzenanr/dartlero.git 

Open the dartlero folder in your Dart Editor. Dartlero's code sits in the lib folder and the library file dartlero.dart, referencing three part files in the model subdirectory (lines (3) to (5)):

library dartlero;
import 'package:unittest/unittest.dart';

part 'model/concept_model.dart';                              (3)
part 'model/concept_entities.dart';                           (4)
part 'model/concept_errors.dart';                             (5)

Dartlero is just a library; it cannot be started by itself. We see that the central concepts are entities and models, and it builds heavily on the built-in List and Map classes. The code is quite abstract but it is instructive to dig into it (use the editor to see the code in its entirety). In the concept_entities.dart file, the abstract class ConceptEntityApi is defined. It describes the properties and methods of an entity in this framework. We see that an entity has only one property named code (with get and set), and there are abstract methods to create (newEntity), to copy, and to transform an entity into a map (toJson) and vice versa (fromJson).

abstract class ConceptEntityApi<T extends ConceptEntityApi<T>>
    implements Comparable {

  String get code;
  set code(String code);
  ConceptEntityApi<T> newEntity();                             (1)
  T copy();
  Map<String, Object> toJson();                                (2)
  void fromJson(Map<String, Object> entityMap);                (3)
}

The newEntity method (line (1)) is used to provide a specific object within the generic code of the ConceptEntity class. The toJson and fromJson methods (lines (2) and (3)) provide the export and import of entities, which will be used in the saving and loading of data.

This class is implemented by ConceptEntity, which also contains methods to display an entity and compare two entities. Although all methods contain code, this class is meant as an interface to be implemented by concrete entity classes (that's why it is called ConceptEntity):

abstract class ConceptEntity<T extends ConceptEntity<T>>
    implements ConceptEntityApi {
    // code left out
}

The abstract class ConceptEntitiesApi defines a number of properties and methods, such as length, forEach, add, toList, and toJson, for a collection of entities; in fact, it contains a list and a map of entities:

abstract class ConceptEntitiesApi<T extends ConceptEntityApi<T>> {
  int get length;
  bool get isEmpty;
  Iterator<T> get iterator;
  ConceptEntitiesApi<T> newEntities();
  ConceptEntityApi<T> newEntity();
  void forEach(Function f);
// other code left out
}

Again, this class is implemented by the class ConceptEntities:

abstract class ConceptEntities<T extends ConceptEntity<T>>
    implements ConceptEntitiesApi {
    // code left out
}

All of the above classes are defined for a generic type T, for example:

abstract class ConceptEntity<T extends ConceptEntity<T>>

When the framework is applied in a concrete domain, T is replaced by a concrete type. This type has to be a child class of ConceptEntity<T>. This will become clearer when we discuss the example in the next section.

In the concept_model.dart file, an abstract class ConceptModelApi is defined, which is implemented by ConceptModel. This is essentially a map connecting names to ConceptEntities:

abstract class ConceptModelApi {
  Map<String, ConceptEntitiesApi> newEntries();
  ConceptEntitiesApi getEntry(String entryConcept);
}
abstract class ConceptModel implements ConceptModelApi {
  Map<String, ConceptEntities> _entryMap;
  ConceptModel() {
    _entryMap = newEntries();
}

  ConceptEntities getEntry(String entryConcept) => _entryMap[entryConcept];
}

The third file concept_errors.dart defines some specific Error classes:

class DartleroError implements Error {
  final String msg;
  DartleroError(this.msg);
  toString() => '*** $msg ***';
}

class JsonError extends DartleroError {
  JsonError(String msg) : super(msg);
}     

Dartlero mostly hides the use of the list and map data structures (by looking at the code, you can see how list and map are used internally). It does not support identifiers and relationships and it doesn't have a code generator.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.118.0.145