Java

AbstractWizardFormController中的command对象是如何进出session的

正常流程: Click "Next" all the way 1. 展现第一个表单时 — 系统会创建一个空的command对象并把它放入session中 2. 提交第一个表单时 — 系统会把command从session中取出,并立即把它从session中移除,然后再把request中的参数值塞到command中,在展现第二个表单之前,系统又会把这个对象塞回到session中 3. 提交第二个表单时 — 系统会把command从session中取出,并立即把它从session中移除,然后再把request中的参数值塞到command中。当展现最终的结果页面时,session中已没有command对象 正常流程: Click "Back" 1. 展现第一个表单时 — 系统会创建一个空的command对象并把它放入session中 2. 提交第一个表单时 — 系统会把command从session中取出,并立即把它从session中移除,然后再把request中的参数值塞到command中,在展现第二个表单时,系统又把这个对象塞回到session中 3. 在第二个表单点“Back”时 — 系统会把command从session中取出,并立即把它从session中移除,然后再把request中的参数值塞到command中。在展现第一个表单时,系统会把这个对象塞回到session中,并把对象丢到Model中,好让第一个表单展现它 异常流程: 1. 展现第一个表单时 — 系统会创建一个空的command对象并把它放入session中 2. 错误地提交第一个表单后 — 系统会把command从session中取出,并立即把它从session中移除,然后再把request中的参数值塞到command中;由于出错,所以会重现第一个表单,这时系统会把command塞回到session中 3. 这时如果按“F5” — 系统就会重走第2步 4. 正确地提交第一个表单和第二个表单,直到看到结果页面  — 到这里session中已无command 5. 如果这时用户按 "F5" 重复提交 — …

AbstractWizardFormController中的command对象是如何进出session的 Read More »

Notes on ‘Refactoring ‘ — 6.1 Replace Inheritance with Delegation

When?   You find that some of the superclass operations aren’t really true of the subclass. The code is saying the subclass has some interface that it doesn’t have. This is confusing. How to solve it?   1. The subclass doesn’t extend its superclass anymore   2. Instead, subclass should REFERENCE superclass to use it …

Notes on ‘Refactoring ‘ — 6.1 Replace Inheritance with Delegation Read More »

Notes on ‘Refactoring ‘ — 5.1 Seperate Query from Modifier

Before Refactoring getPersonAndIncreaseCounter(){ counter ++; return person; } After Refactoring getPerson(){ return person; } increaseCounter{ counter ++; } Benefits     You can call getPerson() as often as you like. You have a lot less to worry about. Exception    It’s OK to change personCache in getPerson() method.

Notes on ‘Refactoring ‘ — 5.2 Replace Exception with Test

Before Refactoring try{ return list.get(index); }catch(IndexOutOfBoundsExceptione){ return null; } After Refactoring if(index >= list.size()){ return null; } return list.get(index); Benefits: Avoid too many exceptions since it is not so good to read and it should only be used for an exception flow.

Notes on ‘Refactoring ‘ — 3.3 Replace Type Code with Class

Before Refactor static final int MAN = 1; static final int WOMAN = 2; After Refactor  — Option1 enum Gender{ MAN, WOMAN } After Refactor  — Option2 class Gender{ static final Gender MAN = new Gender(1); static final Gender WOMAN = new Gender(2); private Gender(int value){ } } Benefits: Type Safe

Notes on ‘Refactoring ‘ — 3.5 Replace subclass with Fields

Before Refactor class Person{ boolean isMale(){} } class Male extends Person{ boolean isMale(){ return true; } } class Female extends Person{ boolean isMale(){ return false; } } After Refactor class Person{ private boolean male; private Person(male){ this.male = male; } boolean isMale(){ return male; } Person createMale(){ return new Person(true); } Person createFemale(){ return new …

Notes on ‘Refactoring ‘ — 3.5 Replace subclass with Fields Read More »

Notes on ‘Refactoring ‘ — 4.1 Decompose Conditional

Before Refactor if(age < 60 && age >= 50){ salary = age*10 + 100; }else{ salary = age*5; } After Refactor if(isMidAge(age)){ salary = midAgeSalary(age); }else{ salary = nonMidAgeSalary(age); } Benefits: You hightlight the condiction and make it clear what you are branching on.

Notes on ‘Refactoring ‘ — 3.1 Replace Data Value with Object

Before Refactoring class Employee{ String phoneNumber; someMethod1(){ String area = phoneNumber.subString(…); } } class Employer{ String phoneNumber; someMethod2(){ String area = phoneNumber.subString(…); } } After refactoring class Employee{ Phone phoneNumber; someMethod1(){ String area = phoneNumber.extractAreaCode(); } } class Employer{ Phone phoneNumber; someMethod2(){ String area = phoneNumber.extractAreaCode(); } } class Phone{ String number; String extractAreaCode(){ … …

Notes on ‘Refactoring ‘ — 3.1 Replace Data Value with Object Read More »