Thursday, January 15, 2009
A hint
When you find yourself wanting to do something like...
myThing = doSomethingToMyThing(myThing); //if it's local or
myThing = doSomethingToMyThing(); //if it's global
you know you should really make that method belong to myThing's class, since all you want to do is change something about that object.
If there's no such handy method in the MyThing class, it may be time to make your own object extending it, and give it the method. It's the OO way!
cuz myThing.doSomething(); just looks cleaner, don't it?
Thursday, January 8, 2009
No join method?!
the opposite of split is... nothing
boo. shame on you, Sun.
Thursday, June 12, 2008
mysterious smells
The good news: we're pretty good at doing what is needed very quickly.
The bad news: our code is starting to smell.
What do I mean by smell? A 'code smell' is a term I just learned the other day. Basically it's a combination of less-than-optimum coding practices, usually introduced by a lack of refactoring, or using procedural programming techniques (because they're more intuitive/easier to implement) when in the long run the code would be much easier to maintain and understand using object oriented principles.
Here is a list stolen from http://wiki.java.net/bin/view/People/SmellsToRefactorings
(which in turn was summarized from the classic book "Refactoring" by Kent beck.)
| Smell | Description | Refactorings |
|---|---|---|
| Comments | Should only be used to clarify "why" not "what". Can quickly become verbose and reduce code clarity. | Extract Method Rename Method Introduce Assertion |
| Long Method | The longer the method the harder it is to see what it’s doing. | Extract Method Replace Temp with Query Introduce Parameter Object Preserve Whole Object Replace Method with Method Object |
| Long Parameter List | Don't pass in everything the method needs; pass in enough so that the method can get to everything it needs. | Replace Parameter with Method Preserve Whole Object Introduce Parameter Object |
| Duplicated Code | Extract Method Pull Up Field Form Template Method Substitue Algorithm | |
| Large Class | A class that is trying to do too much can usually be identified by looking at how many instance variables it has. When a class has too many instance variables, duplicated code cannot be far behind. | Extract Class Extract Subclass |
| Type Embedded in Name | Avoid redundancy in naming. Prefer schedule.add(course) to schedule.addCourse(course) | Rename Method |
| Uncommunicative Name | Choose names that communicate intent (pick the best name for the time, change it later if necessary). | Rename Method |
| Inconsistent Names | Use names consistently. | Rename Method |
| Dead Code | A variable, parameter, method, code fragment, class, etc is not used anywhere (perhaps other than in tests). | Delete the code. |
| Speculative Generality | Don't over-generalize your code in an attempt to predict future needs. | If you have abstract classes that aren't doing much use Collapse Hierarchy Remove unnecessary delegation with Inline Class Methods with unused parameters - Remove Parameter Methods named with odd abstract names should be brought down to earth with Rename Method |
There are more on that site, and even more in the book. I should really buy it. But it might just sit on the shelf like my 'Design Patterns' book. Oh well, at least my coworker found use for it and has been semi-permanently borrowing it.
But I digress.
Friday, May 16, 2008
Perly Java
if(something that might be true){
do this;
}else{
do that;
}
or alternatively,
if(something that might be true){
do this;
}else if(something else that might be true){
do that;
}else{
do the alternative.
}
Of course there are a number of ways to make these statements shorter, like ommitting closing curly braces if the 'do this' operation is one line, etc.
These shorter ways are a little harder to read, but make the code a little more compact which can be a good thing.
But there is an even SHORTER way! If you just have a simple if/then/else statement, nothing fancy, just one operation for the if and the else, then you can get it down to one line.
To make this even more cryptic, it is not even necessary to use the words 'if' or 'else' in there at all: in place of if is '?' and in place of else is ':'.
So the above code fragment would look like this:
(something that might be true)?do this:do that;
This is getting suspiciously like Perl, if you ask me. Java heresy! ;)
Friday, May 2, 2008
Singletons: I finally get it
I had heard about singletons, and in fact had to study about them before. But I studied them in a kind of abstract way and never really had to use them - until now.
Here is a great great understandable explanation from "Using the Singleton Pattern"
by Budi Kurniawan (http://www.onjava.com/pub/a/onjava/2003/08/27/singleton.html).
How do you write a Singleton class? Simple: create a public static method that is solely responsible for creating the single instance of the class. This also means that the client of the class should not be able to invoke the Singleton class's constructor, either. Because the absence of a constructor will make the compiler create a no-argument public constructor, a class applying the Singleton pattern has a private or protected constructor. Because the constructor is private or protected, there is no way a client can create an instance of that class by calling its constructor. The constructor is not accessible from outside of the class!
If the only constructor cannot be accessed, how do we get an instance of that class? The answer lies in a static method in the class. As mentioned above, a Singleton class will have a static method that calls the constructor to create an instance of the class and return this instance to the caller of the static method. But isn't the constructor private? That's right. However, remember that the static method is also in the same class; therefore, it has access to all members of the class, including the private members of the class.
You might ask the following question: "You can't create an instance of a class by calling its constructor, so how do you call the static method (responsible for creating the single instance of the class) without having the class instance?" Note, though, that static members of a class can be invoked without having an instance of that class. To limit the number of instances to one, the static method has to check if an instance has been created before. If it has, it simply returns a reference to the previous created instance. If it has not, it calls the constructor to create one. It's as simple as that.
So to get my map, I create a singleton class to hold my data, create a static getInstance method, and instantiate it from the GUI with my data mapping. Then on the server, I call the getInstance method (which will pass me back the ONE object with my map), and voila!
Friday, March 28, 2008
Do-it-yourself equals and hash code methods
But sometimes, you just need a little more. You can override these methods and give your own classes more specific instructions about what to do when they are being tested for equality or being indexed. I still have much to learn about this, but found a tasty looking link for further, later perusal.
http://www.geocities.com/technofundo/tech/java/equalhash.html
Friday, March 14, 2008
Data Facades
the use of Data Facades. I noticed this in some of the newer parts of our code base, where it's being refactored by a more competent programmer than I! :)
Here's a little blurb on it from the MSDN site:
"Consider using a data facade to wrap the most relevant data needed by the client. You can develop a wrapper object, with a coarse-grained interface, to encapsulate and coordinate the functionality of one or more objects that have not been designed for efficient remote access. It provides clients with single interface functionality for multiple business objects."
What does that mean? Say my server-side code has a few queries that have very little difference between them. Instead of making if/else statements to differentiate them, create a *DataFacade class for each of these states. These in turn should all implement an interface that has methods for getting a part of the query. The *DataFacade classes will in turn have the specifics for their method bodies.