Skip to content

Architecting on Force.com

At CODA we are heavily into the implementation of design patterns within our Java and .Net based products, and as such found ourselves quickly wanting to benefit from them on the Salesforce platform as we embarked on our CODA2go project to build a new Finance system. To date we have implemented Domain Model, Unit of Work, Identity Map, Lazy Load, Data Mapper and Service Layer. The platform also provides a solid implementation of the Model View Controller pattern through its new Visualforce technology. It’s very likely that CODA is amongst the first, if not the first software vendor to implement these patterns on this platform and I’m pleased to say despite the infancy of the Apex language they have taken very well. For those unfamiliar with design patterns, think of them as generic cook books for developers that describe solutions and strategies to building well structured and critically, well defined, consistent and thus maintainable implementations. This Wikipedia article is a good general reference. The above links are taken from Martin Fowler’s excellent site. Implementing these patterns alongside a representation of our product’s domain model has also been critical to our desire to keep code relating to aspects such as business logic, data representation, querying, persistence and user interface code separate. This approach has been base architecture design for all CODA products ever since our first client server application, CODA-Financials.

The Force.com platform provides developers with Apex objects that reflect objects defining your application’s “schema”, which in turn is defined by the developer through the web interface or more recently in the Eclipse toolset offered by Salesforce. Currently the resulting Apex objects (so called SObjects), are not what you might regard as very “Bean like” and have no scope for adding behaviour through inheritance. As such they tend to feel to us more like they represent an application’s data model (although some declarative validation rules can be defined) as opposed to its domain model, where data and behaviour are defined together. For this reason we tend to view and refer to SObjects on the platform as DTO’s (Data Transfer Objects) for use within our persistence layer (see Data Mapper). In discussions with Salesforce architects we choose to implement Apex classes that at a basic level can be said to wrap these objects, but in fact form the basis of what has become the core layer of the CODA 2go implementation, the domain model layer. There are many ways of adding business behaviour to your Force.com application, by coding in various forms and places to suit your immediate requirement. By using a combination of triggers, custom buttons, SControls (HTML snippets), JavaScript, Web Services and more recently Apex code handlers on Visualforce UI controllers. CODA needed to define an implementation strategy that would withstand the increasingly complex business scenarios each sprint would bring as our new Finance application continues to grow over not only its initial release sprints, but continue through its life (our current CODA-Financials product is over 12 years old and still being actively developed!). So our strategy needed to be one that would provide a clear and easy-to-follow code partitioning model driven by the purpose and responsibility of the code being written by the developer. Thus we have one simple rule; only pure business logic goes into our domain layer Apex classes and nothing else. Standard methods such as canDelete, canUpdate, validate etc. exist on each domain class to provide consistency for common behaviours. This isn’t to say we ignore the other areas of the platform where code can get invoked – quite the opposite, the Force.com trigger feature is key to the validation phase our domain objects go through when being committed to the database via the unit of work. Except that in the CODA case the trigger implementations are pretty general in nature, in fact we have now generalized these. Thus simply, their role is to establish an instance of the applicable domain class for the trigger SObject (DTO) to delegate to. e.g. canUpdate and validate methods. If you consider the addition of a business orientated Web Service layer to CODA 2go, we can be sure that Apex code implementing these services needs only interact with our domain model layer to invoke the exact same behaviour as our client interface exposes. Thus critically for any good API, ensure no business logic has leaked out into other areas such as the UI handlers. Something which is a common weakness in some application implementations, often leading to limited API exposure of the application functionality. In our most recent sprint we have been considering our resource utilisation on the platform, particularly in respect to the amount SQL requests we make. Since this is a governed limit enforced by the platform we need to monitor this carefully. To this end we expanded our implementation of the Identity Map pattern through the code written in previous sprints that had not had this pattern applied. The results speak for themselves, in terms a significant drop in the number of SQL requests being made when compared with results from the same test (Creating Invoices) run on a previous sprint code base.

Contact us
See a demo