There is a well-known heuristic called the Law of Demeter .
Law of Demeter says that a method f of a class C should only call the methods of these:
• C
• An object created by f
• An object passed as an argument to f
• An object held in an instance variable of C
The method should not invoke methods on objects that are returned by any of the
allowed functions. In other words, talk to friends, not to strangers
Sample Violation : final String outputDir = ctxt.getOptions().getScratchDir().getAbsolutePath();
If the code had been written as follows, then we probably wouldn’t be asking about Demeter violations.
final String outputDir = ctxt.options.scratchDir.absolutePath;
This issue would be a lot less confusing if data structures simply had public variables
and no functions, whereas objects had private variables and public functions
-- Clean Code by Robert Martin
Thursday, April 29, 2010
Wednesday, April 28, 2010
Data Abstraction
Concrete Vehicle
public interface Vehicle {
double getFuelTankCapacityInGallons();
double getGallonsOfGasoline();
}
Abstract Vehicle
public interface Vehicle {
double getPercentFuelRemaining();
}
In both of the above cases the second option is preferable. We do not want to expose
the details of our data. Rather we want to express our data in abstract terms. This is not
merely accomplished by using interfaces and/or getters and setters. Serious thought needs
to be put into the best way to represent the data that an object contains. The worst option is
to blithely add getters and setters.
-- Robert Martin / Clean Code
public interface Vehicle {
double getFuelTankCapacityInGallons();
double getGallonsOfGasoline();
}
Abstract Vehicle
public interface Vehicle {
double getPercentFuelRemaining();
}
In both of the above cases the second option is preferable. We do not want to expose
the details of our data. Rather we want to express our data in abstract terms. This is not
merely accomplished by using interfaces and/or getters and setters. Serious thought needs
to be put into the best way to represent the data that an object contains. The worst option is
to blithely add getters and setters.
-- Robert Martin / Clean Code
Tuesday, April 27, 2010
EntityManager methods to save Beans
People asked: Why there is two different methods to save jpa entities.Something like EntityManager.save(anyKindOfEntityBean) ?
Lets have a look at what we have actually
EntityManager.persists (newEntityBean) : creates a new entity using sql insert.If entity already exists in the database you will get a Unique Contraint Violation.
EntityManager.merge (anyKindOfEntityBean) : It creates if not exists.It updates if exists.
Because when you really want to create new entity and you want to be 100% sure it is
new, you use #persist and if that object actually exists, the #persist
will throw an exception.
With #merge, you would have to query database first to make sure.
Briefly If you don't care about objects are really new or not you can use merge of course.
But..Don't you think that it is a bit dangerous? ;)
Lets have a look at what we have actually
EntityManager.persists (newEntityBean) : creates a new entity using sql insert.If entity already exists in the database you will get a Unique Contraint Violation.
EntityManager.merge (anyKindOfEntityBean) : It creates if not exists.It updates if exists.
Because when you really want to create new entity and you want to be 100% sure it is
new, you use #persist and if that object actually exists, the #persist
will throw an exception.
With #merge, you would have to query database first to make sure.
Briefly If you don't care about objects are really new or not you can use merge of course.
But..Don't you think that it is a bit dangerous? ;)
How to detach a specific entity from your PersistenceContext ?
A way to detach a specific JPA Entity Bean :
What is the main problem here ?
EntityManager.flush () method persists all changes from attached JPA Entity Beans that was acquired through an EntityManager to the underyling database.
But for some reason we don't want to change some specific objects within the current PersistenceContext.
So What we can do to prevent this situation ?
Answer :
EntityManager.refresh(Object o)
This method will restore original state of the entity, if primary key of the entity bean has not been changed.
What is the main problem here ?
EntityManager.flush () method persists all changes from attached JPA Entity Beans that was acquired through an EntityManager to the underyling database.
But for some reason we don't want to change some specific objects within the current PersistenceContext.
So What we can do to prevent this situation ?
Answer :
EntityManager.refresh(Object o)
This method will restore original state of the entity, if primary key of the entity bean has not been changed.
Monday, April 26, 2010
Why Joda Time ?
They said : Joda-Time has been created to radically change date and time handling in Java. The JDK classes Date and Calendar are very badly designed, have had numerous bugs and have odd performance effects. Here are some of our reasons for developing and using Joda-Time
joda time
joda time
public boolean isAfterPayDay (DateTime datetime) {
if (datetime.getMonthOfYear () == 2) { // February is month 2!!
return datetime.getDayOfMonth () > 26;
}
return datetime.getDayOfMonth () > 28;
}
public Days daysToNewYear (LocalDate fromDate) {
LocalDate newYear = fromDate.plusYears (1).withDayOfYear (1);
return Days.daysBetween (fromDate, newYear);
}
public boolean isRentalOverdue (DateTime datetimeRented) {
Period rentalPeriod = new Period ().withDays (2).withHours (12);
return datetimeRented.plus (rentalPeriod).isBeforeNow ();
}
public String getBirthMonthText (LocalDate dateOfBirth) {
return dateOfBirth.monthOfYear ().getAsText (Locale.ENGLISH);
}
Friday, April 16, 2010
More real example about how to write clean code
DO NOT DO THIS !
// Check to see if the employee is eligible for full benefits
if ((employee.flags & HOURLY_FLAG) &&
(employee.age > 65))
PREFER THIS WAY
if (employee.isEligibleForFullBenefits())
Note: Yes yes....I am planning to combine all good samplings about writing clean code under a unique Header in My Blog.
Wednesday, April 14, 2010
Java Executor Service and Future !!!
Some jobs can be passed to another thread/pool and can be called with a given timeout value.
By the way your application business logic can continue its execution without waiting longer than expected or hanging.
Here is the task is "Callable c" and given timeout is 2000 millisecond. "future.get". So we will get a TimeoutException.
You can easily test it by running.
I have tried to simulate some blocking method with Thread.sleep ().You can replace it with your own code (exm:socket.read ()).
In the below example timeout is 2 seconds and operation takes 3 seconds.So code will get timeoutException.If you decrease the timeout will get a return object called ReturnObject.
I have tried to simulate some blocking method with Thread.sleep ().You can replace it with your own code (exm:socket.read ()).
In the below example timeout is 2 seconds and operation takes 3 seconds.So code will get timeoutException.If you decrease the timeout will get a return object called ReturnObject.
import java.util.concurrent.*;
public class FutureTest {
private static int nThreads = 20;
public static void main(String[] args) {
LinkedBlockingQueue
ExecutorService executorService = new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS, taskQueue);
Callable c = new Callable() {
public Object call() throws Exception {
Thread.sleep(3000);
ReturnObject rt = new ReturnObject();
rt.setReturnName("serkan sunel");
return rt;
}
};
Future future = executorService.submit(c);
try {
Object returnObj = future.get(2000, TimeUnit.MILLISECONDS);
System.out.println("returned :" + returnObj);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}
}
}
Subscribe to:
Posts (Atom)