Wednesday, January 27, 2016

Abstract Factory Design Pattern


Abstract Factory pattern can come really handy when creating sets of related objects. It allows developpers to take advantage of two of the key features of Object Oriented Design to create objects: Polymorphism and Abstraction. Polymorphism is the ability of an object to take many forms. it's done through inheritance. For example, charachteristics of a diesel engine are different from a gasoline engine, but both of them have common functionality such as start, and stop. Abstraction allows hiding functionality of an object. It allows the separation of the implementation from the object itself. It's provided though interfaces and abstract classes. In this tutorial, we will go through how to implement the abstract factory design pattern in Java. Abstract Factory allows the creation of different factories that will be later used to create objects. In other terms, Abstract Factory can be refered to as a Factory of Factories.

Suppose we want to assemble a car with an Engine, and a Gear. an Engine can be either Diesel or Gasoline and a Gear can be either Manual or Automatic.  A car needs an engine and a gear to be assembled. It does not care about what type of Engine and Gear it is using. We will start first of all by designing our abstract engine and gear, and then extend them to define our specific types.

Engine.java
public abstract class Engine {
 
 public abstract void buildEngine();
 public abstract void testEngine();

}

Gear.java
public abstract class Gear {
 
 public abstract void buildGear();
 public abstract void testGear();

}
Now we are going to extend Engine to create DieselEngine and GasolineEngine:
DieselEngine.java
public class DieselEngine extends Engine {

 @Override
 public void buildEngine() {
  System.out.println("Building Diesel Engine");
  
 }

 @Override
 public void testEngine() {
  System.out.println("Testing Diesel Engine");
  
 }

}
GasolineEngine.java
public class GasolineEngine extends Engine {

 @Override
 public void buildEngine() {
  System.out.println("Building Gasoline Engine");
  
 }

 @Override
 public void testEngine() {
  System.out.println("Testing Gasoline Engine");
  
 }

}
We need to extend Gear as well to create ManualGear and AutomaticGear:
AutomaticGear.java
public class AutomaticGear extends Gear {

 @Override
 public void buildGear() {
  System.out.println("Attaching Automatic Gear");
  
 }

 @Override
 public void testGear() {
  System.out.println("Testing Automatic Gear");
  
 }

}
ManualGear.java
public class ManualGear extends Gear {

 @Override
 public void buildGear() {
  System.out.println("Attaching Manual Gear");
  
 }

 @Override
 public void testGear() {
  System.out.println("Testing Manual Gear");
  
 }

}
Our car object needs an Engine and a Gear regardless of whether the engine is diesel or automatic and whether the gear is manual or automatic:
Car.java
public class Car {
 
 Engine engine;
 Gear gear;
 
 public Car(Engine engine, Gear gear){
  this.engine = engine;
  this.gear = gear;
 }
 
 public void assemble(){
  System.out.println("-----------Starting car assembly");
  engine.buildEngine();
  gear.buildGear();
  System.out.println("-----------car assembly done");
 }
 
 public void test(){
  System.out.println("-----------Starting car tests");
  engine.testEngine();
  gear.testGear();
  System.out.println("-----------car tests done");
  
 }

}
Now, we need a method to create "Engines" and "Gears". We can go ahead and just instantiate the objects using their constructors, but there is a more classy way to do it. Since our objects are related, we can use one factory to generate them. We need a flexible factory that can generate both types. In other words, we need an abstract form of a factory that can be extended/implemented.
AbstractFactory.java
public abstract class AbstractFactory {
 abstract Engine getEngine(String engineType);
 abstract Gear getGear(String gearType); 
}
We can extend our factories as needed :
EngineFactory.java
public class EngineFactory extends AbstractFactory {

 @Override
 Engine getEngine(String engineType) {
  
  
  if(engineType.equals("Diesel")){
   
   return new DieselEngine();
   
  }else if(engineType.equals("Gasoline")){
   return new GasolineEngine();
  }
  return null;
 }

 @Override
 Gear getGear(String gearType) {
  //Not needed for Engine
  return null;
 }

}
GearFactory.java
public class GearFactory extends AbstractFactory {
 @Override
 Engine getEngine(String engineType) {
  //Not needed
  return null;
 }

 @Override
 Gear getGear(String gearType) {
  // TODO Auto-generated method stub
  if(gearType.equals("Manual")){
   return new ManualGear();
  }else if(gearType.equals("Automatic")){
   return new AutomaticGear();
  }
  return null;
 }

}
Finally, we need a factory producer that will create the needed factory depending on the class of the object: Gear or Engine.
FactoryProducer.java
public class FactoryProducer {
 public static AbstractFactory getFactory(String factoryType){
  if(factoryType.equals("Engine")){
   return new EngineFactory();
  }else if (factoryType.equals("Gear")){
   return new GearFactory();
  }
  return null;
 }
}
To test our Abstract Factory pattern we can do something like :
public class Test {
 public static void main(String[] args) {  
  AbstractFactory engineFactory = FactoryProducer.getFactory("Engine");
  AbstractFactory gearFactory = FactoryProducer.getFactory("Gear");
  
  Engine dieselEngine = engineFactory.getEngine("Diesel");
  Engine gasolineEngine = engineFactory.getEngine("Gasoline");
  
  Gear manualGear = gearFactory.getGear("Manual");
  Gear automaticGear = gearFactory.getGear("Automatic");
  
  Car car1 = new Car(dieselEngine, manualGear);
  Car car2 = new Car(gasolineEngine, automaticGear);
  
  car1.assemble();
  car1.test();
  
  car2.assemble();
  car2.test();

 }

}
Result:
As you can see, we have abstracted out Engine and Gear using a Factory and hidden their implementation from Car. Car only executes their methods.

Full example at: https://github.com/zak905/java8features/tree/master/src/opencode/designpatterns/abstractfactory

Sunday, January 10, 2016

Implementing Hypermedia (Hateoas) for a Rest Application in Spring


Hypermedia (Hateoas) is considered not only a good practice but also an important aspect of Rest APIs design. It allows better decoupling of resources and subresources and better optimization of the data sent by the server. Suppose we have a resource with a long list of subresources, it would be overwhelming to have all the data sent in one request, while the user only needs data in couple of fields. Hypermedia allows to add links to subresources to the resource. In this tutorial, we will demonstrate how to implement Hatoeas in a Spring Rest based application.

Requirements:
Spring (MVC, Core, Hateoas,...), full list of dependencies can be found here.
Eclipse or any other IDE
Jetty plugin


We have already covered in a previous tutorial how to create a Rest application in Spring, so I suppose you already have that part covered. Suppose we have an object like this:

public class Person {
 private String firstname;
 private String lastName;
 private int age;
 private String departement;
 private Account account;
 private Profile profile;
 
 public Person(){
  
  
 }
 
 /**
  * @return the firstname
  */
 public String getFirstname() {
  return firstname;
 }
 /**
  * @param firstname the firstname to set
  */
 public void setFirstname(String firstname) {
  this.firstname = firstname;
 }
 /**
  * @return the lastName
  */
 public String getLastName() {
  return lastName;
 }


 /**
  * @param lastName the lastName to set
  */
 public void setLastName(String lastName) {
  this.lastName = lastName;
 }


 /**
  * @return the age
  */
 public int getAge() {
  return age;
 }

 /**
  * @param age the age to set
  */
 public void setAge(int age) {
  this.age = age;
 }

 /**
  * @return the departement
  */
 public String getDepartement() {
  return departement;
 }

 /**
  * @param departement the departement to set
  */
 public void setDepartement(String departement) {
  this.departement = departement;
 }

 public Account getAccount() {
  return account;
 }

 public void setAccount(Account account) {
  this.account = account;
 }

 public Profile getProfile() {
  return profile;
 }

 public void setProfile(Profile profile) {
  this.profile = profile;
 }
Notice that person has a Account and Profile objects as fields (or subresource):

public class Account {
 
 private String username;
 private String password;
 
 public String getUsername() {
  return username;
 }
 public void setUsername(String username) {
  this.username = username;
 }
 public String getPassword() {
  return password;
 }
 public void setPassword(String password) {
  this.password = password;
 }
 

}
public class Profile {
 
 private String description;
 private String interests;
 private String activities;
 
 
 public String getDescription() {
  return description;
 }
 public void setDescription(String description) {
  this.description = description;
 }
 public String getInterests() {
  return interests;
 }
 public void setInterests(String interests) {
  this.interests = interests;
 }
 public String getActivities() {
  return activities;
 }
 public void setActivities(String activities) {
  this.activities = activities;
 }
}
Without using Hateoas the Rest representation of our resource is:

You can notice that we have both the data of the profile and the account sent with the Request. So, we need to change these two subresources to links and add the links to the controller.

First, our main resource needs to extend ResourceSupport which used for setting links in a resource object.

public class Person extends ResourceSupport

Also we are going to ignore both the profile and the account subresources so that they are not sent with the resource using Jackson's @JsonIgnore. 


@JsonIgnore
public Profile getProfile() {
 return profile;
 }

@JsonIgnore
public Account getAccount() {
 return account;
 }
We need also to modify our controller accordingly:

@Controller
@RequestMapping("/person")
public class PersonController {
 
 @RequestMapping(value="{id}", method= RequestMethod.GET)
 public @ResponseBody Person getPerson(@PathVariable Integer id){
  ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
  PersonRepository repository = context.getBean(PersonRepository.class);
  
  Person person = repository.retrieve(id);
  
  person.add(linkTo(PersonController.class).slash(id).withSelfRel());
  person.add(linkTo(PersonController.class).slash(id).slash("account").withRel("account"));
  person.add(linkTo(PersonController.class).slash(id).slash("profile").withRel("profile"));
 
  return person;
 }
 
 @RequestMapping(value="{id}/profile", method=RequestMethod.GET)
 public @ResponseBody Profile getProfile(@PathVariable Integer id){
  ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
  PersonRepository repository = context.getBean(PersonRepository.class);
  
  Person person = repository.retrieve(id);
  
 
  return person.getProfile();
  
 }
 
 @RequestMapping(value="{id}/account", method=RequestMethod.GET)
 public @ResponseBody Account getAccount(@PathVariable Integer id){
  
  ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
  PersonRepository repository = context.getBean(PersonRepository.class);
  
  Person person = repository.retrieve(id);
  
 
  return person.getAccount();
 }

You can notice that we have added three links to the Person's resource in the method getPerson() , one that links to self, one for Account, and one for Profile. The reason we have added a link of the resource to itself is that, by convention, the link to self provides more detailed data about the object. But in our case, the self link references the same thing as the current resource. Now, if we request our resource in http://localhost:8080/person/2, the sent data will look something like:


Now if you go to the link of Person's account: http://localhost:8080/person/2/account, the sent data will be only for the account:


Full example can be found here: https://github.com/zak905/rest-spring-example