Code Review 痛并享受着

Categories: Java; Tagged with: ; @ September 12th, 2013 0:06

1. Interface

几乎所有的Class都是某些Interface的实现, 但我从来没有认真考虑过接口应该怎么用, 用到什么程度.

举例说, 有接口IDatabase, 还有具体类DefaultDatabase, Oracle, DB2…

理论上, 除了配置文件/Factory中可能会用到具体实现, 初次之外, 就不应该在任何Class中使用具体实现!

但事实上, 尤其是在不假思索, 取名叫做DefaultDataBase时,  经常会使用DefaultDataBase而不是IDatabase…

 

2. SVN

模块/文件夹 需要重构+重新命名.

由于担心SVN出现莫名其妙的问题, 所以新建了文件夹, 然后将新的文件逐步复制进去.

所有文件的历史记录将丢失.

 

3. Exception

WebService的Exception应该继续抛出, 而不是处理. 这样客户端在收到Exception后可以进行后续处理, 譬如重定向到某一个错误页面.

Extending Java Generic Classes

Categories: Java; Tagged with: ; @ September 5th, 2013 23:34

“You can subtype a generic class or interface by extending or implementing it. The relationship between the type parameters of one class or interface and the type parameters of another are determined by the extends and implements clauses.”

http://docs.oracle.com/javase/tutorial/java/generics/inheritance.html

package com.liguoliang.core.dao;

import java.util.List;

import com.liguoliang.core.modle.Animal;

public abstract class AbstractDAO <T extends Animal>{
	
	protected  T saveAnimal(T animal) {
		System.out.println("Save: " + animal.toString());
		return animal;
	}
	
	protected abstract List<T> getList();
}

Sub class should follow the contract made by the super class: T extends Animal

Otherwise, got the Error: Bound mismatch: The type ** is not a valid substitute for the bounded parameter of the type AbstractDAO

package com.liguoliang.core.dao;

import java.util.List;

import com.liguoliang.core.modle.Dog;

public class DogDAO<WhatEver extends Object> extends AbstractDAO<Dog> {
	
	public Dog saveDog(Dog dog) {
		return saveAnimal(dog);
	}

	@Override
	protected List<Dog> getList() {
		return null;
	}
	
	public WhatEver whatEver(WhatEver w) {
		return w;
	}
	
}

关于Exception的Capture

Categories: Java; Tagged with: ; @ September 4th, 2013 0:14

今天写了段很挫的代码, 简单的来说就是这样:

	public static void main(String[] args) {
		try {
			throwNewException();
		} catch (Exception e) {
			System.out.println(e);
			System.out.println(e.getMessage());
		}
	}
	
	private static void throwNewException() {
		Object test = null; // simulate the Spring injection Error.
		test.getClass(); 
		throw new RuntimeException("UserName cannot be empty.");
	}

简直就是奇葩, 在做UnitTest时, 其中一个用例是throwNewException throw RuntimeException, 

由于Spring注入失败, 导致抛出NullPointerException, 而后续代码依赖于RuntimeException的ErrorMesg, 一直拿不到ErrorMesg. 纠结半天, 原因如下:

 

1.  懒. 使用RuntimeException而不是创建对应的Exception类型;

2.  懒. 在Catch时, catch了Exception, 而且没有打印Exception, 也就是说, 拦截并隐藏了所有Exception!

3.  懒.  Debug时懒得思考, 看到如下的输出:

java.lang.NullPointerException
null

就得出结论, Exception是Null的! WTF!! 然后就开始纠结是不是Spring的问题…

 

所以,

创建Exception类型, Capture具体Exception具体处理, 处理或是继续抛出Exception, 而不是隐藏,.

Clean Code: Meaningful Names 清晰有意义的命名

Categories: Development NotesJava; Tagged with: ; @ August 14th, 2013 0:02

One difference between a smart programmer and a professional programmer is that the professional understands that clarity is king . Professional use their powers for good and write code that others can understand.

Uncle Bob

Summary for Clean Code chapter 2:

Use Intention-Revealing names 表明意图

int d; –> int daysSinceCreation;

list1 –> flaggedCells

Avoid Disinformation 提供真实信息

accountList:  Unless it’s actually a List. otherwise, accountGroup/bunchOfAccounts/accounts would be better

Make meaningful distinctions 有意义的区分

copyChars(a1, a2) –> copyChars(source, destination)

Use Pronounceable Names 使用可以发音的变量名称

luo –> lastUpdatedOn

Hungarian notation 匈牙利命名法 不必再刻意添加前缀

strName –> name

m_desc –> desc

Class names: noun or noun phrase. Method names, verb or verb phrase.

Don’t be cute 清晰表达即可, 不要画蛇添足

eatMyShorts() –> abort() [Eat my shorts, by Bart Simpson]

Pick One Word per Concept 为一个概念选定一个名称 Don’t pun 不要使用双关词汇

fetch, get

add, insert?

Use Solution Domain Names 使用解决方案领域内词汇

AccountVisitor, StudentFactory

Add Meaningful Context 有意义的语境, Don’t Add Gratuitous  Context 但不要增加无意义的上下文

Class name: SGMailingAddress –> MailingAddress

Getting started with Spring MVC

Categories: Java; Tagged with: ; @ August 11th, 2013 12:00

1. Config pom.xml

2. Add mvc-dispatcher in web.xml

3. Config dispatcher xml, i.e.

        <context:component-scan base-package="com.liguoliang.jee.web" />
 
        <bean
            class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <property name="prefix">
                <value>/WEB-INF/pages/</value>
            </property>
            <property name="suffix">
                <value>.jsp</value>
            </property>
        </bean>

4. Controler:

package com.liguoliang.jee.web;


@Controller
@RequestMapping("/OrgMgt")
public class OrgMgtController {
	@RequestMapping(method=RequestMethod.GET, value={"", "view"})
	public String listOrgs(ModelMap modelMap) {
		return "OrgsList"; // JSP
	}
	
	@RequestMapping(value="new", method=RequestMethod.GET)
	public String createOrg(ModelMap modle) {
		Org initOrg = … // init new Org object.
		modle.addAttribute("newOrg", initOrg);
		return "NewOrg";
	}
	
	@RequestMapping(method=RequestMethod.POST)
	public String onSubmit(@ModelAttribute("org") Org org, BindingResult result) {
		OrgValidator validator = new OrgValidator();
		validator.validate(org, result);
		if(result.hasErrors()) {
			return "NewOrg";
		}
		
		return "redirect: OrgMgt";
	}
	

	@RequestMapping(value="view/{id}", method=RequestMethod.GET)
	public String viewOrg(ModelMap modelMap, @PathVariable Integer id) {
		modelMap.addAttribute("id", id);
		return "OrgDetails";
	}
}

Newer Posts <-> Older Posts



// Proudly powered by Apache, PHP, MySQL, WordPress, Bootstrap, etc,.