Thursday, August 27, 2009

Working with Strategy in AS3/Flex

Strategy tells us to
• Define and encapsulate a family of algorithms.
• Make encapsulated algorithms interchangeable.
• Allow algorithms to change independently from the clients that use it.

HRAgency

For illustration purposes,in this sample application, a Strategy pattern is used to implement a solution for an HR employment agency.
• The agency has a number of consultants it represents. Clients call for different consultant job types targeted at either- employer or jobseeker. They want either a particular consultant or particular support tasks or main tasks they can perform.
• To create a flexible program for the HR agency, each of the specific support related and main tasks has been created in separate algorithms. The algorithms are encapsulated, and the consultants delegate their performance skills to the encapsulated algorithms—strategies.

The base Consultant context class


The first step is to create a context class and concrete contexts that will use the different tasks and support jobs.
Consultant class is the base class, establishing the references to the strategy methods.
The main tasks and support operations are delegated to the strategy classes.

The concrete Consultant classes
• EmployeeConsultant extends the context Consultant
• JobSeekerConsultant extends the context Consultant

Each is assigned a different task and support that are delegated to concrete strategy instances.




package
{
class Consultant
{
protected var mytasks:ITasks;
protected var mysupport:ISupport;
public function doManagementTasks( ):void
{
mytasks.task( );
}
public function doSupportTasks( ):void
{
mysupport.support( );
}
}
}

package
{
class EmployeeConsultant extends Consultant
{
public function EmployeeConsultant( )
{
tasks = new NewHireInduction( );
support = new FileRecord( );
}
}
}

package
{
class JobSeekerConsultant extends Consultant
{
public function JobSeekerConsultant( )
{
tasks = new Close( );
support = new CallUp( );
}
}
}


The Tasks Interface and Implementations

All the algorithms for doing tasks are encapsulated in the concrete strategy subclasses.
The TASKS interface provides the abstract method, and the subclasses add detail to the operations. A total of three TASK algorithms are implemented.
• Manage.as
• Close.as
• NewHireInduction.as




package
{
interface ITasks
{
function task( ):void;
}

}

package
{
//Manage Multiple Projects
public class Manage implements Tasks
{
public function tasks( ):void
{
trace("Look at me juggle! Whoops!\n")
}
}
}

package
{
//Make Open Files Close
public class Close implements ITasks
{
public function task( ):void
{
trace("Now close the open tasks. Successfully found the job!\n")
}
}
}



The Support Interface and Implementations

All the algorithms for doing tasks are encapsulated in the concrete strategy subclasses.
The SUPPORT interface provides the abstract method, and the subclasses add detail to the operations.
A total of two SUPPORT algorithms are implemented.
• Callup.as
• FileRecord.as




package
{
//Support Tasks Interface
interface ISupport
{
function support( ):void;
}
}

package
{
//Consultants chase each other
public class CallUp implements ISupport
{
public function support( ):void
{
trace("Status Call - I'm going to talk to you!");
}
}
}

package
{
public class FileRecord implements ISupport
{
public function support( ):void
{
trace("I'm adding this client in the records!")

}
}
}


The HRManager Sprite

The HRManager class instantiates two different consultant classes, through their interfaces rather than implementations by instantiating through the Consultant subclasses.
All are delegated from the Consultant context class and implemented in the concrete consultant classes.
The output represents the algorithms set up in the strategy classes.

package {
import flash.display.Sprite;

public class HRManager extends Sprite
{
public function HRManager()
{
var jobseeker:Consultant=new JobSeekerConsultant();
jobseeker.doManagementTasks();
jobseeker.doSupportTasks();

var employer:Consultant=new EmployeeConsultant();
employer.doManagementTasks();
employer.doSupportTasks();
}
}
}

Saturday, August 22, 2009

Creating Combobox within a DataGrid column in Flex

The compononet that needs to be attached might be a Combobox or a Checkbox.
One of the techniques is to create a custom ComboBox and use the itemRenderer property of the DataGridColumn to display it inside the data grid as a Combobox which then, internally fetches its values from an XML.

<mx:DataGrid id="portfolioGrid" width="100%" height="100%"
dataProvider="{portfolioModel.security}" selectable="true">
<mx:columns><mx:Array>
<mx:DataGridColumn dataField="Symbol"/>
<mx:DataGridColumn dataField="Quantity" textAlign="right"/>
<mx:DataGridColumn dataField="Price" textAlign="right"/>
<mx:DataGridColumn dataField="Value" textAlign="right"/>
<mx:DataGridColumn dataField="portfolioType"
width="175" textAlign="center"
headerText="Type"
sortable="false"
editable="true"
editorDataField="newState"
rendererIsEditor="true"
itemRenderer="MyComboBox"/>
</mx:Array></mx:columns>
</mx:DataGrid>


MyComboBox.mxml needs to be imported and corresponding handler functions for the ComboBox component needs to be defined in this separate file.

Sunday, August 16, 2009

"Protocols that RULE the FLEX world"

In the context of RIA, protocols that we need to get familiarized with are
1. REST - HTTP Object <mx:httpservice>
2. SOAP - WebServices Object WSDL <mx:webservices>
3. AMF - Remote Objects <mx:remoteobject>
4. XML Sockets (myXML = new XMLSocket;)

RIA's essentially reside on the client and communicate with the servers only to request and process data unlike normal web apps which are page-centric.

First is the widely used, REST(Responseful State Transfer) includes - HTTP(Hyper Text Transfer Protocol):
  • HTTP Service Component typically consumes XML responses.
  • They let you send HTTP GET, POST, HEAD, OPTIONS, PUT, TRACE, and DELETE requests and include data from HTTP responses in a Flex application.
  • Flex does not support mulitpart form POSTs.
  • The HTTPService's send() method makes the call to the JSP page.
  • The resultFormat property of the HTTPService component is set to object, so the data is sent back to the Flex application as a graph of ActionScript objects.
<mx:HTTPService id="srv" url="catalog.jsp"/> <mx:DataGrid dataProvider="{srv.lastResult.catalog.product}" width="100%" height="100%"/> <mx:Button label="Get Data" click="srv.send()"/>

For RemoteObjects:
The results of remote invocations are returned via events.
RemoteObject provides the result event for success or fault for failures.
  • To implement we must write the corresponding handler functions. Flex will call these methods, supplying an Event object as a parameter. It’s our responsibility to get the information from the event and act accordingly.
  • Explicitly mapping Action Script objects to Java objects and Serializaton of data
  • Converting data from Java to Action Script
<mx:RemoteObject id="srv" destination="product"/>
<mx:DataGrid dataProvider="{srv.getProducts.lastResult}" width="100%" height="100%"/>
<mx:Button label="Get Data" click="srv.getProducts()"/>


For more indepth information, please refer to Flex3 with Java.