Friday, July 26, 2013

Java: Sockets

Socket, defined by Oracle document, is one endpoint of a two-way communication link between two programs running on the network. A socket is bound to a port number so that the TCP layer can identify the application that data is destined to be sent.

What does this really mean?

Photo from The Bowery Boys

Imagine it is 1850. Rowland Hussey Macy, Macy's' store owner, is walking down the street of NYC when he notices strings hanging from several apartment complexes. 

"Excuse me, do you know what those strings are?" he asked a passerby. 

"They are can telephone lines. You attach cans to each end of the line and used it to talk to one another." 

"Intriguing. How far does it travel?"

"About half a mile." 

"Half a mile? I wonder....."

Photo by Jin Choi

As Mr. Macy walks back to the office, a plan begins to formulate. Two months later, he rented a small office across from Central park. The office has a window where people can come and request to talk to a representative. Because the window is small, only one person can come to the window at a time. To serve multiple clients at a time, Mr. Macy has the brilliant idea of using the can telephones. When a client needs to speak to a representative, she comes to the window. The representative at the window will give her a can telephone. She can use the telephone to speak with a representative inside of the office. This way, while Mary is talking on the side with one representative, Tom can comes to a window and request to speak to another. When Mary is done, she returns the can telephone so others can use it. 

Photo from Wiki

That is how I understand the socket. The building Mr. Macy rent is like the computer. It has many windows for many businesses. Macy can rent office 1 while Kohl rents office 2. The computer is the same way. It has many ports where an application can "rent/reserve" ports. From 0 - 1023, these ports are always in use, aka lifetime renter. You can't use these. But your application can rent any other ports from 1024+. Once you tell the computer you are using that port, no one else can use it. When a client need to speak to your application, it goes to the port that you "rent".



When you create a server, you need to create a ServerSocket. This socket is like the representative at the window, he is responsible for opening and closing the window(/port) and assigning request. He can also handle request, but if he is handling request, then no one will be able to speak to him, so it's best to hand the job to someone else.

The normal sockets are like the can telephones. When the client comes to your "window", you assigned a specific can telephone to him/her. That way, you can communicate freely. If I speak to socket one, I know I am talking to John because I assigned him that line. If I don't have sockets, I wouldn't know who I am talking to. When John is done talking to me, or I to him, we must close the socket so we can free up resources for other user. You can only talk to the client once.

This is what my server class looks like. Currently it accepts one client, returns "Hello, world!", then closes the sockets. After you run it, you can open your browser and go to http://localhost:4000 to see "Hello, world!"
import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {

    public static void main(String[] args) throws IOException {
        Server server = new Server();
        server.start();
    }

public void start() {
        try {
           ServerSocket serverSocket = new ServerSocket(4000); //Representative at the window
            Socket clientSocket = getSocket().accept(); //Socket assign to client
            PrintWriter response = new PrintWriter(clientSocket.getOutputStream(), true); //get translator
            response.println("Hello, world!"); //Talk to client
            response.close(); 
            clientSocket.close(); //Return can telephone
            getSocket().close(); //close your window
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
One thing to note is the PrintWriter. When you call clientSocket.getOutputStream(), what you have to send to OutputStream are bytes. So PrintWriter is like a translator. You say, here's a string, translate it to bytes and give it to output stream.

Wednesday, July 10, 2013

SOLID: Single Responsibility Principle (SRP)


Even after five years of programming, I am still struggling with this principle. I don't know how to determine if a method is part of the class responsibility. In the Agile Software Development Principles, Patterns, and Practices book, Uncle Bob has this class structure:

At first glance, the design feels ok to me. The Rectangle class has an area and it knows how to draw itself. In my Tic Tac Toe, I have a similar logic for the players. I let the players give me a move by injecting a strategy in the player class. For a computer player, that means using minimax strategy. For a human player, a console "strategy" which really means display a message to the user to get the user input. This felt like a good design because the game doesn't have to worry about getting input. It doesn't even know what type of players it has.

However, after I watched the Clean Coder video, I understood what Uncle Bob means when he said it should change for one, and only one reason. Instead of thinking about responsibility, think about who uses the methods in the class. For example, look at this this class:
public class Employee {
  public Money calculatePay()
  public String reportHours()
  public void update()
  public void add()
}

Who will use these methods?

  • Someone who needs to know how much to pay the employee (aka payroll system)
  • Someone who needs to add/update the employee information

When you think about it that way, you can clearly see that these methods should be in two classes. And it makes sense because if you change the database schema, update() and add() need to know about it. But that doesn't have anything to do with reported hours or pay calculation.

Looking back at the graph, I can see why that is a violation of the single responsibility principle. The draw method uses the GUI and the computational class uses area. The application also uses the GUI. So when the GUI change, Rectangle has to change even though the area code didn't.

As for my Tic Tac Toe program, maybe it's ok because the class that gets the move is the strategy class, and the strategy only have one reason to change, which is how it gets the player's move.