Wednesday, December 18, 2013

Rails: New Framework - Old Design Problems

I have been programming for Rails for about 2-3 years now. As I came from a C# background it was a bit awkward for me to see some design principles I took as good practices being unashamedly broken such as:

  • data-driven models mixed with persistence logic instead of plain old domain objects
  • controllers being used as application scenarios instead of coordinators between my actual application object and the view ( that was my understanding of MVC )
At that time I just thought it was the ruby-on-rails way of doing things and as a good newcomer in the ruby developer community I decided I should learn and listen more from other rails developers and forums than telling what the best practices should be.

However after some years of work experience I realized some of those design problems were not sufficiently addressed for some anti-patterns: ( At least not until this year - some problems are still not addressed )
  • fat controllers / skinny models
  • skinny controllers / fat models
  • god models
  • transparent polyglot persistence in domain models ( SQL, NoSQL, Graph, etc ... )
Note that these design problems were solved in other programming environments long ago.

Now with the maturity of rails developer community and the increasing adoption of rails in many enterprises I see design patterns and ideas being presented more often. 
The objective of these ideas seems to be the same: keep active record models focused only on data and extracting out logic of any kind ( business, view, etc.. ) to other classes or modules.
Some ideas that called my attention are:
  • Use of service objects that orchestrate rails models in handling complex scenarios
  • Use of rails concerns (modules) to extract behavior or methods that do not belong to the model responsibility (which in rails means data persistence and validation)
Some oppose to rails concerns because it can lead your rails model class to have many roles instead of one-role. ( This is a popular clean code principle: one class, one role )
However in his article DHH gave good reasons for doing it what actually made me open an exception for this clean code principle for this particular ruby case. ( I am a clean code fan and exceptions are rare)

In this case this clean code principle of one-role-class became a bit different for me after reading DHH article (see reference below in chubby models): 
  • one class should have one IMPLEMENTATIONAL role. 
In Ruby a rails model should implement only ONE role while it can be injected by many others.
For instance it is not a problem that your class contain many roles since they come from mixins.
However mixins (or Rails concerns) should augment the rails model features and not make your class implementation dependent on them. It is not forbidden to be dependent on mixins such as by active record or mongoid since they are part of the one implementational role defined for the class but some caution is needed.

In the other hand the idea of using a service object can make it clear that some complex business concepts are executed separately. Scenarios include payment process, authentication and many others. Its benefit is very clear to me.

Both ideas are of great help to keep both controllers and models on a diet ( skinny controller / skinny models ) but other design problems such as transparent polyglot persistence and possible many others remain unanswered.

I hope to see what the ruby community will have to say about that in the future.
Maybe I can answer some of those questions, who knows ?

References:









Thursday, December 06, 2012

RORM - Ruby Domain Objects with Persistence

After some time using ActiveRecord and MongoId, I decided it was time to create a ruby ORM for domain objects as my first github project.
https://github.com/hcmarchezi/rorm/blob/master/README.md

Monday, November 12, 2012

Separated Interface Design Pattern


When developing a system in many cases it is possible to identify dependencies among different layers whose responsibilities are well defined in the system.

Some examples of layer dependencies are:
  • Controller layer dependency and UI layer
  • Domain logic layer and persistence layer

One strategy to remove dependencies between layers is to use the separated interface design pattern. This pattern consists of defining an interface from the bottom layer that is going to be used by the top layer. See diagram below  to understand how it works for controller and UI layer:


The controllers in the example above only reference interface views and never know which view implementation they are actually working with.

This design pattern is recommended for a system when:
  • One layer (such as a controller) will be reused to be plugged into different versions of the other layer (such as HTML5 and native view layer implementations)
  • Layers are easier to be tested in isolation
  • It is not desired that one layer has API dependencies from the other layer

References:




Sunday, August 28, 2011

JavaScript: Object Oriented Programming


By using functions and the structures above it is possible to a function object which syntax works just like a C++/Java class. See examples below.

Classes

In JavaScript classes are declared as functions.
function Task(name,dueDate)
{
   this.name = name;
   this.dueDate = dueDate;
};

var myTask = new Task(“Clean house”,”2011-07-01”);
myTask.name = “some new name”;

Methods

Methods are declared by extending the function prototype. 
var User = function(email,password) {
   this.email = “”; // public field
   this.password = “”;
};
User.prototype.generatePassword = function() {  // public method
   this.password = "generatedpass";
}
var user = new User(“you@email.com”,”mypassword”);
user.generatePassword(); // password is generatedpass

Alternatively methods can be declared inside the function declaration.
var User = function(email,password) {
   this.email = “”;
   this.password = “”;
   this.generatePassword = function() {
       this.password = “generatedpass”;
   };
};

Inheritance

In order to make a class inherit from another class, the subclass prototype must be set to the desired parent object. It is also necessary to set the constructor as the current class which is a little od. See example below.
function Person() {
   this.firstname = "James";
};
Person.prototype.generateName = function() {
   this.firstname = "generatedname";
};


function Student() {
   this.school = "Rahway School";
};
Student.prototype = new Person();
Student.prototype.constructor = Student;
Student.prototype.setBestSchool = function() {
   this.school = "Best school in town";
};

Polymorphism

Polymorphism can be achieved by simply declaring methods with the same name.
Consider the hierarchy of figures as an example below.
function Photo() {    
}
Photo.prototype.getDestinationPath = function() {
   return “./photos/common”;
};
function PartyPhoto() {
}
PartyPhoto.prototype = new Photo();
PartyPhoto.prototype.constructor = PartyPhoto;
PartyPhoto.prototype.getDestinationPath = function() {
   return “./photos/parties”;
};

photo = new Photo();
photo.getDestinationPath(); // path for common photos

partyPhoto = new PartyPhoto();
partyPhoto.getDestinationPath(); // path for party photos

Encapsulation

In the examples above all attributes and methods were public. In order to declare private attributes or methods one solution is to follow the template code below: (taken from http://www.codeproject.com/KB/scripting/jsoops.aspx )

function MyClass(){    
   //Private members
   return{
       //Public members
   }
}

An App class can be implemented as:

function App(appname,description) {
   var _name = appname;
   var _description = description
   return {
       getName: function() { return _name; },
       getDescription: function() { return _description; },
       setName: function(appname) { _name = appname; },
       setDescription: function(description) { _description = description; }
   };    
}
var myApp = new App(“voila”,”my game”);
var.setName(“other game”);

Please note that this approach does not offer a way to have encapsulation and inheritance at the same time. Read next section to know one way to achieve this.

Inheritance with Encapsulation

By experimenting with the approach above, I found out a different way that made it possible to have both encapsulation and inheritance in JavaScript.
The idea is to declare private members as function variables as above and then augment the parent object with the desired public functions. Thus it is not necessary to work with prototypes.
Take the generic Person class as an example:
function Person(name) {
   // Private Members
   var _name = "";
   // Public Members (accesses private members)
   var obj = new Object();
   obj.setName = function(name) { _name = name; };
   obj.getName = function() { return _name;  };  
   // Constructor
   obj.setName(name);
   return obj;
};

A person instance will have access to getName and SetName but not _name attribute and therefore we have encapsulation.
For a Student class that inherits from Person, the code would be:
function Student(name,school) {
   // Private Members
   var _school = "";
   // Creating parent object: Studen inherits from Person
   var parent = new Person(name);
   // Augmenting parent object with Student methods
   parent.setSchool = function(school) { _school = school; };
   parent.getSchool = function() { return _school; };
   // Constructor Logic (Initialization)
   parent.setSchool(school);
   return parent;
};

These functions can be used just like normal classes:
var person = new Person("James");
person._name; // undefined
person.getName(); // James

var student = new Student("Jack","Orange City School");
student._name;        // undefined
student.getName();  // Jack
student._school;       // undefined
student.getSchool(); // Orange City School

Sunday, February 27, 2011

iPhone Development: to Objective-C or not to Objective-C ?

When I think of Objective-C, what comes to my mind is a niche programming language for the MacOS and Apple related products. Thus as far as I know this is the only officially supported language to develop products for iPhones, iPods, iPads and so on ....
On the other hand I really what to develop apps that will work in Windows, Linux and MacOS, and for this purpose I see two options:

1) Develop in C/C++ and try to find tools that translate this code to Objective-C and/or MacOS

2) Use Objective-C to develop any kind of application (at least desktop and mobile apps)

Developing portable iPhone apps outside Objective-C


Swig

For the first option, there is swig ( http://www.swig.org/ ) which is a wrapper for C++ to export its classes and/or functions to several languages (Objective-C is a work in progress).
However it doesn´t really solve the problem because there are libraries.

Mono Touch

The Mono Touch ( http://monotouch.net/ ) is probably one of the most interesting project to develop apps for the iPhone without Objective-C. It makes it possible to develop apps with C#.NET. The same Mono project also make it possible to develop apps for Linux. As a consequence, C#.NET could be seriously considered to develop apps for a wide range of platforms. However unlike Mono one must pay to start using it which may not be a problem if you are familiarized with C#.NET.

PhoneGap

Another options is PhoneGap ( http://www.phonegap.com ) which is an open-source framework whose objective is to let developers to write apps with HTML5+CSS+JavaScript and execute it to the different mobile platforms including iOS.

Objective-C as a portable programming language


I recently read about he mechanics and philosophy of Objective-C language and I got quite impressed by its features. It is not just C with classes as I heard before, it is actually a powerful dynamic language. Everything is an object including the classes itself what reminds me of Smalltalk, LISP and Python.

There are also some options to use Objective-C outside of the Apple ecosystem:

GNU Step

As stated in their website ( http://www.gnustep.org/ ) the objective is to create an open version of Cocoa (former NextStep) for several platforms including Linux and Windows.

Besides porting the API this project also comes with several developer tools such as an IDE named ProjectCenter and a GUI code generator called Gorm.

Publishing ClickOnce winforms applications with command-line MSBuild

One of the most interesting characteristics of tools such as CCNet and Nant is the automated deploy.

I found many examples of how to publish an application with pre-configured projects with click-one but I wanted to do it different.

In order to make the project file cleaner the approach was to remove all click-once configurations from the project(*.csproj) so that command-line MSBuild will take care of publication configuration in a NAnt script.

After some full-days of research, I found the solution below. I hope it helps in your project.


  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  

  
  
  
  

  
  

Thursday, June 03, 2010

Tools and Utilities for the .NET Developer

Here is a list I got from the internet that might be useful (at least for a while):

http://geekswithblogs.net/mbcrump/archive/2010/05/25/tools-and-utilities-for-the-.net-developer.aspx

Sunday, May 09, 2010

Using Fluent Builder Pattern to Configure Test Objects

Depending on the complexity of the domain model, configuring mock objects for specific cenarios can make the resulting test code to get messy.

Consider the situation below with C#, NUnit and Moq framework

[Test]
[ExpectedException(InvalidPaymentAgreementException)]
public void PaymentAgreementMustNotBeCreatedWhenThePaymentOptionIsNotValidForTheDebtType()
{
  Mock < PaymentOption > somePaymentOptionMock = new Mock < Paymentoption > ();

  Mock < DebtType > debTypeMock = new Mock < DebtType > ();
  debtTypeMock
    .Setup(debtType.GetPaymentOptions())
    .Returns(new List < PaymentOption > (){somePaymentOptionMock.Object});

  Mock < PaymentOption > anotherPaymentOptionMock = new Mock < PaymentOption > ();

  Mock < Debt > debtMock = new Mock < Debt > ();
  debtMock.Setup(debt.DebtType).Returns(debTypeMock.Object);            

  PaymentAgreement paymentAgreement = new PaymentAgreement(
    new PaymentAgreementCreationParameter()
    {
      AgreementYear = SystemDate.Get().Value.Year,
      AgreementNumber = 1,
      AgreementCreationDate = SystemDate.Get().Value.Date,
      NumberOfInstallments = 1,
      AgreementValue = 100.0m,
      Debts = new List < Debt > () { debtMock.Object },
      SelectedPaymentOption =  anotherPaymentOptionMock.Object
    });
}

A developer who reads the unit test can take a consirable amount of time to understand what is actually being tested even if a well-designed mock framework such as Moq is in use. Most of this work is about configuring mock objects. Besides the code size, the unit test doesn´t speak the language of the domain (business) and thus it becomes a mass of meaningless mock configuration.
I am on my way to learn how to apply TDD effectvely in software development and I quickly realized that the quality of unit tests are very important in order to this kind of methodology to succeed.

Accidentally some days I read an interesting post from Andrian about Rich Domain Tests at http://adrianhummel.wordpress.com/ and I decided to apply his idea.
After reading his post I got to the conclusion that one way to solve or at least minimize this unit-test-messy-code-problem was by using a fluent builder pattern to configure mock objects by using a builder whose interface could be describe how I am configuring a mock object with an interface closer to domain language.

The unit test below is a rewritten from the example above with the concepts described here:

[Test]
[ExpectedException(InvalidPaymentAgreementException)]
public void PaymentAgreementMustNotBeCreatedWhenThePaymentOptionIsNotValidForTheDebtType()
{
  PaymentOption somePaymentOption = PaymentOptionMockBuilder
                                    .Begin()
                                    .BuildPaymentOption();

  DebtType debtType = DebtTypeMockBuilder
                      .Begin()  
                      .AddPaymentOptionOf(somePaymentOption)
                      .BuildDebtType();
            
  PaymentOption anotherPaymentOption = PaymentOptionMockBuilder
                                       .Begin()
                                       .BuildPaymentOption();          
            
  Debt debt = DebtMockBuilder
              .Begin()
              .WithDebtTypeOf(debtType)
              .BuildDebt();

  PaymentAgreement paymentAgreement = new PaymentAgreement(
    new PaymentAgreementCreationParameter()
    {
      AgreementYear = SystemDate.Get().Value.Year,
      AgreementNumber = 1,
      AgreementCreationDate = SystemDate.Get().Value.Date,
      NumberOfInstallments = 1,
      AgreementValue = 100.0m,
      Debts = new List < Debt > () { debt},
      SelectedPaymentOption =  anotherPaymentOption
    });

}

The fluent builder for Debt is DebtMockBuilder and can be programmed as follows:

public class DebtMockBuilder
    {
        private Mock < Debt > _debtMock;

        public static DebtMockBuilder Begin()
        {
            DebtMockBuilder builder = new DebtMockBuilder();
            builder._ debtMock = new Mock < Debt > ();
            return builder;
        }

        public Debt BuildDebt()
        {
            return _debtMock .Object;
        }

        public DebtMockBuilder WithDebtTypeOf(DebtType debtType)
        {
            this._debtMock.Setup(debt => debt.DebtType).Returns(debtType);
            return this;
        }
    }

PaymentOptionMockBuilder follows the same idea.

Although I see that some improvements are needed I could see the following advantages from fluent mock builders:

  • The test code was easier to understand because domain terms were applied instead of specific API language.


  • Specific mock framework calls were encapsulated which theoretically can let programmers to use another mock framework in other projects or using more than one mock framework in the same test (I dont know why someone would do such a thing...).


  • Finally mock configuration becomes more flexible since existing methods don´t have to be modified to include new configuration but only a new configuration method is needed. Thus mock configuration can evolve as needed without loosing the domain interface.