Uses for non-visual Flex components

Brian LeGros | December 13th, 2007 | programming  

Recently, I've been interested in examining the features of non-visual components as it applies to Flex. I don't hear them talked about a lot (at least in the small part of the blog-o-sphere that I read), but I think there are some uses for these types of components that could really catch on in the community. I've tried to put together a sample application to show an example of some of the ideas I'm playing with in my head.

So the big place where I see non-visual components having a use is when attempting to bridge the stateless and stateful portions of a Flex application, mainly in the area of remote services. When I design a web service or remote object to be used by Flex, I typically build it in Java (or ColdFusion) and I design the service such that its methods operate in a stateless fashion. For example, when I call a method on my service, I don't expect previous calls to that method to influence the results of my current call; at least from the perspective of the caller. Additionally, I have the expectation that more information may be required when calling the method since the remote object receiving the call has no context in which to interpret the method call besides the method itself. Now I'm know an argument can be made about whether something truly is stateless or not, but that's not the goal of this post. Let's work with this ad hoc definition of stateless for now.

Flex provides us with a very simple, global means to get a hold of these services: RemoteObject, WebService, HttpService; there are other means by which to connect to remote services, but for now let's take the simple example of stateless RPC-based services. Typically in my Flex applications, I want to emulate a synchronous call from the application to the service (using something that implements IResponder or mapping the result/fault methods manually). Ideally I should have a class abstracting these calls to improve cohesion in the application; frameworks like to use command, delegate, or proxy classes, for example. During the emulation of this synchronous call I usually have my result/fault handler call out to a method on a class to change the state of an object (e.g. - setting values on the ModelLocator in Cairngorm), consequently firing propertyChanged events and/or custom events to update visual components via data binding.

All that being said, there are a couple of things with this approach that I want to address. First, I'm making the assumption that the class which abstracts the interactions with my service should also remain stateless. No where in the creation of the object am I changing its state so that the behaviors associated with the object may have a different context when executed. Second, I'm making the assumption that the behavior of this abstracting class must be separate from the data it uses. Propagating a change in an object's state via events is the back-bone of Flex data-binding. Not only that, but data binding is very simple to use and code, why shouldn't this simplicity be available in the ActionScript class abstracting the call to the remote service?

So that's enough conceptualizing for now, let's look at some example code. Please note the entire working example can be found at this location.

In this example, we have a very simple phone directory application. A SearchView exists which takes input from the user and announces a custom event (SearchEvent) passing that user input as its payload (i.e. - SearchCriteria). This event is handled by the Application class which in turn calls the find() method on an instance of SearchComponent. SearchComponent is a non-visual component which uses data-binding to propagate changes from the stateless world into my stateful Flex application. The code for SearchComoponent can be found below:

  1. package com.brianlegros.nvc_example.component
  2. {
  3.    import flash.xml.XMLDocument;
  4.    import mx.collections.XMLListCollection;
  5.    import mx.collections.ListCollectionView;
  6.    import mx.collections.IList;
  7.    import mx.collections.ArrayCollection;
  8.    import flash.net.URLRequest;
  9.    import flash.net.URLLoader;
  10.    
  11.    import com.brianlegros.nvc_example.vo.Employee;
  12.    import com.brianlegros.nvc_example.vo.SearchCriteria;
  13.    
  14.    public class SearchComponent
  15.    {
  16.       [Bindable]
  17.       public var locations : IList;
  18.      
  19.       [Bindable]
  20.       public var departments : IList;
  21.      
  22.       [Bindable]
  23.       public var employees : IList;
  24.      
  25.       private var data : XML;
  26.      
  27.       public function SearchComponent() : void
  28.       {
  29.          var request : URLRequest = new URLRequest("results.xml");
  30.          var loader : URLLoader = new URLLoader(request);
  31.          loader.addEventListener(Event.COMPLETE, function() : void
  32.             {
  33.                data = XML(loader.data);
  34.                
  35.                locations = findLocations();
  36.      
  37.                departments = findDepartments();
  38.             }
  39.          );
  40.          
  41.          this.employees = new ArrayCollection();
  42.       }
  43.  
  44.       private function findLocations() : ArrayCollection
  45.       {
  46.          var temp : ArrayCollection = new ArrayCollection();
  47.                  
  48.          for each(var item : XML in this.data.employee.location)
  49.          {
  50.             if(!temp.contains(item.toString()))
  51.             {
  52.                temp.addItem(item.toString());
  53.             }
  54.          }
  55.          
  56.          return temp;
  57.       }
  58.      
  59.       private function findDepartments() : ArrayCollection
  60.       {
  61.          var temp : ArrayCollection = new ArrayCollection();
  62.                  
  63.          for each(var item : XML in this.data.employee.department)
  64.          {
  65.             if(!temp.contains(item.toString()))
  66.             {
  67.                temp.addItem(item.toString());
  68.             }
  69.          }
  70.          
  71.          return temp;
  72.       }
  73.      
  74.            
  75.       public function find(criteria : SearchCriteria) : void
  76.       {       
  77.          var temp : ArrayCollection = new ArrayCollection();
  78.                  
  79.          for each(var item : XML in this.data.employee)
  80.          {
  81.             if(criteria.firstName.toUpperCase() == item.firstName.toString().toUpperCase()
  82.             || criteria.lastName.toUpperCase() == item.lastName.toString().toUpperCase()
  83.             || criteria.nickName.toUpperCase() == item.nickName.toString().toUpperCase()
  84.             || criteria.location == item.location
  85.             || criteria.department == item.department)
  86.             {
  87.                var employee : Employee = new Employee();
  88.                employee.firstName = item.firstName.toString();
  89.                employee.lastName = item.lastName.toString();
  90.                employee.nickName = item.nickName.toString();
  91.                employee.location = item.location.toString();
  92.                employee.department = item.department.toString();
  93.                employee.phone = item.phone.toString();
  94.                
  95.                temp.addItem(employee);
  96.             }
  97.          }
  98.          
  99.          this.employees = temp;
  100.       }
  101.    }
  102. }

There a few things to note about this component for the purpose of this example:

  • A method on a remote service/object is not actually being called, I'm using an XML document to simulate that process.
  • I am not actually emulating a synchronous call, I'm allowing the current thread to block on the method call. If I were to emulate the synchronous call, I would suggest using anonymous functions as the result and fault handlers for the remote service/object. The code in this example would be short and not warrant a named method mapping (this is done a lot in JavaScript when registering event handlers).
  • Yes, my coding style kinda sucks, get over it.

Now when the find() method is called it does not return anything, instead it updates the component's internal state via the employees property which then fires a propertyChanged event which is handled by ResultsView to populate a datagrid. Additionally, notice that when the object is constructed it makes a call to fetch location and department information to which controls in the SearchView are bound and updated when construction is complete. These values from these controls are used to filter the search performed by the user.

Going back to the conceptual, there are a few questions that come to mind:

  1. Aren't components supposed to be reusable? - From my POV, it feels like Flex has already done a great job of handling re-use through the RemoteObject, HttpService, and WebService classes. It seems that if re-usability is needed it would be at the service rather than the non-visual component. The non-visual component in my example is literally acting as a perspective for its service, or what potentially could be a group of services. Right now, however, I'm not sure if there are huge performance issues that may result from having multiple component perspectives for a single or series of services. I would assume for RemoteObject it may not be as big as a hit as it would be for a web service. Maybe this would be based on the remoting implementation you choose (i.e. - LCDS, BlazeDS, WebORB, Granite Data Services, etc).
  2. Aren't you just causing side-effects on objects? - In my opinion, it's not doing anything different than what Flex is doing with its visual components. In fact, what I think justifies this particular approach is the fact that you have the ability to notify anyone watching the object when its state has changed; I've always considered side effects as changes in state that I potentially didn't know about as the caller. The Flash movie instance is stateful; why not take advantage of this environment to add state to the classes abstracting our services? I'm building these non-visual components to satisfy the needs of my application, so I will know how they should behave and can to document that formally based on the constructs of the language. Now, if you ask me if this approach should be used for building an API-like interface to a set of remote services, then I would have to say no. The implementer of an API doesn't know how their code will be used in the context of an application, consequently keeping these components as stateless as possible is to the benefit of the API developer; context is limited to the execution of a method call. I think the Twitter API for Flash Developers is a great example of this.
  3. Where do I put all of these non-visual components? - This question I believe involves much more conversation about the implementation of these non-visual components. The example application is extremely simple and does not represent the issue of how to handle event propagation. In the example, all events are being propagated to the Application class and emulating a sort of global event system similar to those that I've seen in Flex frameworks with which I've worked. In fact, this is how easyMVC handles its event registration in the ControllerFactory; a ControllerEvent with a user provided type is registered on the Application and no matter where the event is dispatched, it's told to bubble to the Application to be handled by a mapped method in a custom Controller class. I have to admit that I like this approach much better than Cairngorm and PureMVC's approach of building their own global event system. I know both camps have their own reasoning for why they've done it, but I don't think that what Adobe has provided is worth re-writing. On the other hand, does the hierarchical nature of MXML bind visual component layout and construction too close such that without global event systems we can't be productive as Flex developers? On a side note, data binding in practice isn't always the answer to our problems; how a component can take advantage of these non-visual components and still interact with the components it needs to is a mystery to me. This may come back to the nature of MXML as well.
  4. Do I need a framework if I use this approach? - This is something I'm still trying to figure out. The biggest use of Flex frameworks I've found is a structured approach for making calls to remote services. I feel like frameworks have way too much boiler plate code and if this approach is practical, a good alternative may exist in place of adopting a framework. It seems to me like Flex frameworks have come from the mindset of the web world where stateless HTTP is king. We don't have to use the Front Page Controller pattern to build rich UI's; I think it's time to move on to different interpretations of the MVC pattern. I always find myself asking, did developers in the Java Swing world find themselves turning to a framework or were the constructs of Swing enough to be productive. If people were productive with Swing and it was a widget toolkit for AWT, why can't the same be true for Flex and Flash?

All this being said, this is just my latest idea. As you can tell, I still have a lot of unanswered questions. We are the process of implementing this approach on a much larger scale at work and hoping to solve the questions listed above. I'm always interested in feedback, so please rip this to shreds. I am far from experienced in this arena and am always open to what others have to say despite what some may think.

NOTE: For those who are interested, I began along this line of thinking based of the latest buzz-worthy topics in the programming community. It interested me as to how OSGI implemented their component architecture in Java w/o some language level support (e.g. - formal properties) and why it so popular. I was also intrigued by a proposal put together by Joe Noxel, from the Java Posse, regarding additions to Java for some of the language level elements already present in Flex. Additionally, SOA has come into debate by some of the more experienced professionals in software engineering and SCA (see Apache Tuscany as an example) has been identified as a potentially better alternative. So all this talk, combined with the little amount of component programming I've done with COM+ and .NET, made me wonder. If there is such a huge draw towards component-oriented design is there anything in Flex that we can do to take advantage of these practices? Does having formal properties and support for events as it presents itself in Flex aid developers with the tools necessary to utilize component-oriented design? Is one of those areas specifically the perspective of bridging the gap from the stateful component to the stateless service? Now I know a component has a much richer definition than I'm limiting it to, but this is just the point. To what extent can we, and should we, use components within Flex?

Architectual Styles - Part Four : Layering

admin | October 7th, 2007 | series  

In the fourth part of this series, I'd like to talk about my uses of layering as it applies to architectural styles. In searching for a good explanation of the Layers pattern itself, I stumbled up on this posting which I thought was a good analysis. Although the analysis is done in the context of Visual FoxPro, it gets across the mindset I have when working with the Layers pattern.

In my experience, I find myself consistently implementing layering in my applications as they grow in scale. I try to use layering as means by which to simplify the interactions between objects in my application to somewhat, well-defined levels of abstraction. I find that layering is also a good exercise in following good practices as it applies to cohesion and coupling; without an appropriate use of both, the use of layers may appear more difficult than it should be. In reading this post, please keep in mind that these abstractions are in place to help reduce complexity from the perspective of the developer. Adherence to preserving the integrity of each layer in your architecture is left up to you. In practice, you may come to find that breaking those boundaries every once and while may be more practical, but that is decision you have to come to.

So let's take a look at an overview diagram that I threw together:

Layering Overview

In the diagram there are few things that I want to point out. Firstly, I chose to show what I commonly refer to as a 3-tier layering scheme: Presentation, Business, and Integration. Semantically speaking, I've heard a lot of variations on the naming of these layers (e.g. - Presentation = Interface, Integration = Data), but for the purpose of this series let's stick with what written. Second, I've chosen to identify a few patterns in the given layers based on my previous experience with them. Please note that there are entire disciplines in software engineering devoted to pattern analysis and implementation, these are just a few that I've found useful and not a comprehensive or exclusive list. Third, for the purpose of this diagram, I've split the Presentation layer into two segments: Application and Service. Each section represents how I use the Presentation layer in the context of constructing an application with a UI or a service API. It should be assumed that the Business and Integration layers have to solve similar problems for each section, so no distinction has been made in the other layers.

With that being said, let's look at each layer in more detail:

  • Presentation - The Presentation Layer is where I place all of the classes associated with assembling some type of consumable interface for either an application or a service API.

    For an application, the typical interface I expose is a user interface. Web templates, view widgets, and other UI components make up the class types I place into this layer. Typically the Consumer for applications are end-users.

    For service APIs, I tend to expose Service classes which encompass units of work from the API as a whole, usually as methods on an object. The Service class' responsibility normally does not exceed aggregating functionality from the Business Layer. Based on the approach I'm taking, I may even include input validation as the responsibility of the Service class. Additionally, Facade/Adapter classes can be created to re-expose the functionality identified by the Service class but take only responsibility for the translation of messages to and from the consumer of the API. For example, I may not be able to call the service API by instantiating the Service class in shared memory, I may have to utilize RPC calls over SOAP. A Facade/Adapter class would be helpful for creating an interface to use as a basis for WSDL generation and translation of value objects to domain objects (more on this in a little bit). The Consumer for service APIs could be an application or another service API.

  • Business - The Business Layer is where I place all of the classes associated with the implementation of the business rules, usually as outlined by my use cases. Based on the architectural style you choose to implement (see next post in series), domain classes can potentially play a larger role in the implementations of these rules. Other classes applicable to this layer could be Validators (for business rules not input), Managers, and Unit of Work classes aggregating interactions as they relate to the Integration Layer. Although I consider the domain classes an integral portion of the "glue" between layers, I usually associate them with the Business Layer since its goals relate more directly to the problem domain than functional aspects.
  • Integration - The Integration Layer is where I place all of the classes that act as abstractions for the external resources on which my application is dependent. The responsibility of this layer usually results in classes managing connection and location information as well as domain object mapping. I typically do not find myself creating Transfer classes since most technologies (e.g. - ORM solutions) can work with my domain classes directly. In the diagram you can see some examples of the types of resources and the patterns I use to abstract them. Remember, the Integration Layer is just providing friendly abstractions; the use of those abstractions is dictated by the Business Layer. If multiple classes in the Business Layer need to send an email, both could have a common use of an EmailDelegate, for example, that exposes the basic functionality associated with sending an email. The classes in the business layer care about what's in the email, the delegate cares about how to send that email and other functional aspects of email.

Hopefully after these brief explanations, it begins to become apparent the crucial role that a domain plays in a layered architecture. The domain pervades into each layer as a contract allowing each to focus on how it can solve the problem using the behavior, or set of behaviors, for which it is responsible. This is yet another reason that semantics play such a large role in the creation of a domain; forming semantically relevant contracts between layers allow you scale your software as the solutions needed for the problem domain scale. From my experience, this turns out to not only be true as it relates to uses cases and business requirements but as it relates to functional requirements as well (e.g. - integrating something like instant messaging into the application).

That's about all I have on layering, but suffice it to say, I think migitating complexity is always a good thing when you know it will be an issue you have to address in the future. Hopefully I was able to make sense of my perspectives to help you reduce the complexities you encounter. In the next post of this series, we will get more into architectural styles as it relates to the Business Layer as I will try to convey ideas on what I consider light and heavy-weight architectures. I will also try to touch more on the idea of state and what it means for each of these styles.

Thanks for reading.

Does object persistence complicate architectures with existing data models?

Brian LeGros | October 7th, 2007 | programming  

Recently at work we've been using a lot of ORM solutions on the Java side for our service APIs. Our intent is to focus the interaction we have with our DB resources to that of object persistence rather than ad-hoc data access. So technology-wise the transition has involved going from Spring JDBC to things like iBatis and Hibernate.

To take a step back, let me qualify what I consider to be object persistence versus data access. I see data access as the direct use of a data model (e.g. - relation model via an RDBMS, hierarchical model via XML, etc), by an application. Typically I categorize data access code as code that working directly with the data model's query language (e.g. - SQL, XQuery/XPath, etc). Now, it usually benefits me when working in an object-oriented paradigm to find some type of mapping between the data model and the application's object model, which is where I see the desire to migrate to an object persistence paradigm for data access. In fact, I consider object persistence just a subset and abstraction of the term data access I've defined above. For me object persistence implies that data access is distilled into a simple set of conventions and/or configurable options to allows objects from an application's domain to gain basic CRUD (create, read, updated, delete) behaviors. In my mind, a few popular patterns for object persistence come to mind (ActiveRecord and Data Mapper) but I get the impression that what is perceived as a mature object persistence solution is a solution which completely abstracts the means by which to directly interact with the data model.

I don't necessarily think object persistence is a bad solution, in fact, I can see a lot of productivity coming from a reduced set of work when building an integration layer into your application. What I wonder about is the following:

  1. When an object persistence solution should be selected for use with an application.
  2. The amount of productivity gained from using an object persistence solution.
  3. The degree to which an object persistence solution should abstract direct data access.

Let's take the example of an application being developed from scratch without an existing relational model. I think the 3 points from above are easily answered by looking at how popular the Rails framework has become. I think when building an application anew, having an abstraction for the relational model is great approach. As a developer you can focus solely on your object model which, in my opinion, ideally means more time for working on modeling a domain and deciding on your application's architecture versus how its persisted.

Unfortunately, I think a majority of shops that like to apply the "enterprise" buzzword to their software infrastructure, don't have a luxury of building their data models from scratch. Let's take the example of building an application from scratch using an existing relational model. For this example I think there are a few divisions I have to make before forming my analysis:

  1. The relational model was constructed focusing on standards (i.e. - SQL DDL) and over time has become fairly normalized.
  2. The relational model was constructed utilizing vendor specific objects and over time have become fairly normalized.
  3. The relational model was constructed utilizing standards and vendor specific objects and over time has become more disheveled than normalized.

For the first division, I think an object persistence solution is extremely useful. In my opinion, using a solution that implements the Data Mapper pattern will result in productivity because the implication is that the data access being performed isn't that complicated. I also think that abstracting out direct data access may be beneficial so that it motivates the keepers of the relational model to maintain all of the work they've put into normalization moving forward.

For the second division, I think similar assumptions can be made as they were for the first division. From what I can tell it seems like most "mature" object persistence solutions provide you a means by which to work with vendor specific objects (e.g. - stored procedures, custom objects, rules, etc). I think normalization will save the day as long as the vendor objects in the relational model don't contain business logic which hasn't found its way into your application when it should.

This point I feel leads us to the third division; your shit is all mixed up from a relational perspective. I think object persistence can still be considered for use with an application of this type, but the complexity of the application should come into play as well when making the decision. I think a great gauge of whether or not to go the object persistence route is the complexity of your domain. If I find that I've got 2 domain classes with a simple composition relationship, I don't think using an object persistence solution is going to make me productive; heck, the domain may even be overkill. As far as direct data access goes, if normalization isn't there to provide some structure to the relational model, the implication, at least in my company's case, is that vendor objects were used to supplement the benefits you get from normalization. This means that business logic that possibly should be contained in the application is tucked away in a vendor object; short of rewriting that vendor object, you may need to reuse the functionality it provides. Direct data access at this point is the only option from what I can tell (e.g. - you need to use an inline non-deterministic SQL function as criteria for a join clause in a SELECT statement). From what I've seen in iBatis, object persistence with direct data access is definitely a real and usable option.

As one final point, I think utilizing an object persistence solution, especially in this third division, needs to be approached with a lot of caution when dealing with an existing data model. The forces that drove the creation of the existing data model are not the forces that are driving the creation of the application with which you need to integrate. From what I can tell, in the implementations I seen at work, the object persistence API can definitely start to drive, at a minimum, the way the application domain is being constructed. I'm not just talking about semantics, I'm also talking about data encapsulation and relationships. From what I can tell, based on your architectural approach (e.g. - fat models), this can result in a some pretty strange object behaviors emerging. I don't have any good examples, so that pretty much just makes this paragraph bunk, so hack these last few sentences up to an opinion. I would encourage readers, however, to do my work for me; show me some examples where you find this to be true.

Overall, I really like the idea of using object persistence in my applications, if I feel the complexity of the application and the data model being used warrant it. I do think sometimes that ORM tools are overused, but as employed developers I still think it comes back to finding the right set of tools for the job and being productive. If object persistence isn't going to fulfill those requirements, just remember that it's ok to not use one.

NOTE : I read a really good blog post about ActiveRecord and Rails yesterday that motivated me to finish this post. Even though this post isn't about patterns in object persistence, I think it's a great read if you have some time.

Architectual Styles - Part Three : Domains

Brian LeGros | August 9th, 2007 | series  

The concept of a custom type is something that is hard to avoid when designing object-oriented software. I've always seen custom types as a way to bring organization and semantic meaning to my applications. I find they help me to better describe data, relationships, and behavior especially when implemented in the form of classes. My biggest question, however, when I first began programming was the degree to which I should be utilizing classes. I always end up trying to find a balance between the following two questions:

  • To what extent do I utilize a class for semantic purposes?
  • To what extent do I utilize a class for reuse?

When does the use of a class for semantic reasons become overkill and when am I designing for too much flexibility? I've come to favor semantics over reuse, however I feel both are very important in the creation of successful architectural designs.

So let's talk about domains. What are they and why do I care? Well, for starters, when I refer to a domain, what I'm actually referring to are the identifiable entities based on a "real-world" problem for which a software application needs to be constructed to act as a solution. Put much simpler, a domain can be a collection of objects from the "real-world" recreated in software to solve a problem. Again this is just my definition, so yours may vary.

Please understand that the purpose of this post, is not how to conduct a domain analysis. There are much smarter people in the world with much better ideas than me that can help you in this area. That being said, below is a UML class diagram describing an example domain for a very simple search engine:

Example 1 - Class Diagram

The Search1 class is used to represent a search executed by a user. The SearchCriteria class represents the possible criteria that can be used to execute a search. SearchEngine1 is a very naive approach at representing some type of Fascade which uses an external search engine to execute a search. In this example, let's say the utlimate goal of a search is to return some type of collection of strings, each of which represents a URI somehow related to the search criteria provided.

Now in this example, I've taken what I feel is a very pragmatic approach to representing the search results in my model; I decided to use a generic collection object of type List (arrays, sets, or any other type of generic collection could be used here, I just chose List). Please note, I make the assumption that the caller already has created the Search and SearchCriteria objects and the External Search Engine will return a List. Below is a simple sequence diagram which shows the order of messages sent within the application:

Example 1 - Sequence Diagram

So in Example 1 I have reused a collection object with a stock set of behavior with which I am familiar and can probably be productive with little effort. On the other hand, I have sacrificed the semantics of my domain, because the notion of search results are nothing more than a generic collection. Let's say that I want to do something more with search results than List provides. What if I want to sort search results? If it's a simple ascending or descending alphabetical sort, then yeah, my generic collection can probably handle the work, but what about a sort by domain name or protocol? If we were to implement this using the model from Example 1, the Caller actor would have to take the responsibility (assume the behavior) of sorting the search results because we chose to go with a generic collection. Although coupling remains loose because of the flexibility of different classes which may be typed as List, the Caller's cohesion will be reduced because it's assuming the behavior of a domain its consuming. What about this design decision from a maintenance POV; will other developers immediately know where to look for the behavior associated with sorting search results? Is the answer still yes if you have multiple Caller actors which call execute() on the Search object?

Example 2 is an alternative to Example 1 where semantics were chosen over reuse:

Example 2 - Class Diagram

Example 2 - Sequence Diagram

In this example, the External Search Engine is still returning a List, but the SearchEngine2 class is digesting that List and converting it into a SearchResults object (SearchResults could even inherit from List). The SearchResults class has behavior associated with it and now has semantic meaning in the context of the domain. From a maintenance perspective, it is also easy for other developers to see where the behavior for sorting search results resides. Additionally, the behavior associated with SearchResults is completely encapsulated from Caller, so cohesion remains high with both the actor and the object. Coupling on the other hand does get tighter, but I see this as a worth-while compromise to obtain a more semantically meaningful domain.

Similar examples where I see myself choosing semantics over reuse are situations such as reporting. I've said this in the past, but reports very commonly represent entities within a domain. In fact, I see a very common behavior associated with reports, rendering report contents (not to be confused with how to deliver the rendered contents of a report). If a report is being generated from a database, for example, why should the calling process be subject to having its cohesion reduced so that an abstract data type can be used (e.g. - a RecordSet class or the like)? How maintainable does the notion of rendering a report become when other calling processes have to utilize the behavior; what if we need to render a report in multiple ways instead of one default way (e.g. - fixed length, comma-delimited, XML)?

Please keep in mind, I've said that my preference is choosing semantics over reuse when modeling a domain, but I still see this as a preference. I am not saying that I will never use abstract data types when modeling a domain. I am saying however, if the data, relationships, and behavior associated with domain warrant the use of a custom type, I am much more likely to create that type, than look for an opportunity for reuse. I like to use the "pseudo-metrics" of cohesion and coupling as a check and balance to help gauge the trade-offs I'm making in the domain as well. I have begun to use these principles even more with my current employer than every before. I think the fact that we have to live with our code for quite some time (5+ years in some cases) is definitely another driving factor for my preferences.

As I continue this series, please try to keep an open mind and realize that this post will serve as the basis for other posts as well. I have many more styles to talk about. Thanks for reading this far.

<< Part 2 : Cohesion and Coupling

Ah, that’s how the Canonical Data Model fits in!

Brian LeGros | July 18th, 2007 | programming  

So over the last few months, myself and few other developers at work have been brainstorming on approaches to implementing an SOA. Now before I say anything more, realize I haven't read any books on best practices as far as building an SOA from scratch; I'm just getting into the area and still have mixed feelings about the approach. In any case, I was listening to good old Software Engineering Radio on the way home today (SOA Part 2a) and they were able to answer a question I had in the back of my mind for a while.

When the challenge of coordinating services came up, I was able to understand the purpose of an ESB and how helpful it could be as a tool. When the issue of communication and protocols came up, JMS seemed like a very natural and loosely coupled solution (I definitely liked the idea of messaging over RPC). With Max working on a PoC with Mule and ActiveMQ, I felt the need to explore the issue of a canonical data model and the challenges that came with using one.

From the SER episode I listened to today, I felt reassured that this portion of the SOA was definitely a difficult one to incorporate. What I was trying to get my head around was a way in which common data types could be exchanged between business processes and how the definition for those types could be shared. SER pointed out that there are a few aspects of the shared data model you have to consider:

  1. Business processes may require semantically different data attributes for similar data types (i.e. - a Customer data type may require different information in a Data Indexing service than an Order Processing service)
  2. Data types may require different views of their data attributes based on external factors such as quality of service (i.e. - a call center service may only need name, phone number, and last 4 of your SSN for performance reasons but an Billing service would require a more complete view of the Customer regardless of performance).

SER recommended approaching this issue from a modeling perspective and then utilizing versioning and something as ubiquitous as XML (via XSD, or maybe even OWL) to represent an additional data layer to be used by the SOA. Services can retain their own domain classes which could be based on data structures defined in XML. SER suggested that the lack of a rigidly typed Java interface, for example, offers more resilience when it comes to versioning the canonical data model. They went as far as to suggest that versions of the data model could be marked as semantically similar or different. If a version of a data type was deemed semantically similar then it may be possible to for its consuming APIs to upgrade to the latest version without the need to refactor. I did worry that versioning could potentially get out of hand and in the end all we'd be doing is producing data types which were tightly coupled to business process, but from what I'm hearing that may not be the case.

Additionally, they suggested that a canonical data model be evaluated for use within selective domains in the enterprise. In doing so, it may be easier for business processes which have a dependency on a similar data type to share the same data type definition without the baggage of needing an act of God to change the data type definition later down the road. This approach seems like a patch-work solution where a few groups agree on the same data type definitions rather than the entire enterprise, but I can't think of a better approach from my limited exposure to SOA.

I realize I have lots to learn about this particular style of architecture, but SER is always a great listen. They definitely give me new perspectives on the topics I'm interested in. Keep up the great work guys.

Frameworks Conference 2007 : Intro to Object Factories

admin | May 19th, 2007 | conferences  

Rob Gonda gave this session. He went into a basic overview of OO constructs (e.g. - class, object, method, etc.). He then went into the concept of the Factory pattern. The explainations between the IoC and Dependency Injection patterns were interchanged a few times, but Rob was able to get the basic idea across. He explained how to use ColdSpring and the problems it helped to solve in terms of object construction. As he walked through each concept he used Ray Camden's Galleon app to show how object factories could be used to simplify the construction process based on the solution.

It's funny to hear all of the variations with respect to what people call the classes they work with. Rob in an aside mentioned the classifications he likes to give classes:

  • Service classes
  • Transient classes
  • Persistence classes being Transfer and ActiveRecord classes
  • Business classes (I think I remember him saying this one, but this may be interchangable with Transient classes)

Just another variation of how to communicate your ideas about OO programming I guess.

I was pleasently surprised with the quality of the content as compared to the rest of the sessions. Great job Rob; nice meeting you at cf.objective()!

Frameworks Conference 2007 : Rails for the Ruby-Impaired

admin | May 17th, 2007 | conferences  

John Paul Ashenfelter also gave this session. He gave a very comprehensive overview of the Ruby on Rails framework and the tools it provides to solve a multitude of common problems faced by web application developers. The context of the session was definitely to draw a comparison between ColdFusion/Fusebox/etc and RoR. No negative connotation went along with the comparison, but you could definitely tell he's a big Rails fan.

John had some very valid points, but I got the same vibe I do from most of the community experts when they present regarding the type of work they do. In my current job we are attempting to build software that is going to last for at least a decade, or so we hope. We're making decisions which are not only helping to shape the software we build, but decisions to better understand the business domain we're working within. I am really curious if most of these consultants have similar concerns? I'm sure they follow best practices and are good at their jobs, but what type of longevity and scale do consultants have in mind? Is the time necessary to build things like canonical data models and SOA's only available to the salaried guys/gals? It seems like consulting is very project/task-based which I associated with very short term goals. I don't know, I'm probably off my rocker.

Anyway, good talk John, thanks for mentioning JRuby too!

Frameworks Conference 2007 : Design Pattern Safari

admin | May 16th, 2007 | conferences  

Peter Farrell gave this session and it made me wonder what he's teaching to the ColdFusion community. In fact there were a lot of ideas that he was preaching that came off to me as extremely naive and short sighted. With that being said, please understand that my review of his session is just my opinion, I could be completely off base and detached in terms of OOD.

One of the big things that got me, which is something that got me while attending cf.objective(), is the ColdFusion Community Experts' use of the DAO and (Table) Gateway pattern. Peter explained a DAO as an object used to represent a single row in your database mapping to a single Bean in your application. Who said that a single row is the only way to represent your object model in a relational one? If this is what you consider a DAO, what's the ActiveRecord pattern? The other thing that gets me is their use of the (Table) Gateway pattern. The community's interpretation of this pattern is encouraging a nasty mix of a relational data structure in an object-oriented model. Peter claims that this is ok for performance, and I agree that sometimes you want the relational data in its raw format for performance improvements (i.e. - reporting). That being said, how do we represent a report in our object models? Let's create an object to represent the report we're trying to generate which wraps the relational data structure and then expose behavior on the report like render(). The reason to work within an object-oriented paradigm is to emulate the environment in which the problem exists and to form a solution which matches the ideal real-world solution as closely as possible. Now this definition is a bit loose, but the general idea is there. We need the concept of a collection of objects to work within an object-oriented paradigm. Collections themselves are traditionally objects with responsibilities/behaviors of their own. If performance is a concern, then implement caching, lazy load techniques, or something else geared towards performance in your architecture; don't smelt the relational model into the object model. To say that collections of objects are not useful and a huge performance overhead is very naive.

Peter went on to talk about the Singleton pattern. He represented the concept of the Singleton pattern as storing a variable in the Application scope. Obviously, this is not an implementation of the Singleton pattern, just the use of a persistent memory scope. He didn't mention anything about the responsibilities of an object implementing the Singleton pattern in terms of construction, accessing the same instance reference in memory, or the effect of the pattern on object cohesion.

Overall I'd give this session a "pass" on the must listen list. I'm dissapointed with the Frameworks Conference and the allowance of a presentation of this quality, especially obtaining the materials ahead of time. Nothing personal Peter, I still have lots of learning to do as well, but I didn't care for the presentation.