Sunday, May 19, 2013

Desing Patterns in Java - builder pattern

Static factories and constructors share a limitation: they do not scale well to large
numbers of optional parameters.
Consider the case of computer configuration builder. There are parts that are essential in this build, but also there are optional parts.

There number of ways that developers usually try to approach this problem. First is  telescopic constructors where you need to create constructor for each of optional parameter. This approach has obvious disadvantages (ugly code, lot of work). Second approach is to use JavaBeans in which you call a parameterless constructor to create the object and then call setter methods to set each required parameter and each optional parameter of interest. There are two problems with this approach. First is that JavaBean may be in an inconsistent state partway through its construction. Second is that this pattern pre-cludes the possibility of making a class immutable.
There is however third approach that is very elegant and can create immutable objects. It is a form of the Builder pattern.Instead of making the desired object directly, the client calls a constructor (or static factory) with all of the required parameters and gets a builder object. Here is how it looks like:
public class ComputerConfigurator {    
    private final int sizeOfRam;
    private final int sizeOfHdd;
    private final int processorSpeed;    
    private final int dedicatedGpuSpeed;
    private final boolean waterCooling;
    
    public static class Builder {
        //Required params
        private final int sizeOfRam;
        private final int sizeOfHdd;
        private final int procesorSpeed;        
        //Optional params
        private int dedicatedGpuSpeed;
        private boolean waterCooling;

        public Builder(int sizeOfRam, int sizeOfHdd, int procesorSpeed) {
            this.sizeOfRam = sizeOfRam;
            this.sizeOfHdd = sizeOfHdd;
            this.procesorSpeed = procesorSpeed;
        }
        
        public Builder dedicatedGpuSpeed(int val) {
            dedicatedGpuSpeed = val;
            return this;
        }
        
        public Builder waterCooling(boolean val) {
            waterCooling = val;
            return this;
        }
        
        public ComputerConfigurator build() {
            return new ComputerConfigurator(this);
        }
        
    }
    
    private ComputerConfigurator(Builder builder) {
        sizeOfRam = builder.sizeOfRam;
        sizeOfHdd = builder.sizeOfHdd;
        processorSpeed = builder.procesorSpeed;
        dedicatedGpuSpeed = builder.dedicatedGpuSpeed;
        waterCooling = builder.waterCooling;
    }
}
The builder’s setter methods return the builder itself so that invocations can be chained. Here’s how the client code looks:
public class Main {
    
  public static void main(String[] args) {
    ComputerConfigurator firstComputerConfigurator = new ComputerConfigurator.
            Builder(2, 40, 3000).
            dedicatedGpuSpeed(1000).build();
        
    ComputerConfigurator secondComputerConfigurator = new ComputerConfigurator.
            Builder(2, 40, 3000).
            dedicatedGpuSpeed(1000).waterCooling(true).build();
  }    
}

Saturday, May 18, 2013

Desing Patterns in Java - Visitor

Visitor lets you define a new operation (method) on object without changing the classes (interface) of the elements on which it operates. This is the essence of visitor patter. The name "Visitor" is misleading and this pattern has noting to do with visiting, iteration or something like that. If you need to perform operations across a disparate set of objects, Visitor might be the pattern for you. Let see how does it work.

So let's presume we have have some disparate object structure and we want to run one operation on each object of this structure.
Here is how it works then:
The core of this pattern is Visitor interface. This interface defines a visit operation for each type in the object structure. The object (one object from structure) interface simply defines an accept method to allow the visitor to run some action over that object. This operation is here to to allow the visitor access to the object.

Here we have example that will calculate average Per Seat Fuel Economy for different type of vehicles. Calculation is quite simple: consumption / number of seats. Each of vehicle is represented with simple POJO's. Each of this object have one accept method so we have access to object through unified interface.

Interfaces:
public interface Visitable {
    
    void accept(Visitor visitor);
    
}

public interface Visitor {
    
    void visit(Bike bike);
    void visit(Bus bus);
    void visit(Car car);
    
}
Simple POJO's.
public class Bike implements Visitable {
    
    private int consumption;
    
    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }
    
    public Bike(int consumption) {
        this.consumption = consumption;
    }
    
    public int getConsumption() {
        return consumption;
    }  
            
}

public class Bus implements Visitable {
    
    private int numberOfSeats;
    private int litersConsumption;

    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }
    
    public Bus(int numberOfSeats, int litersConsumption) {
        this.numberOfSeats = numberOfSeats;
        this.litersConsumption = litersConsumption;
    }
   
    public int getNumberOfSeats() {
        return numberOfSeats;
    }

    public int getLitersConsumption() {
        return litersConsumption;
    }   
    
}

public class Car implements Visitable {
    
    private int consumption;
    private int weight;
    private int seats;
    
    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }

    public Car(int consumption, int weight, int seats) {
        this.consumption = consumption;
        this.weight = weight;
        this.seats = seats;
    }    
    
    public int getConsumption() {
        return consumption;
    }
   
    public int getWeight() {
        return weight;
    }

    public int getSeats() {
        return seats;
    }
}
Although this objects don't know how to calculate average per seat consumption we will learn them how to do that without even touching them:
public class EfficiencyVisitor implements Visitor {
    
    private int efficiency;
    
    @Override
    public void visit(Bike bike) {
        efficiency += bike.getConsumption() / 2;
    }

    @Override
    public void visit(Bus bus) {
        efficiency += bus.getLitersConsumption() / bus.getNumberOfSeats();
    }

    @Override
    public void visit(Car car) {
        efficiency += car.getConsumption() / car.getSeats() ;
    }

    public int getEfficiency() {
        return efficiency;
    }     
    
}
Client:

public class Main {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        
        int averageConsumptionPerSeat = 0;
        
        List <Visitable> vehicles = new ArrayList<>();
        
        Car mazda = new Car(6, 1024, 5);
        vehicles.add(mazda);
        Car skoda = new Car(7, 1200, 4);
        vehicles.add(skoda);
        Bus merc = new Bus(60, 30);
        vehicles.add(merc);
        Bike suzuki = new Bike(4);
        vehicles.add(suzuki);
        
        EfficiencyVisitor efficiencyVisitor = new EfficiencyVisitor();
        
        for (Visitable vehicle : vehicles) {
            vehicle.accept(efficiencyVisitor);
            averageConsumptionPerSeat += efficiencyVisitor.getEfficiency();
        }
        
        System.out.println(averageConsumptionPerSeat / vehicles.size());
    }
}

Best thing about this is that we can easily add new vehicle types or change existing methods without changing interface or methods on "old" vehicle types.

The whole point of this pattern is to clean up your code. It allow you to separate  certain logic from the elements themselves, keeping your data classes simple.

Sunday, May 5, 2013

Google App Engine channel API in Java (push)

Google App Engine uses long polling as a push technology.

It uses two HTTP connections to the server. When the client has data to send to the server, it initiates an HTTP connection and posts the data to the server. The client also maintains a long-lived HTTP connection to the server that the server uses to return data back to the client. We refer to the first type of connection as the send channel and the second type of connection as the receive channel. Together these two unidirectional channels provide a bidirectional channel of communication between the browser and the server.

In this example we will use GAE push technology support (it however doesn't support full duplex communication, client send HTTP POST request on the server). It is kind of slow, but I think that it is sufficient for non-aggressive client state refresh.

I created some example on GAE, here is youtube video. In this example you can see update of four separate clients. Each client paints canvas with different color.

 

Also you can try it online here: http://codingwithpassion.appspot.com/dots
Delete cookies when you want to restart application.


There are several moving parts you need to orchestrate when developing push capable application. Client side should listen for changes and to update view. Second responsibility for client is off course to send messages to server when client state changes. It should look something like this:
//some demolib for this example
var demolib = {};  
demolib.sendMessage = function(path, opt_params) {      
    if (opt_params) {
      path += opt_params;
    }
    var xhr = new XMLHttpRequest();
    console.log("Posting: " + path)
    xhr.open('POST', path, true);
    xhr.send();
};    
demolib.writeCircle = function(xPos, yPos, color) {
    var canvas = document.getElementById('simpleCanvas');
    var context = canvas.getContext('2d');
    var radius = 10;          
    context.beginPath();
    context.arc(xPos-radius, yPos-radius, radius, 0, 2 * Math.PI, false);
    context.fillStyle = color;
    context.fill();
    context.lineWidth = 5;
    context.strokeStyle = '#003300';
    context.stroke();
};
demolib.onOpened = function() {
 demolib.sendMessage('/opened');
};
demolib.onMessage = function(m) {
 var newState = JSON.parse(m.data);
 if (newState.color != '${color}') {
  demolib.writeCircle(newState.x, newState.y, newState.color); 
 }     
};
demolib.openChannel = function() {
    var token = "${token}";
    var channel = new goog.appengine.Channel(token);
    var handler = {
      'onopen': demolib.onOpened,
      'onmessage': demolib.onMessage,
      'onerror': function() {},
      'onclose': function() {}
    };
    var socket = channel.open(handler);
    'onopen' = demolib.onOpened;
    socket.onmessage = demolib.onMessage;
};
demolib.init = function() {
    demolib.openChannel();
    var canvas = document.getElementById('simpleCanvas');     
    canvas.onclick = function(e) {      
        var centerX = e.pageX - canvas.offsetLeft;      
   var centerY = e.pageY - canvas.offsetTop;
   var token = "${token}";
   var color = "${color}";
   console.log(centerX + ' ' + centerY);
    
   demolib.writeCircle(centerX, centerY, color);
   demolib.sendMessage('/play', '?x='+centerX+'&y='+centerY+'&color='+color);
    };
    demolib.onMessage();
}();    
Then on server side, you need to create channel for each client. In this example we are using user session to manage clients. Only new clients from same IP are allowed (to differentiate between clients and to make this example simple as it can be).
public void doGet(HttpServletRequest req, HttpServletResponse resp)
 throws IOException {   
 try {
  HttpSession session = req.getSession();
  Integer colorIndex = (Integer)session.getAttribute(DotsServlet.COLOR_INDEX_ATTRIBUTE);
  colorIndex = colorIndex != null ? colorIndex + 1 : 0;
  if (colorIndex > Color.size() - 1) {
   noMoreClients(resp, Color.size());    
  } else {   
   session.setAttribute(DotsServlet.COLOR_INDEX_ATTRIBUTE, colorIndex);   
   Color color = Color.getColorByIndex(colorIndex);    
   String ipAddress = Game.getClientIpAddr(req);
   ChannelService channelService = ChannelServiceFactory.getChannelService();   
   String token = channelService.createChannel(color + ipAddress);
   req.setAttribute("token", token);
   req.setAttribute("color", color.toString());
   req.getRequestDispatcher("/jsp/htmlsocket/dots.jsp").forward(req, resp);
  }
 } catch (ServletException exc) {   
  exc.printStackTrace();
 }
}
After each message from client, you need to update each client. We are updating each client for current IP. Something like this:
for (int i = 0; i <= colorIndex; i++) {  
 String user = Color.getColorByIndex(i).toString();
 ChannelService channelService = ChannelServiceFactory.getChannelService();
 String ipAddress = Game.getClientIpAddr(request);
 String channelKey = user + ipAddress;
 channelService.sendMessage(new ChannelMessage(channelKey, getMessageString(x, y, color)));
}
That's basically it. You can also update each client when new client is connected using socket.onopen.