The Software Purist |

CAT | Java

Jun/11

19

Conditional Compilation in Java

I wanted to share a trick I learned a while back, that is pretty useful. Personally, I’m not a fan of including code in your executable/bytecode that is never used, because it has the risk of exposing additional implementation, and generally makes for larger DLLs/Jars. One nice thing I can say about C# is that they did not completely remove the idea of conditional compilation. In C#, you can do the following:


#define LETS_DANCE

...

#if LETS_DANCE
// ... do something ...
#endif

However, C#’s conditional compilation is completely restricted to only being able to define a boolean, where the existence of the preprocessor symbol means it exists, and otherwise, it doesn’t. Makes sense. Conditional compilation without all the nasty misuses of them you see in C++ programs. Seems to be the best of both worlds and an obvious leg up on Java, right?

Well, actually not really. Turns out that Java has supported something similar since day one, also. In Java, the equivalent is this:


public static final LETS_DANCE = false;

...

if (LETS_DANCE)
{
// ... do something ...
}
#endif

Why is this guaranteed to work and not include the unreachable code? Turns out there is an important note in Java. Java will not output code that is obviously unreachable. To be obviously unreachable it needs to be known at compile time as a static final constant variable. So, there you go. Definitely a useful thing.

· ·

Dec/09

6

Programming Paradigms

If you’re an experienced programmer, this probably won’t be new information, but I hope to at least present it in a new way.  When developing software programs, there’s different ways to think about the problems you’re trying to solve, which affect the entire process from initial design to how it’s coded, even to how it’s tested.  I discuss a few of these in this article.

Unstructured

These days, unstructured styles of programming are generally frowned upon. In the old days, you might have programmed unstructured in older dialects of Fortran, COBOL, Basic, etc…, and used GOTO to move between sections of code. All variables were global to the program and so you had to be very careful about the usage and naming. This type of code was simple to code at first, but very difficult to read. In addition, it didn’t scale well at all. As programs got larger, it became exponentially more difficult to maintain. There isn’t much to talk about here, because coding in this manner is rare nowadays, except in specialized fields. You can imagine a program looking very sequential, though. Something like this:

if my height is less than 4'
goto short
elif my height is greater than 6'
goto tall
else
goto normal

short:
print "You are too short to go on this ride"
tall:
print "You must wear a helmet."
... offer helmet ...
if accept
goto getonride
else
print "No dice..."
normal:
goto getonride

getonride:
print "Welcome onto the ride."

exit:
print "You must leave.  NOW!"

As you can see, this can quickly get out of control. Reuse was almost non-existent.

Procedural Programming/Imperative Programming

Procedural programming was the first type of structured programming and it started to become widespread in the late 60s and early 70s.  It was probably the first major step towards programming we do today.  Structured programming is still used quite a bit and is the basis for some of the later programming paradigms.  Structural programming is responsible for mostly eliminating the widespread use of GOTO.  This methodology was more commonly taught at the time I was in college, as Object-Oriented programming was newer at the time, and not very well understood outside of a smaller community.  The main concepts behind is that any task can be broken up into sub-tasks.  Emphasis is placed on functionality and data structures.  With this, it is became easy to break down a workflow with direct relationships and traceability for a functional specification, often, provided by a customer.  This directly can be derived into software functional requirements, and then directly derived into software code, and then directly derives into tests.  Because all of the emphasis is on functionality, and the code is structured in that manner, it provides a lower barrier to entry than newer techniques such as Object-Oriented Programming. Due to this, the common tool for figuring out where a piece of code is implemented is simply a matter of using grep (on Linux/Unix) or find (on Windows).  Data definitions can be provided by systems engineers, because once the functionality is defined, the data required is also easily derived.

Some of the common procedural-oriented programming languages are Ada-83, Algol, Pascal and C.  Of course, at different points, many of the procedural programming languages later gained Object-Oriented features with new revisions (Ada-95, C++, etc…).  One of the main problem with structural programming concerns reuse.  You can successfully meet functional requirements, but later notice that different components of the system have 95% similar functionality.  It becomes difficult to directly express these relationships in your code.  To try to handle reuse of sections of code where there can be different types used, you wind up with large if and/or switch statements.  The problem then becomes that for each new type that supports this relationship, you wind up modifying working code, which is always risky.  Modifying working code makes it difficult to supply a working library because elements in the library will often be changed.

As an example, let’s take the case of a vehicle and then provide multiple types of vehicles, a car and a bus. Example in C:

void drive(int type, void* obj)
{
	switch (type)
	{
		case CAR:
		{
			Car* car = (Car*)obj;
			// ... Logic to accelerate car
		} break;
		case BUS:
		{
			Bus* bus = (Bus*)obj;
			// ... Logic to accelerate bus
		} break;
		default:
		{
		} break;
	}
}

Later, we provide a boat:

void drive(int type, void* obj)
{
	switch (type)
	{
		case CAR:
		{
			Car* car = (Car*)obj;
			// ... Logic to accelerate car
		} break;
		case BUS:
		{
			Bus* bus = (Bus*)obj;
			// ... Logic to accelerate bus
		} break;
		case BOAT:
		{
			Boat* boat = (Boat*)obj;
			// ... Logic to accelerate boat
		} break;
		default:
		{
		} break;
	}
}

As you can probably see, it’s relatively easy to figure out where to insert the code, but the maintenance of this can increase quickly, if you take into account that each function, such as drive, park, accelerate, addFuel, etc… would each need this sort of switch statement. You would wind up changing a lot of working code.

Object-Oriented Programming

Object-Oriented programming could be considered the next phase in the evolution of programming languages.  It largely gained popularity due to C++ (formerly C with Classes).  Object-Oriented development changes the emphasis.  The emphasis in Object-Oriented programming is not with defining the functionality of the system and the data.  Instead of putting the emphasis on the data of the system, you start out by identifying the objects in the system.  So, imagine a game, such as the original Super Mario Bros.  You could identify objects such as your main character (Mario, Luigi), the enemies in the world (Goombas, Koopa Troopas, Bowser, etc…), the blocks, the pipes, moving platforms, and even the world itself.  The functionality is tied in when the objects communicate with each other. In technical terms, this communication is called messaging. The functions are owned by objects, and are called methods, instead of functions. This ownership is based on something being able to do something else.  For example, Mario can jump, so Mario might have a method called jump().  Mario can also shoot fireballs, so he would have a method called shoot().  Since Mario and Luigi are the same, they might simply be two separate object instances of the same class called Player.  The enemies have some similarities, so they could be structured with a base class called Enemy and derived classes, which implement the different functionality.  It’s a different way of thinking about things.

Now what I’ve described so far might not make sense if you’re not proficient with Object-Oriented programming, so let me go back to the Vehicle example.  Here’s what it would look like in OO-terms:

class Vehicle
{
public:
	virtual void drive() = 0;
};

class Car : public Vehicle
{
public:
	virtual void drive()
	{
		// ... Logic to accelerate car
	}
};

class Bus : public Vehicle
{
public:
	virtual void drive()
	{
		// ... Logic to accelerate bus
	}
};

class Boat : public Vehicle
{
public:
	virtual void drive()
	{
		// ... Logic to accelerate boat
	}
};

In it’s most simple form, OO is simply a reorganization of code. However, it is obviously much more than this and this is a very simple example, which doesn’t touch all of the depths of how far things can go, but I think is fine to start. When you say that a Car is derived from a Vehicle, you are effectively saying that a Car is-a Vehicle. This is the basis for this type of inheritance. You should only derive if you can logically say that something is something else. For example, you shouldn’t have Bus derive from Boat, because a bus is-not-a boat.

So, if you look at the above example, I think you can see how this flows really nicely for things like GUIs. That’s why you can have a framework where every visual element might be derived from Control, Widget, or even Window (Side note: except in Actionscript, where for legacy reasons, everything is nonsensically derived from MovieClip). There’s logic behind this. A button is-a control. A push button is-a type of button. A list box is-a type of widget or control. And so on… It gets a little trickier when the base class is called Window (or CWnd in MFC), but if using this type of framework, you can try to accept the notion that each control could be considered a window, even though there were better name choices.

Object-oriented suffers from a set of problems of its own, even though it is an improvement over procedural programming. The first is that there’s more typing, at least upfront. As developers, we try to reduce typing, but OO can often be more verbose than necessary. Of course, wizards and newer programming languages aim to reduce this overhead more than languages like C++ or Java, which can often be overly verbose. The OO theory, though, is that through reuse, you avoid much of this typing as you develop higher-level things because you’re basically picking from a toolbox. OO also suffers from not having the same traceability that you have in procedural programming, because functional requirements do not map directly into design anymore, nor into code, nor into testing. When doing Object-Oriented Design, Object-Oriented Programming and Object-Oriented Testing, the traceability becomes less direct, and so newer processes try to take this into account a bit more.

· · · · · · · · · · · · · · · · ·

Nov/09

17

The Power of Mocks

Mocks are a powerful tool in your testing toolkit. Whether you’re doing test-driven development or not, mocks are absolutely powerful. I first encountered mocks when I started getting a bit heavier into Java development and discovered jMock. My first reaction was that it was amazing. Each mock and stub I would hand-code would take some careful planning and writing of code. The code was always similar and so felt repetitive, yet it was never such a big thing that I thought I had to roll my own heavy reusable mechanism to streamline the process. Then I saw jMock. What used to take me hours took minutes. What used to take 100 lines of code took 10. It was an amazing improvement from a testing standpoint, and removed a lot of the dread when writing unit tests.

If you’re not familiar with mocks, a mock object is an object used in place of a real object for simulating behavior. It’s a very powerful concept. When you’re doing unit tests, you’re often trying to test a unit (often an object) in isolation, so using mocks, whether manual or automated is essential. jMock made this easy. Then I was introduced to Mockito, which was the next step in simplifying the process. Mockito turned the 10 lines of code into about 4 and introduced one critically important concept.

With jMock, in some cases you needed to have an interface in order to mock behavior, so IIRC, you could only be guaranteed to effectively mock with an interface. Concrete classes may work in jMock, but take more finessing. Not so with the amazing Mockito. With Mockito, I could take just about any class and mock the behavior of it and it worked. Amazing library. In addition, it wasn’t overly verbose like jMock is.

Now, in the C++ community, mocking was generally a manual process. There were mocking libraries, but not until recently did we have one that really streamlined the process. Then I discovered gMock, which is an amazing library and really fills the gap for C++. It does about as much as you can in C++, considering the lack of reflection for this sort of task and again gives you the power of mocks like you can get easily in Java.

In conclusion, mocks are an essential part of my testing process and I highly recommend you use them. In future articles, I will try to discuss some sample usage with some examples.

Links:
http://code.google.com/p/googlemock/
http://www.jmock.org/
http://mockito.org/

· · · · · · ·

Theme Design by devolux.nh2.me