Ward Cunningham - the guy that developed first wiki and is also know as a pioneer in both design patterns and Extreme Programming gave a great interview on QCon.
On 18 minute he start speaking about Agile, code review, knowledge sharing and how through Agile We (IT guys) overcome software crisis and now other departments in organization want to learn lessons from IT and Agile.
Also here you can find interview with Barbara Liskov that she gave on Qcon. She's talking about Liskov substitution principle and distributed system.
If you don't know her, She is Turing Award winner and first person (with her students) that join abstracted data types with operations (basically she paved roads for OOP as we know it today).
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();
}
}
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.
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.
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.
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).
Facade Pattern is structural pattern. It basically hide complexity, so I tend to call it "good sense pattern". It also decouples code, which is good thing. But you should not overuse Facade pattern in your applications.
Similar like to much abstraction is considered harmful for code readability, same thing apply to too much simplification (because you basically add layer on top layer and you introduce complexity).
Session facade is useful in situations where it encapsulate the complexities between the client and the server interactions. It manages business objects and provides uniform service access layer to clients. It basically represent centralized peace that minimize method calls over network, exposes uniform interface and managing security and transactions in one place.
ThreadLocal special kind of scope of access. When you put some object or value to this scope on some thread, then this object will be local to that thread. This means that each thread will have it’s own
ThreadLocal variable or reference to some object. One thread can not access/modify other thread’s ThreadLocal variables.
Another important aspect of ThreadLocal is its global access. This means that each method that thread is using can get value/reference from ThreadLocal scope. So, if a thread calls methods from several classes, then all the methods can see the ThreadLocal variable set by other methods.
Use cases of ThreadLocal
ThreadLocals are usally used in Web Applications, specifically in Servlets. For example you have servlet that is processing some request and you want this request object HttpServletRequest to be accesable in services this servlet is using, but you don't want to send it as parameters in method calls. Because each request is usually processed using separate thread we want to have request object bind
to that thread.
We can do this using Thread Local because ThreadLocal is only valid for the duration of the request.
Another use case for ThreadLocal would be as an alternative to an object or resource pool, when we don't mind creating one object per thread. This should be non-trivial objects that have no requirement to be shared among different threads.
Java provides an ThreadLocal object using which you can set/get thread scoped variables.
You just simply create ThreadLocal object and then use set, remove and get methods.