An example of using Dartlero

To get a better feeling of what using a framework entails, let's examine the project that exists as the example folder in the dartlero project, and as a separate project called dartlero_example at GitHub (there are slight differences due to the pub specifications). Get your copy in a separate folder with:

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

Then, open the dartlero_example folder in Dart Editor.

This app defines the simplest possible model: a project model with only one concept, Project. We will now use the Dartlero framework. The dependency on this package is indicated in the pubspec.yaml file so that it can be managed by pub:

name: dartlero_example
version: 1.0.0
author: Dzenan Ridjanovic <[email protected]>
description: An example how to use Dartlero, a model framework for educational purposes.
homepage: http://ondart.me/
dependencies:
  dartlero:
  git: git://github.com/dzenanr/dartlero.git

The dartlero_example.dart library file in the lib folder imports Dartlero and references two files in a subfolder model:

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

part 'model/project_entities.dart';
part 'model/project_model.dart';

In the project_entities.dart file, we will see a Project class that extends the ConceptEntity<Project> framework class, and the Projects collection class that extends the ConceptEntities<Project> class:

class Project extends ConceptEntity<Project> { ... }
class Projects extends ConceptEntities<Project> { ... }

What has happened here? The <Project> type argument is passed to the ConceptEntity class (or ConceptEntities) and its T parameter is replaced by Project. If we replace this, the signature class in the ConceptEntity<T extends, ConceptEntity<T>> abstract class will become more specific: abstract class ConceptEntity<Project extends ConceptEntity<Project>>.

After this, wherever we will see T, Dart (or Dart Editor) will see project; the same is true for the ConceptEntities class. This means that a collection of entities will contain only projects. Thus, if we want to add a task to projects (let's say of the Task type), Dart Editor will complain. Without generics, Dart Editor would happily accept a new task in the projects collection. Using generics makes a framework more general. It can be used with all kinds of concrete types, constraining data so that the model is valid. The following is the complete code of project_entities.dart:

part of dartlero_example;

class Project extends ConceptEntity<Project> {

  String _name;
  String description;

  String get name => _name;
  set name(String name) {
    _name = name;
    if (code == null) {
      code = name;
    }
  }

  Project newEntity() => new Project();

  Project copy() {
    var project = super.copy();
    project.name = name;
    project.description = description;
    return project;
  }

  String toString() {
    return '  {
 '
           '    ${super.toString()}, 
 '
           '    name: ${name}, 
 '
           '    description: ${description}
'
           '  }';
  }

  Map<String, Object> toJson() {
    Map<String, Object> entityMap = super.toJson();
    entityMap['name'] = name;
    entityMap['description'] = description;
    return entityMap;
  }

  fromJson(Map<String, Object> entityMap) {
    super.fromJson(entityMap);
    name = entityMap['name'];
    description = entityMap['description'];
  }

  bool get onProgramming =>
      description.contains('Programming') ? true : false;

  int compareTo(Project other) {
    return name.compareTo(other.name);
  }
}

class Projects extends ConceptEntities<Project> {
  Projects newEntities() => new Projects();
  Project newEntity() => new Project();
}

The Project and Projects classes also contain the newEntity and newEntities methods to create concrete objects, implementing the abstract methods of their parent classes. A project has a name and a description, and some of its methods (such as copy, toString, toJson, and fromJson) extend the methods inherited from ConceptEntity by using the super keyword. The inherited compareTo method gets a new implementation in the project: it is completely overridden. Furthermore, Project adds a new onProgramming method, which is a get-only property to see from the description whether the project has something do to with programming.

The subfolder model also contains project_model.dart with a ProjectModel class that extends the ConceptModel class from the Dartlero framework. Three projects are created in the init() method. The display() method on the model delegates work to the inherited (from ConceptEntities) display() method on the projects object. The following is the code from project_model.dart:

part of dartlero_example;

class ProjectModel extends ConceptModel {

  static final String project = 'Project';

  Map<String, ConceptEntities> newEntries() {
    var projects = new Projects();
    var map = new Map<String, ConceptEntities>();
    map[project] = projects;
    return map;
  }

  Projects get projects => getEntry(project);

  init() {
    var design = new Project();
    design.name = 'Dartling Design';
    design.description =
        'Creating a model of Dartling concepts based on MagicBoxes.';
    projects.add(design);

    var prototype = new Project();
    prototype.name = 'Dartling Prototype';
    prototype.description =
        'Programming the meta model and the generic model.';
    projects.add(prototype);

    var production = new Project();
    production.name = 'Dartling';
    production.description =
        'Programming Dartling.';
    projects.add(production);
  }

  display() {
    print('Project Model'),
    print('============='),
    projects.display('Projects'),
    print(
      '============= ============= ============= '
      '============= ============= ============= '
    );
  }
}

In the packages folder, we will see not only dartlero, but also unittest, because Dartlero needs this library. This project model is exercised in the accompanying project_model_test.dart test program in the test/model. It contains the following code:

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

testProjects(Projects projects) {
  group("Testing Projects", () {
    setUp(() { ...   });
    tearDown(() { ...  });
    test('Add Project', () { ... });    
    // various other tests
    });
}

initDisplayModel() {
  ProjectModel projectModel = new ProjectModel();
  projectModel.init();
  projectModel.display();
}

testModel() {
  ProjectModel projectModel = new ProjectModel();
  Projects projects = projectModel.projects;
  testProjects(projects);
}

main() {
  // initDisplayModel();
  testModel();
}

The main() method calls testModel(), which in turn calls testProjects() that uses the unittest framework. It contains one group ("Testing Projects", () {...} method with setUp, tearDown, and a number of test methods. In the setUp() function, some projects and a collection containing them are created and displayed. Running this test program will give the following output:

Project Model
=============

Projects
[
  {
     code: Dartling Design, 
     name: Dartling Design, 
     description: Creating a model of Dartling concepts based on MagicBoxes.
  }
]
// some output omitted for brevity //
unittest-suite-wait-for-done
PASS: Testing Projects Add Project
// some output omitted for brevity //
PASS: Testing Projects From JSON to Project Model

All 13 tests passed.
unittest-suite-success

Some of the applied tests are given as follows:

  • While instantiating an object:
    var design = new Project();
    expect(design, isNotNull);
  • While adding a project to projects, to count the number of projects:
    expect(projects.length,equals(++projectCount));
       var added = projects.add(project);
       expect(added, isTrue);
  • When projects are cleared:
    expect(projects.isEmpty, isTrue);
  • While searching for a project:
    var project = projects.find(searchName); expect(project.name, equals(searchName));
  • Testing that every project has a name:
    expect(projects.every((p) => p.name != null), isTrue);

So, what are the advantages of using a domain model framework? Clearly, by inheriting from the model classes, we get a (lot of) code that we don't have to write ourselves. So, we get a head start in the functionality of our app. For the simple Dartlero framework, there are methods such as copy, toJson, fromJson, contains, find, and display.

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

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