« February 2005 | Inicio | April 2005 »

March 29, 2005

An example of the Prototype Pattern ( the Java version )

Professor Coupling is a Spanish scientific that is planning to conquer the world. Do you want to read about the problems he encountered, and how he solved them using the prototype pattern?

Professor Coupling was a respected Spanish scientist, that became crazy because of the bad working conditions that all the Spanish scientists must suffer ( well, and because his girlfriend started to date another man ). So he became an evil genius, and now, he only thinks about conquering the world!!!.

professorCoupling.jpg
Professor Couplig

So, he has developed a cloning machine. A very special cloning machine, because it can be programmed in Java.

Professor Coupling’s plan is to clone as many sheeps (Any of various usually horned ruminant mammals of the genus Ovis in the family Bovidae ) as possible ( I don’t know exactly why, remember, he’s a genius, but he’s crazy ).

sheep.jpg
A sheep

So, the cloning machine looks like this:

class CloningMachine { public CloningMachine( ) { } public Sheep buildClone( ) { return new Sheep( ); } public Sheep[] buildManyClones( int cloneNum ) { Sheep[] returnArray = new Sheep[ cloneNum ]; for( int k=0; k< clonesNum; k++ ) { returnArray[ k ] = new Sheep( ); } return returnArray; } }

And the sheep will be like:

class Sheep { public Sheep( ) { //this is a spanish sheep, so it sounds like a spanish sheep! System.out.println( "beeeee. I'm a new Sheep" ); } }

After flooding the world with sheeps ( it was his evil plan, not mine ), Professor Coupling noticed that cloning a few thousands of cows could help him to conquer the world faster. But his cloning machine was not built to clone cows, it was just built to clone sheeps.

cow.jpg
A cow

So, he decides to add the functionality needed to clone cows. How?. Look:

class CloningMachine { function CloningMachine( ) { } public Sheep buildClone( ) { return new Sheep( ); } public Cow buildCowClone( ) { return new Cow( ); } public Sheep[] buildManyClones( int cloneNum ) Sheep[] returnArray = new Sheep[ cloneNum ]; for( int k=0; k< clonesNum; k++ ) { returnArray[ k ] = new Sheep( ); } return returnArray; } }

Professor Coupling is crazy, but he is not an idiot. He soon realizes that he’s going to be in trouble if he wants to clone other animals, like, for instance, birds, or even humans.

After thinking about the problem carefully, Professor Coupling gives it another try:

class CloningMachine { function CloningMachine( ) { } public Object buildClone( String type ) { if( type.equals( "sheep" ) ) { return new Sheep( ); } else if ( type.equals( "cow" ) ) { return new Cow( ); } } public Sheep[] buildManyClones( int cloneNum ) Sheep[] returnArray = new Sheep[ cloneNum ]; for( int k=0; k< clonesNum; k++ ) { returnArray[ k ] = new Sheep( ); } return returnArray; } }

After a few minutes of hysterical laughs, Professor Coupling begins to think about how he has implemented his cloning machine, and he soon finds some weak points.

First, the buildClone method returns an Object, not a Sheep or a Cow. Why? Because this method doesn’t know what it’s going to create. Professor Coupling ( remember, he’s crazy, but he’s not an idiot ) feels that may not be the best way to solve the problem.

And he also notices that if he wants to clone another animal, he will have to change his cloning machine again. Hmm, that’s not easy to maintain.

But then, an idea begins to reach his brain. He doesn’t know exactly how, but what could happen if he could give the cloning machine an animal ( a sheep, a cow, a human, whatever animal ), and tell the machine: “give me 500 like this one”. Brilliant!. He will never have to worry about how the machine works, it will just give him as many copies of an animal he provides as needed.

Professor Coupling then remembers when he was a student, and read a book titled “Design patterns: Elements of reusable object-oriented software” ( the GoF ), and that thing called “The Prototype pattern”.

So, the cloning machine cannot know what to clone and how to clone it. That will be a responsibility of any animal. The cloning machine will just receive an animal, and will tell him to clone itself as many times as needed, and then will return the resulting clones.

In fact, Professor Couplig has noticed that the creation of new cows can be a little more complex that the creation of new sheeps, so he wants to rely on the java cloning mechanism to clone sheeps, and to make the mechanism to clone cows a bit more flexible

So, the first thing to do will be to create an interface ( that extends Cloneable, so it implements clone( ) ) that both the Sheep and the Cow will implement

public interface CloneableAnimal extends Cloneable { public CloneableAnimal duplicate( ); }

[ Note ].It will also be possible that all the different animals will extend a base class, so the return type of duplicate( ) will be that base class. But I will continue my example implementing an interface because I think it’s more flexible.

That method ( duplicate ) will be the one that will create and return a new copy of any single animal that implements it.

So, here’s a sheep:

public class Sheep implements CloneableAnimal { public Sheep( ) { System.out.println( "Sheep template created" ); } public CloneableAnimal duplicate( ) { System.out.println( "the Sheep will clone itself" ); Sheep returnValue = null; try { returnValue = ( Sheep ) super.clone( ); } catch( Exception e ) { System.out.println( "error cloning Sheep" ); } return returnValue; } public String toString( ) { return "I'm a sheep clone, beeeeee"; } }

As you can see, the duplicate( ) method calls the clone method of Sheep's superclass ( Object ) Here’s a cow:

public class Cow implements CloneableAnimal { public Cow( ) { System.out.println( "Cow template created" ); } public CloneableAnimal duplicate( ) { System.out.println( "creating a new Cow instance" ); return new Cow( ); } public String toString( ) { return "Muuuu, cow clone" ; } }

And Professor Coupling will want to do something like this:

public class ProfessorCoupling { public static void sayIt( String words ) { System.out.println( "" ); System.out.println( words ); System.out.println( "" ); } public static void main( String[] args ) { CloningMachine cMachine = new CloningMachine( ); sayIt( "creating Sheep and Cow templates" ); Sheep sheepTemplate = new Sheep( ); Cow cowTemplate = new Cow( ); Cow clonedCow = ( Cow ) cMachine.newClone( cowTemplate ); sayIt( "first cloned cow" ); Sheep clonedSheep = ( Sheep ) cMachine.newClone( sheepTemplate ); sayIt( "first cloned sheep" ); System.out.println( clonedSheep ); sayIt( "Creating 10 new cows" ); CloneableAnimal[] newCows = cMachine.cloneMany( 10, cowTemplate ); sayIt( "Creating 10 new Sheeps" ); CloneableAnimal[] newSheeps = cMachine.cloneMany( 10, sheepTemplate ); sayIt( "Testing the cows created" ); for( int i=0; i< newCows.length; i++ ) { System.out.println( newCows[ i ] ); } sayIt( "Testing the sheeps created" ); for( int i=0; i< newSheeps.length; i++ ) { System.out.println( newSheeps[ i ] ); } } }

So, finally, the cloning machine will be able to receive an animal ( an instance of a class ), and tell it to create as many copies of itself as needed:

public class CloningMachine { public CloningMachine( ) { } public CloneableAnimal newClone( CloneableAnimal template ) { return template.duplicate( ); } public CloneableAnimal[] cloneMany( int itemCount, CloneableAnimal template ) { CloneableAnimal[] returnValue = new CloneableAnimal[ itemCount ]; for( int i=0; i< itemCount; i++ ) { returnValue[ i ] = template.duplicate( ); } return returnValue; } }

So, Professor Coupling can keep on flooding the world with the clones created by his machine, knowing that he is able to create copies of any thing he wants, because he has given his cloning machine the ability to generate objects whose type is unknown.

After some further reading, Professor Coupling also realizes that he has separated the code that handles the details of creating the new animals from the code that actually creates them ( that means, that, for example, if he wants to create 1000 red sheeps today, and 1000 blue sheeps tomorrow, he only has to put a painting machine next to the cloning machine, and that machine will handle the way that those sheeps are painted, without knowing how they were created ).

Thanks to Celia Carracedo for the drawings of the sheep, the cow, and evil Professor Coupling.

An example of the Prototype Pattern

Professor Coupling is a Spanish scientific that is planning to conquer the world. Do you want to read about the problems he encountered, and how he solved them using the prototype pattern?

Professor Coupling was a respected Spanish scientist, that became crazy because of the bad working conditions that all the Spanish scientists must suffer ( well, and because his girlfriend started to date another man ). So he became an evil genius, and now, he only thinks about conquering the world!!!.

professorCoupling.jpg
Professor Coupling

So, he has developed a cloning machine. A very special cloning machine, because it can be programmed in actionscript.

Professor Coupling’s plan is to clone as many sheeps (Any of various usually horned ruminant mammals of the genus Ovis in the family Bovidae ) as possible ( I don’t know exactly why, remember, he’s a genius, but he’s crazy ).

sheep.jpg
A sheep

So, the cloning machine looks like this:

class CloningMachine { function CloningMachine( ) { } public function buildClone( ): Sheep { return new Sheep( ); } public function buildManyClones( cloneNum: Number ) { var returnArray: Array = new Array( ); for( var k=0; k< clonesNum; k++ ) { returnArray[ k ] = new Sheep( ); } return returnArray; } }

And the sheep will be like:

class Sheep { function Sheep( ) { //this is a spanish sheep, so it sounds like a spanish sheep! trace( "beeeee. I'm a new Sheep" ); } }

After flooding the world with sheeps ( it was his evil plan, not mine ), Professor Coupling noticed that cloning a few thousands of cows could help him to conquer the world faster. But his cloning machine was not built to clone cows, it was just built to clone sheeps.

cow.jpg
A cow

So, he decides to add the functionality needed to clone cows. How?. Look:

class CloningMachine { function CloningMachine( ) { } public function buildClone( ): Sheep { return new Sheep( ); } public function buildCowClone( ): Cow { return new Cow( ); } public function buildManyClones( cloneNum: Number ) { var returnArray: Array = new Array( ); for( var k=0; k< clonesNum; k++ ) { returnArray[ k ] = new Sheep( ); } return returnArray; } }

Professor Coupling is crazy, but he is not an idiot. He soon realizes that he’s going to be in trouble if he wants to clone other animals, like, for instance, birds, or even humans.

After thinking about the problem carefully, Professor Coupling gives it another try:

class CloningMachine { function CloningMachine( ) { } public function buildClone( type: String ): Object { if( type == "sheep" ) { return new Sheep( ); } else if ( type == "cow" ) { return new Cow( ); } } public function buildManyClones( cloneNum: Number ) { var returnArray: Array = new Array( ); for( var k=0; k< clonesNum; k++ ) { returnArray[ k ] = new Sheep( ); } return returnArray; } }

After a few minutes of hysterical laughs, Professor Coupling begins to think about how he has implemented his cloning machine, and he soon finds some weak points.

First, the buildClone method returns an Object, not a Sheep or a Cow. Why? Because this method doesn’t know what it’s going to create. Professor Coupling ( remember, he’s crazy, but he’s not an idiot ) feels that may not be the best way to solve the problem.

And he also notices that if he wants to clone another animal, he will have to change his cloning machine again. Hmm, that’s not easy to maintain.

But then, an idea begins to reach his brain. He doesn’t know exactly how, but what could happen if he could give the cloning machine an animal ( a sheep, a cow, a human, whatever animal ), and tell the machine: “give me 500 like this one”. Brilliant!. He will never have to worry about how the machine works, it will just give him as many copies of an animal he provides as needed.

Professor Coupling then remembers when he was a student, and read a book titled “Design patterns: Elements of reusable object-oriented software” ( the GoF ), and that thing called “The Prototype pattern”.

So, the cloning machine cannot know what to clone and how to clone it. That will be a responsibility of any animal. The cloning machine will just receive an animal, and will tell him to clone itself as many times as needed, and then will return the resulting clones.

So, ( remember, ActionSctipt does not support abstract classes ), any animal could implement an interface, that contains only one method:

interface ICloneable { public function clone( ): ICloneable; }

[ Note ].It will also be possible that all the different animals will extend a base class, so the return type of clone( ) will be that base class. But I will continue my example implementing an interface because I think it’s more flexible.

That method ( clone ) will be the one that will create and return a new copy of any single animal that implements it.

So, here’s a sheep:

class Sheep implements ICloneable { function Sheep( ) { trace( "Hi, I'm Dolly, I will be cloned soon" ); } public function clone( ): ICloneable { trace( "Beeee, I'm a new sheep" ); return new Sheep( ); } public function toString( ): String { return "{ Hi, I'm a sheep. }"; } }

And here’s a cow:

class Cow implements ICloneable { function Cow( initFlag: Boolean ) { trace( "Muuuu, I'm a cow. I will also be cloned soon" ); if( initFlag == true ) { init( ); } } private function init( ) { trace( "I'm an initialized cow, whatever that means" ); } public function clone( ): ICloneable { return new Cow( true ); } public function toString( ): String { return "{ Yes, I'm a cloned cow, muuuuuu }"; } }

And Professor Coupling will want to do something like this:

var cMachine: CloningMachine = new CloningMachine( ); cMachine.buildClone( new Sheep( ) ); cMachine.buildClone( new Cow( ) ); trace( "--" ); var sheepClones: Array = cMachine.buildManyClones( 5, new Sheep( ) ); var cowClones: Array = cMachine.buildManyClones( 5, new Cow( ) ); trace( "--" ); trace( "sheepClones " + sheepClones ); trace( "cowClones " + cowClones );

So, finally, the cloning machine will be able to receive an animal ( an instance of a class ), and tell it to create as many copies of itself as needed:

class CloningMachine { function CloningMachine( ) { } public function buildClone( template: ICloneable ): ICloneable { return template.clone( ); } public function buildManyClones( clonesNum: Number, template: ICloneable ): Array { var returnArray: Array = new Array( ); for( var k=0; k< clonesNum; k++ ) { returnArray[ k ] = template.clone( ); } return returnArray; } }

So, Professor Coupling can keep on flooding the world with the clones created by his machine, knowing that he is able to create copies of any thing he wants, because he has given his cloning machine the ability to generate objects whose type is unknown.

After some further reading, Professor Coupling also realizes that he has separated the code that handles the details of creating the new animals from the code that actually creates them ( that means, that, for example, if he wants to create 1000 red sheeps today, and 1000 blue sheeps tomorrow, he only has to put a painting machine next to the cloning machine, and that machine will handle the way that those sheeps are painted, without knowing how they were created ).

Thanks to Celia Carracedo for the drawings of the sheep, the cow, and evil Professor Coupling.

March 28, 2005

Code smells and refactorings

I found this link via Agile Spain, and I'm blogging it for my future reference.

This is a list of bad smells ( within a class or between classes ), that can help identify some code chunks that need to be refactored, and gives some hints about how to refactor them.

[XP] Collective code ownership, testing, and coding standards

Extreme Programming (which is both a philosophy and a development methodology) relies upon twelve “development practices”.

From my point of view, one of the fundamental development practices is the “Collective Code Ownership”.

But what does that mean?. Well, as the name says, the project’s code is not owned by any particular developer, so any member of the team can (and in fact must) improve any part of the code at any time.

This approach brings some advantages, no matter if you are pair programming or are just part of a more “conventional” team. First of all, there are no bottlenecks. Also, if you see some code that can be refactored to be improved, you must do it as soon as possible, no matter if you wrote it or not. So, the code becomes much cleaner, but this not only benefits a particular chunk of code or a particular class, but the whole system, which is getting better all the time. Refactorings are also easier, because everybody has some knowledge of the whole project. The overall performance of the team will also increase, because everybody can help any of his co-workers at any time, and it takes also to less frustration (now, you cannot say “my code doesn’t work because THAT idiot didn’t do his job”, just go, and change his code).

But to achieve this goal, there are two things that must be solid as rock. Tests and coding standards.

You are going to work as part of a team that is going to be continuously improving the code. So, there has to be a test for every single class. In fact (but that will be a matter for another post), the tests for a class should be written before writing the class. So, whenever you refactor a class, or a chunk of code, you just have to run the test again. Has everything gone well?. Cool, time to move to another class, then.

But if everybody is going to be able to refactor any chunk of code, there’s a need for a common language. If I’m going to change the code written by another person, everything will be much easier if it looks like my own code: similar variables names, similar method names, the brackets located in the same place, and even the same whitespaces.

The code is the common language that is going to be spoken by the members of the team. So, they are the ones that should define it. But everybody must follow the standard.

By the way, tools like eclipse simplify the work of defining and following a coding Standard. Just define some preferences ( Window->Preferences->Java->Code Style ) and export them to all the team member’s computers.

March 06, 2005

[OT] Mac mini "mini review"

I finally received my mac mini two days ago. Here are my first impressions after this weekend: I love it.

First, some pictures:

The box:

mini_caja.jpg

The contents of the box:

mini_package.jpg

And the final setup:

mini_global.jpg

And the review:

1.- Installation.

The installation process was extremely easy. Just plug in the keyboard, video and mouse, switch the computer on and you're done.

I bought the computer because I wanted to upgrade my main windows box, but I want to use my windows box as a web, ftp and cvs server. So, I bought this KVM switch. Plugging the wires into the KVM switch was more time consuming that booting the mini.

2.- Applications.

A lot of applications are preinstaled: iLife'04 (yes, 04, not 05), Mail, Safari, iCal, iChat...

In the package there's also a DVD containing iLife'05. So upgrading the iLife suite was very easy. Just inserting the DVD and waiting a few minutes.

3.- Performance.

The hardware specifications:

Processor: PPC G4 ( 1.42 GHz )
RAM: 512 MB
HDD: 80 GB
Bluetooth / Superdrive

I am impressed by the computer's performance. Right now I'm running iTunes, iPhoto, Firefox, Mail, iCal, Adium, QuickSilver, ecto, NetNewsWire, AddressBook, a Remote Desktop Connection to my windows box, and Flash MX 2004. And the computer runs all these applications smoothly.

This is much more than what I expected.

When working with Flash, everything is easy and smooth. But Eclipse does not perform very well, specially when writing Java code.

4.- Cooling and noise.

The computer is very quiet. You can hardly hear the fan or the hard drive. But the SuperDrive is very noisy ( not when watching a movie, but when installing software, for instance ). The computer's surface, after two days switched on, is cold.

So, I must confess that I'm impressed by the computer's performance and ease of use.

In a few hours, I must go back to the office and to my windows box. I really hate mondays.