1. Interface
几乎所有的Class都是某些Interface的实现, 但我从来没有认真考虑过接口应该怎么用, 用到什么程度.
举例说, 有接口IDatabase, 还有具体类DefaultDatabase, Oracle, DB2…
理论上, 除了配置文件/Factory中可能会用到具体实现, 初次之外, 就不应该在任何Class中使用具体实现!
但事实上, 尤其是在不假思索, 取名叫做DefaultDataBase时, 经常会使用DefaultDataBase而不是IDatabase…
2. SVN
模块/文件夹 需要重构+重新命名.
由于担心SVN出现莫名其妙的问题, 所以新建了文件夹, 然后将新的文件逐步复制进去.
所有文件的历史记录将丢失.
3. Exception
WebService的Exception应该继续抛出, 而不是处理. 这样客户端在收到Exception后可以进行后续处理, 譬如重定向到某一个错误页面.
“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
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; } }
今天写了段很挫的代码, 简单的来说就是这样:
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, 而不是隐藏,.
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.
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
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"; } }
// Proudly powered by Apache, PHP, MySQL, WordPress, Bootstrap, etc,.