??xml version="1.0" encoding="utf-8" standalone="yes"?>国产精品日韩精品中文字幕,午夜免费在线观看精品视频,亚洲国产精品人久久电影http://www.aygfsteel.com/Jennifer/archive/2012/10/30/390472.html******Tue, 30 Oct 2012 09:03:00 GMThttp://www.aygfsteel.com/Jennifer/archive/2012/10/30/390472.htmlhttp://www.aygfsteel.com/Jennifer/comments/390472.htmlhttp://www.aygfsteel.com/Jennifer/archive/2012/10/30/390472.html#Feedback0http://www.aygfsteel.com/Jennifer/comments/commentRss/390472.htmlhttp://www.aygfsteel.com/Jennifer/services/trackbacks/390472.html
首先什么是ExceptionQ?br />

Definition: 

An exception is an event, which occurs during the execution of a program, that disrupts the normal flow of the program's instructions.


再看什么是“程”Q如果流E是指程序的每一步执行,那异常就是控制流E的Q它是用来区分E序的正常流E和非正常流E的Q从上面异常的定义就可以看出。因此ؓ了明我们应该说”不要用异常控制程序的正常程“。如何定义正常流E和非正常流E很难,q是一个主观的军_Q没有一个统一的标准,只能Ҏ实际情况。网上找个例子:
bool isDouble(string someString) {
    
try {
        
double d = Convert.ParseInt32(someString);
    } 
catch(FormatException e) {
        
return false;
    }
    
return true;
}
q个E序其实不是想convert数字Q而是想知道一个字W串是否包含一个数字,通过判断是不是有异常的方式来军_q回trueq是falseQ这是个SmellQ这U应该算”异常控制了正常流E?#8220;。我们可以通过正则表达式或其他方式来判断?br />
另外Clean Code上一个例子:
    try {  
        MealExpenses expenses 
= expenseReportDAO.getMeals(employee.getID());  
        m_total 
+= expenses.getTotal();  
    } 
catch(MealExpensesNotFound e) {  
        m_total 
+= getMealPerDiem();  
    } 
MealExpensesNotFound异常影响了正常的计算m_total的业务逻辑。对于这U情况可以通过一下方式改q?/span>Q?br />
    public class PerDiemMealExpenses implements MealExpenses {  
        
public int getTotal() {  
            
// return the per diem default  
        }  
    } 

以上两个例子是比较明昄异常控制正常程QSmell很明显,不会有很大争议,但是实际情况中可能有很多例子没有q么明显Q因为都是主观判定的。比如一下代码,不异常控制正常流E?

public int doSomething()
{
    doA();
    
try {
        doB();
    } 
catch (MyException e) {
        
return ERROR;
    }
    doC();
    
return SUCCESS;
}

看到q样一D늨序,如果没有上下文,我们无法判断。但是如果doSomething是想让我们回{yes or noQsuccess or errorQ我们不应该通过有无异常来判断yes or noQsuccess or errorQ应该有个单独的Ҏ来判断,q个Ҏ只做这一件事情。如果doSometing是执行一个操作,那么在这个过E中我们假定是不会出现问题的Q否则抛出异常是比较合理的?br />







*** 2012-10-30 17:03 发表评论
]]>
ClassLoader 加蝲机制 http://www.aygfsteel.com/Jennifer/archive/2012/09/08/387307.html******Sat, 08 Sep 2012 09:58:00 GMThttp://www.aygfsteel.com/Jennifer/archive/2012/09/08/387307.htmlhttp://www.aygfsteel.com/Jennifer/comments/387307.htmlhttp://www.aygfsteel.com/Jennifer/archive/2012/09/08/387307.html#Feedback0http://www.aygfsteel.com/Jennifer/comments/commentRss/387307.htmlhttp://www.aygfsteel.com/Jennifer/services/trackbacks/387307.html1. Java Class Loading Mechanism

首先当编译一个Java文gӞ~译器就会在生成的字节码中内|一个publicQstaticQfinal的class字段Q该字段属于java.lang.ClasscdQ该class字段使用Ҏ讉KQ所以可以有Q?/div>
java.lang.Class clazz = MyClass.class

当class被JVM加蝲Q就不再加蝲相同的class。class在JVM中通过QClassLoaderQPackageQClassNameQ来唯一军_。ClassLoader指定了一个class的scopeQ这意味着如果两个相同的包下面的class被不同的ClassLoader加蝲Q它们是不一LQƈ且不是type-compatible的?/div>

JVM中所有的ClassLoaderQbootstrap ClassLoader除外Q都是直接或间接l承于java.lang.ClassLoader抽象c,q且Zؓ逻辑上指定了parent-child关系Q实Cchild不一定承于parentQ我们也可以通过l承它来实现自己的ClassLoader?/div>

JVM ClassLoder架构Q从上到下依ơؓparent-child关系Q?/div>
  • Bootstrap ClassLoader - 启动cd载器Q主要负责加载核心Javacdjava.lang.Object和其他运行时所需classQ位于JRE/lib目录下或-Xbootclasspath指定的目录。我们不知道q多的关于Bootstrap ClassLoader的细节,因ؓ它是一个native的实玎ͼ不是Java实现Q所以不同JVMs的Bootstrap ClassLoader的行Z不尽相同。调?span style="background-color: #eeeeee; font-size: 13px; ">java.lang.String.getClassLoder() q回null?/span>
  • sun.misc.ExtClassLoader - 扩展cd载器Q负责加载JRE/lib/ext目录?Djava.ext.dirs指定目录?/li>
  • sun.misc.AppClassLoader - 应用cd载器Q负责加载java.class.path目录
  • 另外Q还有一些其他的ClassLoader如:java.net.URLClassLoaderQjava.security.SecureClassLoaderQjava.rmi.server.RMIClassLoaderQsun.applet.AppletClassLoader
  • 用户q可以自q承java.lang.ClassLoader来实现自qClassLoaderQ用来动态加载class文g?/li>
ClassLoaderҎ?/strong>Q?/div>
  • 每个ClassLoaderl护一份自q命名I间Q同一个ClassLoader命名I间不能加蝲两个同名的类?/li>
  • 为实现Java安全沙箱模型Q默认采用parent-child加蝲铄构,除Bootstrap ClassLoader没有parent外,每个ClassLoader都有一个逻辑上的parentQ就是加载这个ClassLoader的ClassLoaderQ因为ClassLoader本n也是一个类Q直接或间接的承java.lang.ClassLoader抽象cR?/li>
java.lang.Thread中包含一个public的方法public ClassLoader getContextClassLoader()Q它q回某一U程相关的ClassLoaderQ该ClassLoader是线E的创徏者提供的用来加蝲U程中运行的classes和资源的。如果没有显式的讄其ClassLoaderQ默认是parentU程的Context ClassLoader。Java默认的线E上下文加蝲器是AppClassLoader?/div>

ClassLoader工作原理Q?/strong>

了解ClassLoader工作原理Q先来看一个ClassLoadercȝ化版的loadClass()Ҏ源码
 1 protected Class<?> loadClass(String name, boolean resolve)
 2         throws ClassNotFoundException
 3     {
 4         synchronized (getClassLoadingLock(name)) {
 5             // First, check if the class has already been loaded
 6             Class c = findLoadedClass(name);
 7             if (c == null) {
 8                 long t0 = System.nanoTime();
 9                 try {
10                     if (parent != null) {
11                         c = parent.loadClass(name, false);
12                     } else {
13                         c = findBootstrapClassOrNull(name);
14                     }
15                 } catch (ClassNotFoundException e) {
16                     // ClassNotFoundException thrown if class not found
17                     // from the non-null parent class loader
18                 }
19 
20                 if (c == null) {
21                     // If still not found, then invoke findClass in order
22                     // to find the class.
24                     c = findClass(name);
25                 }
26             }
27             if (resolve) {
28                 resolveClass(c);
29             }
30             return c;
31         }
32     }

首先查看该class是否已被加蝲Q如果已被加载则直接q回Q否则调用parent的loadClass来加载,如果parent是null代表是Bootstrap ClassLoaderQ则有Bootstrap ClassLoader来加载,如果都未加蝲成功Q最后由该ClassLoader自己加蝲。这Uparent-child委派模型Q保证了恶意的替换Java核心cM会发生,因ؓ如果定义了一个恶意java.lang.StringQ它首先会被JVM的Bootstrap ClassLoader加蝲自己JRE/lib下的Q而不会加载恶意的。另外,Java允许同一package下的cd以访问受保护成员的访问权限,如定义一个java.lang.BadQ但是因为java.lang.String由Bootstrap ClassLoader加蝲而java.lang.Bad由AppClassLoader加蝲Q不是同一ClassLoader加蝲Q仍不能讉K?/div>

2. Hotswap - 热部|?/strong>

即不重启JVMQ直接替换class。因为ClassLoaderҎ,同一个ClassLoader命名I间不能加蝲两个同名的类Q所以在不重启JVM的情况下Q只能通过新的ClassLoader来重新load新的class?/div>

 1  public static void main(String[] args) throws InterruptedException, MalformedURLException {
 2         IExample oldExample = new Example();
 3         oldExample.plus();
 4         System.out.println(oldExample.getCount());
 5 
 6         Hotswap hotswap = new Hotswap();
 7         while (true) {
 8             IExample newExample = hotswap.swap(oldExample);
 9             String message = newExample.message();
10             int count = newExample.plus();
11             System.out.println(message.concat(" : " + count));
12             oldExample = newExample;
13             Thread.sleep(5000);
14         }
15     }
16 
利用hotswap替换qExampleQ每5U钟轮询一ơ,swapҎ实现如下Q?/div>
 1  private IExample swap(IExample old) {
 2         try {
 3             String sourceFile = srcPath().concat("Example.java");
 4             if (isChanged(sourceFile)) {
 5                 comiple(sourceFile, classPath());
 6                 MyClassLoader classLoader = new MyClassLoader(new URL[]{new URL("file:"+classPath())});
 7                 Class<?> clazz = classLoader.loadClass("Example");
 8                 System.out.println(IExample.class.getClassLoader());
 9                 IExample exampleInstance = ((IExample) clazz.newInstance()).copy(old);
10                 System.out.println(exampleInstance.getClass().getClassLoader());
11                 return exampleInstance;
12             }
13         } catch ...
24         return old;
25     }
q里必须exampleInstance转型为IExample接口而不是ExmapleQ否则会抛出ClassCastExecptionQ这是因为swapҎ所在类Hotswap是有AppClassLoader加蝲的,而且加蝲Hotswap的同时会加蝲该类引用的Exmaple的symbol linkQ而Example是MyClassLoader加蝲的,不同的ClassLoader加蝲的类之间直接用会抛出ClassCastException, 在本例中ClassLoader实现如下Q?/div>
 1 public class MyClassLoader extends URLClassLoader {
 2 
 3     public MyClassLoader(URL[] urls) {
 4         super(urls);
 5     }
 6 
 7     @Override
 8     public Class<?> loadClass(String name) throws ClassNotFoundException {
 9         if ("Example".equals(name)) {
10             return findClass(name);
11         }
12         return super.loadClass(name);
13     }
14 }
而对IExample我们q是调用super的loadClassҎQ该Ҏ实现仍是JVM的parent-child委派方式Q因此最l由AppClassLoader加蝲Q加载Hotswap时加载的symbol link也是由AppClassLoader加蝲的,因此能够成功?/div>

此外再热部vӞ被替换的cȝ所有引用及状态都要迁Ud新的cMQ本例中只是很简单的调用copy函数q移了count的状态?/div>

Tomcat的jsp热部|机制就是基于ClassLoader实现的,对于其类的热部v机制是通过修改内存中的class字节码实现的?/div>



*** 2012-09-08 17:58 发表评论
]]>Java Runtime exec问题http://www.aygfsteel.com/Jennifer/archive/2012/09/05/387125.html******Wed, 05 Sep 2012 14:43:00 GMThttp://www.aygfsteel.com/Jennifer/archive/2012/09/05/387125.htmlhttp://www.aygfsteel.com/Jennifer/comments/387125.htmlhttp://www.aygfsteel.com/Jennifer/archive/2012/09/05/387125.html#Feedback0http://www.aygfsteel.com/Jennifer/comments/commentRss/387125.htmlhttp://www.aygfsteel.com/Jennifer/services/trackbacks/387125.html1. java.lang.IllegalThreadStateException: process hasn't exited


1 public static void main(String[] args) {
2         try {
3             Process process = Runtime.getRuntime().exec("javac");
4             System.out.println(process.exitValue());
5         } catch (IOException e) {
6             e.printStackTrace();
7         }
8     }

execҎ创徏了一个native的进E,q返回该process的对象,如果q程q没有返回,调用exitValueҎ׃出现此异常,因ؓ该方法没有阻塞,其实现如下:
1 public synchronized int exitValue() {
2         if (!hasExited) {
3             throw new IllegalThreadStateException("process hasn't exited");
4         }
5         return exitcode;
6     }

2. waitForҎ

 1 public static void main(String[] args) {
 2         try {
 3             Process process = Runtime.getRuntime().exec("javac");
 4             int result = process.waitFor();
 5             System.out.println(result);
 6         } catch (IOException e) {
 7             e.printStackTrace();
 8         } catch (InterruptedException e) {
 9             e.printStackTrace();
10         }
11     }

waitForҎ会一直阻塞直到nativeq程完成Qƈq回nativeq程的执行结果。如果nativeq程无法执行完成QwaitForҎ一直阻塞下去,其实现如下:
1 public synchronized int waitFor() throws InterruptedException {
2         while (!hasExited) {
3             wait();
4         }
5         return exitcode;
6     }

该程序在jdk1.7 windows下测试工作正常,q回2; 但是jdk1.4 windows下测试出现hang。JDK documention的解释是
The methods that create processes may not work well for special processes on certain native platforms,
such as 
native windowing processes, daemon processes, Win16/DOS processes on Microsoft Windows,or shell scripts.
The created subprocess does not have its own terminal or console. All its standard io (i.e. stdin, stdout, stderr)
operations will be redirected to the parent process through three streams (getOutputStream(), getInputStream(),
getErrorStream()). The parent process uses these streams to feed input to and get output from the subprocess. Because some 
native platforms only provide limited buffer size for standard input and output streams,
failure to promptly write the input stream or read the output stream of the subprocess may cause
the subprocess to block, and even deadlock.

所以,出现hangӞ及时的flush标准输入输出或者错误流能够消除hangQ如上面的javacQ我们知道redirect到stderr中,所以解决hang后的代码
 1 public static void main(String[] args) {
 2         try {
 3             Process process = Runtime.getRuntime().exec("echo 'abc'>b.txt");
 4             BufferedReader reader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
 5             String line;
 6             while((line=reader.readLine())!=null){
 7                 System.out.println(line);
 8             }
 9             int result = process.waitFor();
10             System.out.println(result);
11         } catch (IOException e) {
12             e.printStackTrace();
13         } catch (InterruptedException e) {
14             e.printStackTrace();
15         }
16     }


3. exec() is not a command line q不是所有的command line命o都可以用exec

 1  public static void main(String[] args) {
 2         try {
 3             Process process = Runtime.getRuntime().exec("echo 'abc'>a.txt");
 4             BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
 5             String line;
 6             while((line=reader.readLine())!=null){
 7                 System.out.println(line);
 8             }
 9             int result = process.waitFor();
10             System.out.println(result);
11         } catch (IOException e) {
12             e.printStackTrace();
13         } catch (InterruptedException e) {
14             e.printStackTrace();
15         }
16     }
l果为:
1 'abc'>a.txt
2 0
q没有将创徏a.txtQ而从命o行执?span style="color: #000000; ">"echo 'abc'>a.txt"却正创Za.txt

*** 2012-09-05 22:43 发表评论
]]>Practices of Extreme Programming - XPhttp://www.aygfsteel.com/Jennifer/archive/2011/11/03/362636.html******Thu, 03 Nov 2011 13:44:00 GMThttp://www.aygfsteel.com/Jennifer/archive/2011/11/03/362636.htmlhttp://www.aygfsteel.com/Jennifer/comments/362636.htmlhttp://www.aygfsteel.com/Jennifer/archive/2011/11/03/362636.html#Feedback0http://www.aygfsteel.com/Jennifer/comments/commentRss/362636.htmlhttp://www.aygfsteel.com/Jennifer/services/trackbacks/362636.html
  1. Whole Team - Cutomers, managers and developers work closely with one another. So they are all aware of one another's problem and are collaborating to solve the problem. The customers can be a group of BAs, QAs or marketing persons in the same company as developers. The customers can be the paying customer. But in an XP project, the customer, however defined, is the member of and available to the team.
  2. User Stories - In order to plan a project, we must know something about the requirement, but we don't need to know very much. We need to know only enough about a requirement to estimate it. You may think that in order to estimate the requirement, you need to know all the details. That's not quite true. You have to know that there are details and you have to know roughly the kinds of details, but you don't have to know the sepecifics. Since the sepecific details of the requirements are likely to change with time, especially once the customers begin to see the system together. So when talking about requirements with the customer, we write some key words on a card to remind us of the conversation. A user story is memonic token of an ongoing conversation about a requirement. Every user story should have an estimation.
  3. Short Cycles - An XP project delivers working software every iteration - one or two weeks. At the end of each iteration, the sytem is demonstrated to the customer or the stakeholder in order to get their feedbacks. Every release there is a major delivery that can be put into production.
  4. The Planning Game - The customers decide how important a feature is and the developers decide how much effort the feature will cost to implement. So the customers will select a collection of stories based on the priority and the previous iterations' velocity.
    1. The Iteration Plan - Once an iteration has been started, the business agrees not to change the definition or priority of the stories in that iteration. The order of the stories within the iteration is a technical decision. The developers may work on the stories serially or concurrently. It depends but it's a technical decision.
    2. The Release Plan - A release is usually three months. Similarly, the business or customer selecte collections of user stories and determines the priority based on their buget. But release are not cast in stone. The business can change or reorder at any time. They can write new stories, cancel stroies or change the priority. However, the business should not to change an interation that has been started.
  5. Acceptance Tests - The detail about the user stories are captured in the form of acceptance tests specified by the customer. The acceptance tests are written by BAs and QAs immediately before or concurrently with the implementation of that story. They are written in a scripting form that allow them to be run automatically and repeatlly. These tests should be easy to read and understand for customers and business people. These tests become the true requirement document of the project. Once the acceptance test passes, it will be added the body of passing acceptance tests and is never allowed to fail. So the system is migrated from one working state to another.
  6. Pair Programming - One memeber of each pair drives the keyboard and types the code. The other member of the pair watches the code being typed, finding errors and improvements.
    1. The roles change frequently. If the driver gets tired or stuck, the pair grabs the keyboard and starts to drive. The keybord will move back and forth between them serval times in one hour. The resulting code is designed and authored by both memebers.
    2. Pair memebership changes frequently. A reasonable goal is to change pair partner at least once per day. They should have worked on about everything that was going on in this iteration. Also it is very good for knowledge transfer.
  7. Collective Ownership - A pair has right to check out any module and imporve it. No particular pair or developer are individually responsible for one particular module. Every developer of the project has fully responsible for each line of the code. So don't complain about the code may be written by the other pair. Let's try to improve it. Since it is our code.
  8. Open Workspace - The team works together at one table or in one room. Each pair is within earshot of every other pair. Each has the opportunity to hear when another pair is in trouble. Each konws the state of the other. The sound in this room is a buzz of conversation. One might think that this would be a noise and distracting envrionment. But study suggested, working in a "war room" envrionment may increase productivity.
  9. Simple Design - An XP team makes its designs as simple and expressive as they can be. Furthermore, the team narrows its focus to consider only the stories that are planned for the current iteration, not worrying about stories to come. The team migrates the design of the system from iteration to iteration to be the best design for the stories that the system currently implements.
    1. consider the simplest thing that could possibly work. - XP teams always try to find the simplest possible design option fot the current batch of stories.
    2. You aren't going to need it. - That means an XP team introduces one technology or one infrastructure before it is strictly needed. Yeah, but we know we are going to need that database one day. We are going to have to support multiple threads one day. So don't we need to put the hooks in for those things? The team puts the technology or infrastucture in only if it has proof or at least very compelling evidence. that putting it in now will be more cost-effective than waiting.
    3. Once and only once. XPers don't tolerate duplication of code. Wherever they find it. they remove it. The best way to remove redundancy is to create abstractions. After all, if two things are similar, some abstraction can be from them.
  10. Continuous Integration
  11. Sustainable Pace
  12. Test-Driven Development
  13. Refactoring
  14. Metaphor


*** 2011-11-03 21:44 发表评论
]]>
数据库范?/title><link>http://www.aygfsteel.com/Jennifer/archive/2011/10/30/362331.html</link><dc:creator>***</dc:creator><author>***</author><pubDate>Sun, 30 Oct 2011 14:27:00 GMT</pubDate><guid>http://www.aygfsteel.com/Jennifer/archive/2011/10/30/362331.html</guid><wfw:comment>http://www.aygfsteel.com/Jennifer/comments/362331.html</wfw:comment><comments>http://www.aygfsteel.com/Jennifer/archive/2011/10/30/362331.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/Jennifer/comments/commentRss/362331.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/Jennifer/services/trackbacks/362331.html</trackback:ping><description><![CDATA[<ol><li> W一范式 - 列的原子性,数据库表中的每一列都是不可再分的基本数据?/li><ol><li>单一字段有多个有意义的|比如 QpeopleQaddressQ其中address包括streetQcityQcountryQ以逗号分割。想要查询住在某一city的people很不Ҏ</li><li>用很多字D|表示同一事实Q比如(peopleQaddress1Qaddress2Qaddress3Q,q我们假设每个people最多有三个地址Q当惌查询住在同一地址的people时也很不ҎQ因为有可能people1的address1与people2的address2相同Q每一ơ都要比?*3ơ组?br /></li></ol><li>W二范式 - W合W一范式Q且表中的属性必d全依赖于全部主键Q消除非d性对主键的部分依?/li><ol><li>比如Q组件IDQ供应商IDQ供应商姓名Qh|Q组件ID+供应商IDZ键,h完全依赖于全部主键,因ؓ不同lg不同供应商具有不同h|但是对于供应商姓名,则只依赖于供应商IDQ会造成对同一供应商IDQ名字数据重复,而且如果供应商改名,需要修改全部数据。因此需要单独一个表Q供应商IDQ供应商姓名Q,Q组件IDQ供应商IDQh|<br /></li></ol><li>W三范式 - 非主属性之间不能有依赖关系Q必都直接依赖于主属性,消除传递依?/li><ol><li>比如Q组件IDQ制造商姓名Q制造商地址Q,其中lgIDZ键,而制造商地址依赖于制造商姓名Q需要(lgIDQ制造商姓名Q和新表Q制造商姓名Q制造商地址Q其中姓名是主键</li><li>比如Q订单IDQ组件IDQ单P数量QMhQ,其中Mh=单h*数量QMh依赖于单价和数量Q需要去掉Mh?br /></li></ol><li>BC范式 - M属性(包括非主属性和d性)不能被非d性所军_。第三范式强调非d性不能依赖于其他非主属性,BC范式是第三范式的加强Q强?#8220;M属?#8221;。因此如果满第三范式,q且只有一个主键,则一定满BC范式</li></ol><p>一般,范式高Q表多Q数据库操作旉要表兌Q增加了查询的复杂性,降低了查询性能。因此ƈ不是范式高好Q要Ҏ需要进行权衡,W三范式已经消除了大部分的数据冗余,插入异常Q更新异常和删除异常?br /></p><img src ="http://www.aygfsteel.com/Jennifer/aggbug/362331.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/Jennifer/" target="_blank">***</a> 2011-10-30 22:27 <a href="http://www.aygfsteel.com/Jennifer/archive/2011/10/30/362331.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Page Object Patter For Functional Testhttp://www.aygfsteel.com/Jennifer/archive/2011/10/18/361542.html******Tue, 18 Oct 2011 13:57:00 GMThttp://www.aygfsteel.com/Jennifer/archive/2011/10/18/361542.htmlhttp://www.aygfsteel.com/Jennifer/comments/361542.htmlhttp://www.aygfsteel.com/Jennifer/archive/2011/10/18/361542.html#Feedback0http://www.aygfsteel.com/Jennifer/comments/commentRss/361542.htmlhttp://www.aygfsteel.com/Jennifer/services/trackbacks/361542.htmlWhy?
Functional test characteristic
  1. The number of tests is mostly large.
  2. Page structure and elements may be changed frequently.

If our tests interact directly with the test driver (selenium,etc).
  1. UI element locators(Xpath, CSS, element Ids, names, etc) are copuled and repeat throughout the tests logic. It is hard to maintain, refactor and change especially when we change the page structure.
  2. The fine-grained UI operations hide our actual test intention. After some time we can not easily to identify what we want to do before.

What?
A Page Object models the UI elements that your tests interact with as objects within the test code. It decouples the test logic from the fine-grained details of the UI page.

Test -> Page Object -> Test Driver

The driver is the actual executor of browser action, like click, select, type etc. The page object has knowledage of the HTML structure.


Advantages
  1. When UI changes, only responding page object need to be changed. The tests logic will not be affected.
  2. It makes our tests logic simpler and more readable. Since the tests logic can only focus on its test secinaro rather than the structure of HTML page. As an example, think of login function, it only needs username and password, then do login action. How these are implemented shouldn't matter to the test. We don't care about that it uses a button or link to login.
  3. Complex interactions can be modeled as methods on the page object, which can be used in multiple times.

Best Practices

  1. Public methods represent the services that the page offers
  2. Try not to expose the internals of the page. Like OO programming, object just expose the behaviour and hide its internal details.
  3. Generally don't make assertions, but it is better to do some kind of check to ensure the browser is actually on the page it should be. Since our following tests are all base on the assumption. It can be done by checking something simple like title.
  4. Methods return other page object. This means that we can effectively model the user's journey through our application.
  5. Don't need to represent the entire page. It can be just a tab or a navigation bar that your test interacts with.
  6. Only one place knows the HTML structure of a particular page. UI changes, the fix need only be applied in one place.
  7. Different results for the same action are modeled as different methods. Since the test knows the expected state.

 

*** 2011-10-18 21:57 发表评论
]]>
Function - Clean Codehttp://www.aygfsteel.com/Jennifer/archive/2011/08/25/357234.html******Thu, 25 Aug 2011 00:45:00 GMThttp://www.aygfsteel.com/Jennifer/archive/2011/08/25/357234.htmlhttp://www.aygfsteel.com/Jennifer/comments/357234.htmlhttp://www.aygfsteel.com/Jennifer/archive/2011/08/25/357234.html#Feedback0http://www.aygfsteel.com/Jennifer/comments/commentRss/357234.htmlhttp://www.aygfsteel.com/Jennifer/services/trackbacks/357234.htmlSmall
and the indent level should not be greater than one or two.
2. Do One Thing - Functions should do one thing. They should do it well. They should do it only.
    Steps of function are one level of abstraction below the name of the function. Then the function is doing one thing.
    Another way to know function is doing more than one thing is if you can extract another function from it.
3. One level of abstraction per function
    The stepdown rule - reading code from top to bottom.
    switch
4. Use Descriptive Names
    Don't be afraid to make a name long.
    A long descriptive name is better than a short magic name.
    A long descriptive name is better than a long descriptive comment.
    Dont't be afraid to spend time choosing a name.
    Be consistent in your names.
5. Function Arguments
    The ideal number of arguments for a function is zero.
    Three arguments should be avoided.
    Flag Arguments - can be split into two function.
    Aruments Objects - group the variables and abstract concept if possible.
    Verbs and keywords - function and argument should form a very nice verb/noun pair.
6. Have no side effects
7. Command Query Separation - Functions should either do something or answer something, but not both.
8. Prefer Exceptions to returning error codes.
    Extract try/catch blocks, error handling is one thing.
9. DRY - don't repeat yourself - especially the duplicated logic.


*** 2011-08-25 08:45 发表评论
]]>JavaScript中存在问题但却难以避免的功能Ҏ?/title><link>http://www.aygfsteel.com/Jennifer/archive/2011/07/18/354560.html</link><dc:creator>***</dc:creator><author>***</author><pubDate>Mon, 18 Jul 2011 12:09:00 GMT</pubDate><guid>http://www.aygfsteel.com/Jennifer/archive/2011/07/18/354560.html</guid><wfw:comment>http://www.aygfsteel.com/Jennifer/comments/354560.html</wfw:comment><comments>http://www.aygfsteel.com/Jennifer/archive/2011/07/18/354560.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/Jennifer/comments/commentRss/354560.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/Jennifer/services/trackbacks/354560.html</trackback:ping><description><![CDATA[一Q全局变量<br />1.全局变量可以被Q何部分在L旉改变Q复杂化Q降低可靠?br />2.可能与子E序变量名相同,冲突可能DE序无法q行Q难以调?br /><br />三种声明全局变量模式<br />1.qM函数的var foo Q?value<br />2.直接d属性至全局对象Q全局对象是所有全局变量的容器,在web览器中全局对象名ؓwindowQwindow.foo = value<br />3.直接未经声明的变?Q?隐式的全局变量 foo Q?value<br /><br />二,没有块作用域Q有函数作用?br /><br />函数中定义的参数和变量在函数外部不可见,而在一个函CM位置的定义的变量在该函数的Q何地方可见?br /><br />function f1(){<br />    var a=1;<br />    function f2(){<br />        if(false){<br />            var a=2;    //变量Z函数Q而非Z语句块,没有块作用域<br />        }<br />        console.log(a); //undefined 未定?br />    }<br />    f2();<br />    console.log(a);//1<br />}<br />f1();<br /><br />大多数语a中,一般声明变量都是在W一ơ用到它的地方,在javascript中是一个坏习惯Q因为没有块作用域,更好的是在每个函数开头声明所有变量?br /><br />三,return语句q回一个|D辑ּ必须和return在同一行上<br /><br />return {<br />    status:true<br />};<br /><br />q回包含status成员元素的对象?br /><br />如果?br /><br />return<br />{<br />    status:true<br />};<br /><br />会返回undefined?br /><br />四,保留字不能用来命名变量或函数Q当保留字被用作对象字面量的键值时Q必ȝ引号Q而且不能用点表示法,必须使用括号表示法?br /><br />var object = {case:value}; //非法<br />var object = {'case':value}; //ok<br />object.case = value;       //非法<br />object['case'] = value;    //ok<br /><br />各浏览器对保留字使用限制上实C同,以上语法在FF中合法,但其他浏览器不合法;再有不同的保留字行ؓ也不相同。类似int/long/float{保留字在各览器中都可以做变量名及对象字面量的键倹{但不徏议用Q何保留字?br /><br />五,typeof Q?识别q算数类型的字符?br /><br />但typeof nullq回'object'Q更好的null的方法: my_value === null<br /><br />对于正则表达?typeof /a/Q一些浏览器q回'object'Q另一些返?function'<br /><br />六,parseInt Q?字W串转换为整?br /><br />1.此函数遇到非数字时就停止解析Q即parseInt('16')和parseInt('16 abc')产生l果相同Q都?6.<br />2.如果字符串第一个字W是0Q则Z八进制解析,而不是十q制。八q制中没?Q?数字Q所以parseInt('08')和parseInt('09')l果?。此函数可以接收一个基C为参敎ͼparseInt('08',10)l果??br /><br />七,点?br /><br />0.1+0.2不等?.3<br /><br />八,NaN<br /><br />function isNumber(value){<br />    return typeof value === 'number' && isFinite(value);<br />}<br /><br />isFinite{调NaN和InfinityQ但是isFinite会试图把它的q算数{换ؓ一个数字,如果q算C实上不是一个数字,׃报错Q所以加上typeof value === 'number'?br /><br />九,假?br /><br />0QNaNQ?'QfalseQnullQundefined全部{于假,但它们是不可互换的?img src ="http://www.aygfsteel.com/Jennifer/aggbug/354560.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/Jennifer/" target="_blank">***</a> 2011-07-18 20:09 <a href="http://www.aygfsteel.com/Jennifer/archive/2011/07/18/354560.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>|伯特议事规?/title><link>http://www.aygfsteel.com/Jennifer/archive/2011/07/11/354071.html</link><dc:creator>***</dc:creator><author>***</author><pubDate>Mon, 11 Jul 2011 00:27:00 GMT</pubDate><guid>http://www.aygfsteel.com/Jennifer/archive/2011/07/11/354071.html</guid><wfw:comment>http://www.aygfsteel.com/Jennifer/comments/354071.html</wfw:comment><comments>http://www.aygfsteel.com/Jennifer/archive/2011/07/11/354071.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/Jennifer/comments/commentRss/354071.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/Jennifer/services/trackbacks/354071.html</trackback:ping><description><![CDATA[印象中美国hq求自由Q但他们开会时却是严肃认真Q说到开会,他们有一本厚厚的开会规则-|伯特议事规则。作者亨?马丁.|伯Ҏ业于西点军校Q有一ơ奉命主持一个地Ҏ会的会议Q结果h们争个不亦乐乎,什么结论都没有Q搞砸啦。于是罗伯特研究Z一些规则,最初只有四五条Q放在钱包里Q开会时遵守q些规则Q就能顺利成功。后?876q罗伯特写了《通用议事规则》。至今发行五百万册,|伯特议事规则已取得最q泛的认可和应用Q它的根本意囑֜于一个会议能以尽可能最有效的方式达到它的目的?br /><br />话说|伯特议事规则初C国是在组l农村开会时Q当时会议及其؜乱,表现为:<br />一Q你说周CuQ我引出周润发,东一榔头西一子Q最后忘了开会的目的是啥Q还可能对于已经讨论表决的问题,又重新拿来说Q反反复复,归结h是跑题Q?br />二,领导或者权威讲个不停,下面人睡着啦,归结Z家言Q?br />三,争论hQ互相指责,甚至ndQ归lؓ野蛮争论?br /><br />其实q三条也是我们日怼议经常出现的问题?br /><br />首先说野蛮争论问题,很容易解冻I|伯特议事规则限制只对会议讨论的问题发言Q不允许评议个hQ发a时对L行陈qͼ而非辩论Ҏ。ȝhQ用中国a语来说就?#8220;对事不对?#8221;Q因为指责个人ƈ不能解决问题Q不允许指责一个会员的动机Q动机很难衡量,但可以用强烈的语a谴责一个议案的性质或后果?br /><br />W二对于一家言问题Q罗伯特议事规则限制每个人发a的次数和旉用以避免一家言问题。其实这是个人智慧和l验与集体合作的关系Q仍用中国言语来?#8220;三个臭皮匠顶个诸葛亮”。对于睡着问题Q可能是׃发言人太pQ可以通过前述Ҏ解决Q还可能是由于当前话题不感兴甚x养I则可直接d会议或不参加?br /><br />W三对于跑题问题Q罗伯特议事规则规定会议讨论的内容应当是一个明的动议Q?#8220;动议Q动议,是行动的徏议!”动议必须是具体的Q明的Q可操作的行动徏议,每一个动议都会导致一个action。比?#8220;早上9点上?#8221;Q而不?#8220;早上几点上班Q?#8221;。发a人应首先表明观点Q赞成还是反对,qq理由。与本次会议动议无关的其他动议,应组l其他会议,x们常说的“一事一?#8221;。经双方轮流发言后,L人组l投。对于已l表决的观点Q除非理由充分,q经所有成?/3同意再议Q再l织再次讨论?br /><br />对于W三条,我觉得首先需要把qx会议划分一下几c:<br />1.sessionQ做session的h事先准备好内容,q计划和把握session旉Q同样中间遇Csession无关的其他问题或者非常detail的问题,做session的h要打断讨论,对于重要问题l织其他sessionQ对于detail问题offline讨论?br />2.discussionQ如|伯特议事规则所_l织discussion的h要有明确的动议,支持方与反对方轮发aQ如果规定时间未达成一_l织者须l织投票?br />3.brainstormQ通过集思广益、发挥集体智慧,q速地获得大量的新设想与创意,q是一U极为有效的开启创新思维的方法。头脑风暴结束后才开始对观点q行讨论Q那针对每一个讨论,又是一个discussion?br /><br />另外Qƈ不是所有会议都必须所有h参加Q如果感觉对自己影响不大或者有比会议更要紧的事情可以不参加Q或中间d?img src ="http://www.aygfsteel.com/Jennifer/aggbug/354071.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/Jennifer/" target="_blank">***</a> 2011-07-11 08:27 <a href="http://www.aygfsteel.com/Jennifer/archive/2011/07/11/354071.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ORA-00257 archiver error. Connect internal only, until freedhttp://www.aygfsteel.com/Jennifer/archive/2011/06/02/351636.html******Thu, 02 Jun 2011 14:48:00 GMThttp://www.aygfsteel.com/Jennifer/archive/2011/06/02/351636.htmlhttp://www.aygfsteel.com/Jennifer/comments/351636.htmlhttp://www.aygfsteel.com/Jennifer/archive/2011/06/02/351636.html#Feedback0http://www.aygfsteel.com/Jennifer/comments/commentRss/351636.htmlhttp://www.aygfsteel.com/Jennifer/services/trackbacks/351636.htmlsu oracle
2. Log in as sys user: $sqlplus sys/password as sysdba
3. Find out flash recovery area usage info, from where we can find the archive log space usage percent: SQL>select * from V$FLASH_RECOVERY_AREA_USAGE;
4. Caculate the space used by flash recovery area:SQL>select sum(percent_space_used)*3/100 from V$FLASH_RECOVERY_AREA_USAGE;
5. Show Archive log location: SQL>show parameter log_archive_dest;
6. Show recovery area location: SQL>show parameter recover;
7. Delete or move some old archive log files: SQL>rm -rf archive_log_2011_06_0*;
Notice: After step 7, we must use RMAN to maintain the control files, otherwise, the deletion changes can not be apply.
8. Log in as RMAN: SQL>rman target sys/password;
9. Find out unused archive log: SQL>crosscheck archive log all;
10. Delete expired archive log files: SQL>delete expired archivelog all;
11. Check the flash recovery area usage info again, make sure archive log files have been deleted: SQL>select * from V$FLASH_RECOVERY_AREA_USAGE;
12. Finally, increase the recovery file destination size: SQL>alter system set db_recovery_file_dest_size=3G scope=both;

*** 2011-06-02 22:48 发表评论
]]>
վ֩ģ壺 | ƽ| Ϫ| ̨| ֶ| | | | | | | ɳ| ƺ| | | Ϫ| | ͨ| Դ| ػ| | | ̨| | | | | | | | ɳ| | ɽ| ƽ½| ɽ| | | | ̨| | |