giovedì 28 agosto 2014

Eat that cake!

Introduction

We know it: managing dependencies between software components within a project of magnitude rather than trivial could become a hell if not planned properly. Many of you will wonder why it is necessary to dwell too much on this topic. Responses to this question are two, namely:
  1. low grade of coupling;
  2. high grade of cohesion.
The minimization of dependencies between software components enables greater maintainability, and enhances software testability, cleanliness and elegance. A high cohesion allows us to join one of the basic principles of software development, the DRY principle, “Don't Repeat Yourself”. So, the minimization of dependencies is a goal to be pursued at all levels.

For example, let’s analyze a classic software problem: a repository class (UserRepository), which enables access to information stored on database, and a service class (UserService) that allows the use of this information to other components.
Clearly, the direct association between these two elements creates a high level of coupling between them. In particular UserService is responsible for creating an instance of UserRepository, tying the evolution of UserService in the evolution of the UserRepository code. In addition, it is complex to design any unit tests, which would require the replacement of a UserRepository with a mock in UserService code.

You can improve the situation by abstracting the UserRepository component in an interface and changing the dependency in the UserService towards this interface.
This new configuration enables the use of dependency injection (DI) pattern. DI is a design pattern that helps to separate the behavior of a component from the responsibility for resolution of its dependencies.

For strongly typed object-oriented languages, you must use an external framework that handles and resolves the dependencies. These dependencies are suitably configured by the developer and framework uses these information to operate like a factory, managing the complete life cycle of software components.

In Java, for example, the most commonly used DI frameworks are Spring (http://spring.io/) and Guice (https://github.com/google/guice).

Cake pattern

Scala provides a mechanism to resolve dependencies similar to DI, the cake pattern. Unlike DI pattern in other languages, such as Java, C++, etc ... the cake pattern can be used directly with language constructs available in Scala.

Traits

In Scala the cake pattern is made possible by the presence of the construct of the trait. A trait is similar to a Java interface, but unlike the latter it can have both attributes, both methods completely implemented.

A trait also has a key feature for the cake pattern: can be "added" to any component as a mixin. In this way the attributes and methods of the trait are added to those of the component. This makes it possible to implement some kind of multiple inheritance, that is not allowed in other programming languages.

Self-type annotation

The Self-type annotation is a special construct that allows you to declare the dependencies of a component from one or more trait, i.e. which trait should be associated with the component using mixin. For example, consider the following class BarAble and trait FooAble.
trait FooAble {
  def foo() = “I am a foo!”
}
class BarAble { this: FooAble =>   // self-type annotation
  def bar = “I am a bar and “ + foo()
}
Using the notation this: => FooAble we mean that an object of class BarAble must be associated with trait FooAble using mixin.
object Main {
  def main(args: Array[String]) {
    val barWithFoo = new BarAble with FooAble   // mixin
    println(barWithFoo.bar())
  }
}
In order to instantiate the object barWithFoo, the compiler checks the dependencies declared through mixin and if these are not met it will provide the following error:

“class BarAble cannot be instantiated because it does not conform to its self-type BarAble with FooAble”

The full recipe

Trait and self-type annotation are the foundation of the cake pattern. Return to the main problem, namely the resolution of dependence between the class UserService and the class UserRepository. An elegant solution to the problem must not modify these two classes, maintaining isolated and distinct business aspects from more technical aspects. For this reason, we define two traits whose aim is to enclose the original classes in components more malleable, like layers of a cake.
trait UserRepositoryComponent {
  val userRepository: UserRepository
  class UserRepository {
    def findAll() = Array[User]()   // fake implementation
    def save(user: User) = “Saving a user...”   // fake implementation
  }
}
trait UserServiceComponent { this: UserRepositoryComponent =>
  val userService: UserService
  class UserService {
    def findAll() = userRepository.findAll
    def save(user: User) = userRepository.save(user)
  }
}
In each of the new trait original classes are made available through an internal attribute. Note that an attribute (val) has been preferred to a function (def) because both service and repository are Singleton classes: they require no more than one active instance within an application. Also, note that both traits are abstract, since internal class instances are not initialized.

Note in particular the latter trait, i.e. UserServiceComponent. Through the use of a self-type annotation is declared the dependency upon trait UserRepositoryComponent, through which UserService class can access the userRepository. In case you need to declare multiple dependencies this process can be repeated, using a notation such as
this: A with B with C =>
which A, B and C are traits similar to UserRepositoryComponent.

So we have built a mechanism for declaring dependencies among components. We need to take the last few steps and implement the real mechanism of dependency injection: the implementation of abstract trait; their composition, which allows the resolution of dependencies.

Let’s build a configuration object, implementing concrete instances of classes UserRepository and UserService.
object ComponentRegistry extends 
  UserServiceComponent with UserRepositoryComponent {
  // Dependency injection
  val userRepository = new UserRepository
  val userService = new UserService
}
The dependencies are resolved in one single place and can be modified using subclassing, simplifying unit testing and mocking.

In case you want to replace the dependency to the UserRepository class with a pure interface, you can provide a trait within UserRepositoryComponent, which will be concretely implemented later.
trait UserRepositoryComponent {
  def userRepository: UserRepository
  trait UserRepository {
    def findAll() 
    def save(user: User)
  }
}

References

domenica 10 marzo 2013

Javascript MVC frameworks

It’s hard to admit, but I must change my mind about Javascript MVC frameworks. If someone had told me how good were the MVC framework on the client side only a few years ago, I would have probably said that she understood nothing of software architectures. Now that my experience is growth a little, I find that a good Javascript MVC framework is a must.

ROA example
A scheme of ROA based applications
In a world where datas and resources need to be accessed by different applications, designed and coded in different ways, the only chance we have to survive is to use Resource Oriented Architetures (ROAs). In this kind of architecture, datas and resources are exposed to clients (such as iOS and Android applications, Javascript webapps, etc...) via ReST API. Obviously, every type of these clients has to be designed using design patterns, frameworks, etc…One of the most known architectural design pattern is the Model View Control pattern (MVC).

Because the model can’t be part of a client in this kind of architecture, we have to substitute it with a surrogate. This surrogate has to be synchronized with the real model through the ReST APIs. So, why don’t we use a framework and let do all the dirty job to it?

There are a lot of Javascript MV* framework, such as Backbone.js, Angular.js (sponsored by Google), Ember.js, etc…Any of these frameworks has its own peculiarities. So, how can we choose the one that best fits our needs? Todo MVC (http://todomvc.com/) will help us! Todo MVC is a site in which we can find a simple TODO application developed in each of the best Javascript MV* frameworks.

That's great!



mercoledì 6 marzo 2013

Introducing myself...

Hi everyone,

What is a Big ball of mud?! It is the tipical anti-pattern that you can find realized in many software products (ref. Wikipedia):
A big ball of mud is a software system that lacks a perceivable architecture. Although undesirable from an engineering point of view, such systems are common in practice due to business pressures and developer turnover
A software architecture such this one generates frustration both to software architects and to business men. It is the absolute evil, the kind of mistake that every designer has to avoid.

So, it is important that every software architect and developer learns very well solutions architects with more experience found in their career. It is important to create a knowledge base of software engineering. I perfectly know that this is impossible and that I am not the right person to accomplish this task. But, I am sure that I can make this world a better world.

Currently I am a senior Java developer for an italian system integrator and I am contract professor of the Software Engineering course at Department of Mathematics of University of Padua, Italy.

But, first of all I am a NERD, completely addicted to computer science.

Riccardo
--

(Thanks to xkcd.com to exist)