Download - Anti patterns
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 conversionint recordId = -1;
try { recordId = Integer.parseInt(columnRecordId);} catch (NumberFormatException e) { recordId = 0;}
Exception handleravoidance
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) {• …• }• }
Upcastingpublic 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 inconsistencypublic class AccountManager {private boolean inProgress = false;
public void submit() { if (inProgress) { return; } inProgress = true; … inProgress = false;}}
State inconsistencypublic class AccountManager { private final Lock lock = new ReentrantLock();
public void submit() { lock.lock(); … lock.unlock();}}
State inconsistencypublic 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:\\Temp\\1.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 heapbyte[] pdf = toPdf(file);
Infinitive heapFile pdf = new File(file);InputStream in = new FileInputStream(pdf);
Unbuffered streamsInputStream in = new FileInputStream(file);int b;while ((b = in.read()) != -1) {...}
Unbuffered streamsInputStream in = new BufferedInputStream(new FileInputStream(file))
Wrong propagationtry { …} 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 propagationtry {} catch(ParseException e) {throw new RuntimeException(e.getMessage(), e);}
Impossible exceptiontry {... do risky stuff ...} catch(SomeException e) {// never happens}
Impossible exceptiontry {... do risky stuff ...} catch(SomeException e) {// never happens hopefullythrow new IllegalStateException(e.getMessage(), e); }
Unnecessary CalendarCalendar cal = new GregorianCalender(TimeZone.getTimeZone("Europe/Kyiv"));cal.setTime(date);cal.add(Calendar.HOUR_OF_DAY, 8);date = cal.getTime();
Unnecessary Calendardate = 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 constantspublic interface Constants { String version = "1.0"; String dateFormat = "dd.MM.yyyy"; String configFile = ".apprc"; int maxNameLength = 32; String someQuery = "SELECT * FROM ...";}
Static initializersclass Cache {private static final Timer timer = new Timer();}
Static initializersclass 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 iterationMap<String, String> map = …;
for (String key : map.keySet()) { String value = map.get(key); …}
Map iterationMap<String, String> map = …;
for (Entry<String, String> entry : map.entrySet()) { String key = entry.getKey(); String value = entry.getValue(); …}
Time measurementlong startTime = System.currentTimeMillis(); ...long elapsedTime = System.currentTimeMillis() - startTime;
Time measurementlong startTime = System.nanoTime();...long elapsedTime = (System.nanoTime() - startTime) / 1000000;
Collection<User> users = ...if (users != null && !users.isEmpty()) {
int i = 0;for (User user : user) {
if (i > 0)break;
output.setUserId(user.getId());i++;
}}