Monday, November 12, 2012

Part IV Effective Java - Substitute for C Constructs

This is the fourth part in the series of posts based on the book Effective Java by Joshua Bloch. In the previous post we saw best practices of writing good classes and interfaces.

This section talks of how to convert C constructs to Java. The important section that everybody needs to look into is the Replace Enum constructs with Classes. This will apply to everybody trying to create an Enum.
Replace structures with Classes

The world of C has structures to represent complex data types. The equivalent of that in the Object Oriented world are classes. If a structure is translated to a class it will be a simple/trivial class in the Object Oriented world which will have only private attributes will potential getters and setters. Ideally one should not make the members public and use getters and setters as indicated above. Exception can be made if a class is private to a package or to another class the attributes may be made public as any change in the structure of the class will only have limited impact.

Replace unions with class hierarchies

In C it is possible to define Union which can hold more than one type of data or a set of bytes can be interpreted differently depending on the requirement. It is not possible to do this is Java in the same manner, i.e. no class can be used store different types of data at different points in time. Instead one should use a class hierarchy to represent unions. This will ensure that while we have a common interface using which we can access the set of classes each class can hold the different types of data. Some common data may be held in the common class.

Replace enum constructs with classes

Enums are used in C to represent constants values. It is also used to ensure that that only a right parameter value is passed to a function.
Concerting an enum of the type
typedef enum {SPADES, CLUBS, HEARTS, DIAMONDS} suits;
One way this can be implemented in Java is
public class PlayingCard {
    public static final int SUIT_SPADES = 1;
    public static final int SUIT_CLUBS = 2;
    public static final int SUIT_HEARDS = 3;
    public static final int SUIT_DIAMONDS = 4;
}
But in places where we need to pass a Suit Type to a function or get back a suit type we will end up sending an integer or getting back an integer. This does not ensure that we will get a right integer all the time. This problem can be avoided by using classes to define the suits.
E.g. we could create a class as follows:
public class Suit {
    private final String name;
    private Suit(String name) { this.name = name;}
    public static final Suit SPADES = new Suit(“Spades”);
    public static final Suit CLUBS = new Suit(“Clubs”);
    public static final Suit HEARTS = new Suit(“Hearts”);
    public static final Suit DIAMONDS = new Suit(“Diamonds”);
}
Since the constructor is private the developers cannot extend the class and cannot create instance of classes. Now in the places where we need to pass a Suit type or return a Suit type we can use this class. Also since there are only four instances of this class which we have defined we can be assured that we will never get a class other than one of these four. This also means that we can use the simple == operator for comparisons.

Replace Function Pointers with Classes and Interfaces

C has function pointers. This can be used to pass a comparator function to algorithms like qsort. But java does not support function pointers. The solution will involve defining an interface and then implementing a class that implements the interface. So for a qsort algorithm we can use the Comparable interface and define a class which defines the Comparable interface and defines the compare function which can be used by the qsort algorithm implementation.

In the next section we will see best practices in writing good methods in Java.

No comments: