Java anti-patterns:
             Dark knight rises.



Сергей Моренец
28 февраля 2013 г.
Agenda

• Design patterns
• Anti-patterns overview
• Q&A
Design patterns
• Design Patterns: Elements of Reusable Object-Oriented
  Software
• Published on October 21, 1994
• Authors are Erich Gamma, Richard Helm, Ralph
  Johnson and John Vlissides, referred as Gang of Four
• Creational, structural and behavioral patterns.
Hero of the day
Java Anti-docs
/**
* Rejects current task
*/
public void approve() {
 …
}
Inline conversion
int recordId = -1;

try {
    recordId = Integer.parseInt(columnRecordId);
} catch (NumberFormatException e) {
  recordId = 0;
}
Exception handler
            avoidance
ValidationResultCollector vrc = collector.validate();

if(vrc.hasError()) {
   ValidationResult result = vrc.getError();
   errorText = result.getErrorText();
} else if(vrc.getErrorCode() == CPFErrorID.getNoCPFError()) {
}
Disuse of helper
              libraries
if (param.getFileName() != null &&
param.getFileName().length() > 4) {
try {
    if (param.getFileName().contains(".")) {
         name = param.getFileName().substring(0,
param.getFileName().lastIndexOf("."));
 } else name = attach.getFileName();
} catch (Exception e) {
 e.printStackTrace();
String errorMessage = e.getMessage();
 }
 }
Disuse of helper
             libraries
String name = FilenameUtils.getBaseName(
parameter.getFileName());

String extension = FilenameUtils.getExtension(
parameter.getFileName());
Misuse of inheritance
• public class SuperMap<K, V> extends
  HashMap<K,V>{

•   @Override
•   public V get(Object key) {
•   …
•   }
•   }
Upcasting
public abstract class BaseClass {

public void do() {
  ((DerivedClass) this).validate();
}
}

class DerivedClass extends BaseClass {
public void validate() {
}
}
Lack of synchronization
public class ScreenManager {

private static ScreenManager instance;

public static ScreenManager getInstance() {
if (instance == null) {
     instance = new ScreenManager();
}
return instance;
}
}
State inconsistency
public class AccountManager {
private boolean inProgress = false;

public void submit() {
  if (inProgress) {
     return;
  }
  inProgress = true;
  …
  inProgress = false;
}
}
State inconsistency
public class AccountManager {
  private final Lock lock = new ReentrantLock();

    public void submit() {
      lock.lock();
      …
      lock.unlock();
}
}
State inconsistency
public class AccountManager {
private final Lock lock = new ReentrantLock();

public void submit() {
try {
   lock.lock();
   …
   } finally {
   lock.unlock();
}
}
}
Platform-dependent API
File tmp = new File("C:Temp1.tmp");

File exp = new File("export-2013-02-01T12:30.txt");

File f = new File(path +'/'+ filename);
Platform-dependent API
File tmp = File.createTempFile("myapp","tmp");

File exp = new File("export-2013-02-01_1230.txt");

File f = new File(path +File. pathSeparator+ filename);

File dir = new File(path);
File f = new File(dir, filename);
Infinitive heap
byte[] pdf = toPdf(file);
Infinitive heap
File pdf = new File(file);
InputStream in = new FileInputStream(pdf);
Unbuffered streams
InputStream in = new FileInputStream(file);
int b;
while ((b = in.read()) != -1) {
...
}
Unbuffered streams
InputStream in = new BufferedInputStream(new
FileInputStream(file))
Wrong propagation
try {
  …
} catch(ParseException e) {
   LOGGER.error(e.getMessage());
   throw new RuntimeException();
   throw new RuntimeException(e.toString());
   throw new RuntimeException(e.getMessage());
   throw new RuntimeException(e);
}
Wrong propagation
try {
} catch(ParseException e) {
throw new RuntimeException(e.getMessage(), e);
}
Impossible exception
try {
... do risky stuff ...
} catch(SomeException e) {
// never happens
}
Impossible exception
try {
... do risky stuff ...
} catch(SomeException e) {
// never happens hopefully
throw new IllegalStateException(e.getMessage(), e);
}
Unnecessary Calendar
Calendar cal = new
GregorianCalender(TimeZone.getTimeZone("Europe/Kyiv"));
cal.setTime(date);
cal.add(Calendar.HOUR_OF_DAY, 8);
date = cal.getTime();
Unnecessary Calendar
date = new Date(date.getTime() + 8L * 3600L * 1000L);
Misleading calendar
Calendar c = Calendar.getInstance();
c.set(2009, Calendar.JANUARY, 15);
c.getTime() - ?
Misleading calendar
Calendar c = new GregorianCalendar(timeZone);
c.set(2009, Calendar.JANUARY, 15);
Global constants
public interface Constants {
  String version = "1.0";
  String dateFormat = "dd.MM.yyyy";
  String configFile = ".apprc";
   int maxNameLength = 32;
   String someQuery = "SELECT * FROM ...";
}
Static initializers
class Cache {
private static final Timer timer = new Timer();
}
Static initializers
class Cache {
private static Timer timer;

public static startTimer() {
timer = new Timer();
}
}
Reflection overuse
Class beanClass = ...
if (beanClass.newInstance() instanceof TestBean) ...
Reflection overuse
Class beanClass = ...
if (TestBean.class.isAssignableFrom(beanClass)) ...
Map iteration
Map<String, String> map = …;

for (String key : map.keySet()) {
   String value = map.get(key);
   …
}
Map iteration
Map<String, String> map = …;

for (Entry<String, String> entry : map.entrySet()) {
  String key = entry.getKey();
  String value = entry.getValue();
  …
}
Time measurement
long startTime = System.currentTimeMillis();
  ...
long elapsedTime = System.currentTimeMillis() -
startTime;
Time measurement
long startTime = System.nanoTime();
...
long elapsedTime = (System.nanoTime() - startTime) /
1000000;
Q&A




• Сергей Моренец, morenets@mail.ru
Collection<User> users = ...
      if (users != null && !users.isEmpty()) {
              int i = 0;
              for (User user : user) {
                      if (i > 0)
                               break;
                      output.setUserId(user.getId());
                      i++;
              }}

Anti patterns