Flex Part 02: Value Objects & Model Objects

Value Objects

Value Objects are ActionSrcipt classes which are stored in the project's vo directory.

Think of a Value Object as a row in a database table. Let's imagine a table named
schools with columns for name, phone, address and ranking. Imagine also a related table of students.

Table: schools (one school has many students)
+------------+---------------+
| Field      | Type          |
+------------+---------------+
| id         | Number        |
| name       | String        |
| phone      | String        |
| address    | String        |
| ranking    | Number        |
+------------+---------------+

Table: students
+------------+---------------+
| Field      | Type          |
+------------+---------------+
| id         | Number        |
| school_id  | Number        |
| name       | String        |
+------------+---------------+

Each row in the schools database table will have several properties which effectively describe a single School. The properties of a School contain simple values: strings, numbers, dates etc. This is the essence of a Value Object (VO).

A VO is an ActionScript Class which contains properties that hold simple values. Compare our database table schools to the SchoolVO below:

Actionscript:
  1. /**
  2. * Filename: SchoolVO.as
  3. *
  4. * Find this file in the src/com/domain/project/vo directory.
  5. */
  6. package com.domain.project.vo
  7. {
  8.     public class SchoolVO
  9.     {
  10.         /**
  11.          * The properties of a School
  12.          */
  13.         public var id     :Number;
  14.         public var name     :String;
  15.         public var phone    :String;
  16.         public var address  :String;
  17.         public var ranking  :Number;
  18.     }
  19. }

It makes a lot of sense why some people call VO's "Data Transfer Objects". The purpose of a VO or DTO is to exchange data between the Flex application and a server (In most cases) - so we would expect the VO to model the server-side data we're working with. We won't actually be transferring VO's to and from the server until a much later post, but we will be using VO's in our applications. Why?

VO's provide more than just a clean way to transfer data to and from the server. They create clean readable code, code hinting, and helpful compiler errors when the programmer makes a mistake. All of these are good things, but looking at the SchoolVO class I notice it is lacking some functionality that could be very helpful. Enter Model Objects.

Model Objects

Update: The following section on Model Objects has been updated in a new post titled "Flex Part 02+: A Better Model Object." Please view both posts before deciding how to implement Model Objects in your application.

Model Objects are ActionSrcipt classes which are stored in the project's model directory.

Model Objects give the VO the ability to enforce rules and validations while being used in the application and before being sent to the server. They are the gatekeeper to the VO. In the case of SchoolVO, we may desire to enforce rules such as: the phone number must be at least ten characters long. Well, VO's have no mechanism for enforcing the rules - and they shouldn't.

A Model Object is very similar to a Value Object, except that it will contain methods for enforcing business logic (rules, validations and helper methods). Let's create a School Model Object:

Actionscript:
  1. /**
  2. * Filename: School.as
  3. *
  4. * Find this file in the src/com/domain/project/model directory.
  5. */
  6. package com.domain.project.model
  7. {
  8.     import com.domain.project.vo.SchoolVO;
  9.    
  10.     [Bindable]
  11.     public class School
  12.     {
  13.         /**
  14.          * Bindable properties of a Person
  15.          */
  16.         public var id         :Number;
  17.         public var name   :String;
  18.         private var _phone    :String; // note: private - see getter/setter methods
  19.         public var address    :String;
  20.         public var ranking    :Number;
  21.        
  22.        
  23.         /**
  24.          * Get & Set ethods to enforce rules
  25.          */
  26.         public function set phone(phone:String):void
  27.         {
  28.             if (phone.length>= 10) { _phone = phone; }
  29.             else { trace('Phone number is too short'); }
  30.         }
  31.         public function get phone():String
  32.         {
  33.             return _phone;
  34.         }
  35.        
  36.        
  37.         /**
  38.          * Create a SchoolVO fom Model Object
  39.          */
  40.         public function toVO():SchoolVO
  41.         {
  42.             var vo:SchoolVO = new SchoolVO;
  43.             vo.id         = id;
  44.             vo.name       = name;
  45.             vo.phone       = _phone;
  46.             vo.address   = address;
  47.             vo.ranking    = ranking;
  48.             return vo;
  49.         }
  50.        
  51.        
  52.         /**
  53.          * Create Model Object from SchoolVO
  54.          */
  55.         public static function fromVO(vo:SchoolVO):School
  56.         {
  57.             var mo:School = new School();
  58.             mo.id         = vo.id;
  59.             mo.name       = vo.name;
  60.             mo.phone       = vo.phone;
  61.             mo.address   = vo.address;
  62.             mo.ranking    = vo.ranking;
  63.             return mo;
  64.         }
  65.     }
  66. }

The School Model Object contains get & set method pair to enforce the rule that phone cannot be less than ten characters long. The benefit of this is that the phone property may be updated from anywhere in the application and the School Model Object will validate itself. It is recommended (and admittedly rarely implemented) that getter setter pairs be used for all properties in Model Objects.

Note: An error existed in the above School.as code through 1/27/2008. The error has been corrected. Understand that both a get & set method must be defined in order for data binding to work correctly. A private property can be made read-only by specifying only a get method - but changes to the property will not be reflected through bindings (even though attempting to bind to a read-only property generates no compiler errors or warnings).

Model Object Methods: toVO and fromVO

A Model Object does not require the methods toVO and fromVO, but they sure are helpful. The application will be using School Model Objects to display information and interact with users, but we will still need a way to send the SchoolVO to the server at some point. The toVO method returns a SchoolVO all set to send to the server:

Actionscript:
  1. /**
  2. * Request a Value Object from a Model Object instance (mo)
  3. */
  4. var vo:SchoolVO = mo.toVO();

On the other hand, if we receive a SchoolVO from our server, all we need to do to convert it into a ModelObject is:

Actionscript:
  1. /**
  2. * Create a ModelObject from a Value Object instance (vo)
  3. */
  4. var mo:School = School.fromVO(vo);

Taking this one step further, the Model Object could contain other factory methods like fromXML which would create a Model Object from XML. I hope the benefits of using Value Objects and Model Objects are more clear at this point. They will be made much more clear when we begin sending VO's to and receiving them from a server.

If you would like to jump ahead on your own, please look into the following resources:

  • ColdFusion
    Read about ColdFusion integration with Flex
  • WebORB
    .NET, Java, Ruby on Rails & PHP integration
  • RubyAMF
    Ruby on Rails integration

Please suggest more AMF resources if you are aware of them and can recommend them.

Next ...

Now that we have a way to work with data in Model Objects, we need a place to hold instances of these objects so that users can interact with them. The next post, Flex Part 03: The ModelLocator, will describe how to store all data in one central location, accessible to every part of the Flex application.

Thank you for reading. Your comments are very much appreciated. Remember that these posts are living documents and will be updated over time as input is received and new ideas emerge. So, please, consider your comment a contribution and not a critique.

1 Response to “Flex Part 02: Value Objects & Model Objects”


  1. 1 nate

    AMFPHP is a great AMF implementation.
    It can be found at http://www.amfphp.org

Leave a Reply