Archive for June, 2007

You are currently browsing the archives of Enabling Technology .

创建本地化的google gadget

http://www.google.com/apis/gadgets/i18n.html#Introduction
 Creating a Localized Gadget
To create a localized gadget, the basic steps are as follows:

  1. Write the gadget.
  2. Extract any text that needs to be translated into message bundles.
  3. Find someone who can help you translate the gadget.
  4. The translator creates a new message bundle for a particular locale. This could be per language (French), or per language/country (French/Canada, French/France). Note that non-English message bundles must be saved in UTF-8 format.
  5. The translator sends you a URL to the new bundle.
  6. Modify your gadget spec to use the message bundle.
  7. If your gadget is in the Content Directory, wait 1-2 weeks for the crawler and pipeline to find your updated gadget and make it available in the new market.

Posted by micas on Jun 29th 2007 | Filed in Google Tech | Comments (0)

Google Gadget

Dev guide:

http://www.google.com/apis/gadgets/index.html
Where to submit :

http://www.google.com/ig/submit

Help:

http://www.google.com/apis/gadgets/docs-home.html

Google provide a place to host gadget:
http://www.google.com/apis/gadgets/basic.html#Hosting

Posted by micas on Jun 29th 2007 | Filed in Google Tech | Comments (0)

SortUtil:

package org.rut.util.algorithm;

import org.rut.util.algorithm.support.BubbleSort;
import org.rut.util.algorithm.support.HeapSort;
import org.rut.util.algorithm.support.ImprovedMergeSort;
import org.rut.util.algorithm.support.ImprovedQuickSort;
import org.rut.util.algorithm.support.InsertSort;
import org.rut.util.algorithm.support.MergeSort;
import org.rut.util.algorithm.support.QuickSort;
import org.rut.util.algorithm.support.SelectionSort;
import org.rut.util.algorithm.support.ShellSort;

/**
 * @author treeroot
 * @since 2006-2-2
 * @version 1.0
 */
public class SortUtil {
    public final static int INSERT = 1;
    public final static int BUBBLE = 2;
    public final static int SELECTION = 3;
    public final static int SHELL = 4;
    public final static int QUICK = 5;
    public final static int IMPROVED_QUICK = 6;
    public final static int MERGE = 7;
    public final static int IMPROVED_MERGE = 8;
    public final static int HEAP = 9;

    public static void sort(int[] data) {
        sort(data, IMPROVED_QUICK);
    }
    private static String[] name={
            “insert”, “bubble”, “selection”, “shell”, “quick”, “improved_quick”, “merge”, “improved_merge”, “heap”
    };
    
    private static Sort[] impl=new Sort[]{
            new InsertSort(),
            new BubbleSort(),
            new SelectionSort(),
            new ShellSort(),
            new QuickSort(),
            new ImprovedQuickSort(),
            new MergeSort(),
            new ImprovedMergeSort(),
            new HeapSort()
    };

    public static String toString(int algorithm){
        return name[algorithm-1];
    }
    
    public static void sort(int[] data, int algorithm) {
        impl[algorithm-1].sort(data);
    }

    public static interface Sort {
        public void sort(int[] data);
    }

    public static void swap(int[] data, int i, int j) {
        int temp = data[i];
        data[i] = data[j];
        data[j] = temp;
    }
}

Posted by micas on Jun 28th 2007 | Filed in JavaBasic | Comments (0)

堆排序:

package org.rut.util.algorithm.support;

import org.rut.util.algorithm.SortUtil;

/**
 * @author treeroot
 * @since 2006-2-2
 * @version 1.0
 */
public class HeapSort implements SortUtil.Sort{

    /* (non-Javadoc)
     * @see org.rut.util.algorithm.SortUtil.Sort#sort(int[])
     */
    public void sort(int[] data) {
        MaxHeap h=new MaxHeap();
        h.init(data);
        for(int i=0;i<data.length;i++)
            h.remove();
        System.arraycopy(h.queue,1,data,0,data.length);
    }

     private static class MaxHeap{        
       
        void init(int[] data){
            this.queue=new int[data.length+1];
            for(int i=0;i<data.length;i++){
                queue[++size]=data[i];
                fixUp(size);
            }
        }
        
        private int size=0;

        private int[] queue;
               
        public int get() {
            return queue[1];
        }

        public void remove() {
            SortUtil.swap(queue,1,size–);
            fixDown(1);
        }
        //fixdown
        private void fixDown(int k) {
            int j;
            while ((j = k << 1) <= size) {
                if (j < size && queue[j]<queue[j+1])
                    j++;
                if (queue[k]>queue[j]) //不用交换
                    break;
                SortUtil.swap(queue,j,k);
                k = j;
            }
        }
        private void fixUp(int k) {
            while (k > 1) {
                int j = k >> 1;
                if (queue[j]>queue[k])
                    break;
                SortUtil.swap(queue,j,k);
                k = j;
            }
        }

    }

}

Posted by micas on Jun 28th 2007 | Filed in JavaBasic | Comments (0)

归并排序:

package org.rut.util.algorithm.support;

import org.rut.util.algorithm.SortUtil;

/**
 * @author treeroot
 * @since 2006-2-2
 * @version 1.0
 */
public class MergeSort implements SortUtil.Sort{

    /* (non-Javadoc)
     * @see org.rut.util.algorithm.SortUtil.Sort#sort(int[])
     */
    public void sort(int[] data) {
        int[] temp=new int[data.length];
        mergeSort(data,temp,0,data.length-1);
    }
   
    private void mergeSort(int[] data,int[] temp,int l,int r){
        int mid=(l+r)/2;
        if(l==r) return ;
        mergeSort(data,temp,l,mid);
        mergeSort(data,temp,mid+1,r);
        for(int i=l;i<=r;i++){
            temp[i]=data[i];
        }
        int i1=l;
        int i2=mid+1;
        for(int cur=l;cur<=r;cur++){
            if(i1==mid+1)
                data[cur]=temp[i2++];
            else if(i2>r)
                data[cur]=temp[i1++];
            else if(temp[i1]<temp[i2])
                data[cur]=temp[i1++];
            else
                data[cur]=temp[i2++];           
        }
    }

}
改进后的归并排序:

package org.rut.util.algorithm.support;

import org.rut.util.algorithm.SortUtil;

/**
 * @author treeroot
 * @since 2006-2-2
 * @version 1.0
 */
public class ImprovedMergeSort implements SortUtil.Sort {

    private static final int THRESHOLD = 10;

    /*
     * (non-Javadoc)
     *
     * @see org.rut.util.algorithm.SortUtil.Sort#sort(int[])
     */
    public void sort(int[] data) {
        int[] temp=new int[data.length];
        mergeSort(data,temp,0,data.length-1);
    }

    private void mergeSort(int[] data, int[] temp, int l, int r) {
        int i, j, k;
        int mid = (l + r) / 2;
        if (l == r)
            return;
        if ((mid - l) >= THRESHOLD)
            mergeSort(data, temp, l, mid);
        else
            insertSort(data, l, mid - l + 1);
        if ((r - mid) > THRESHOLD)
            mergeSort(data, temp, mid + 1, r);
        else
            insertSort(data, mid + 1, r - mid);

        for (i = l; i <= mid; i++) {
            temp[i] = data[i];
        }
        for (j = 1; j <= r - mid; j++) {
            temp[r - j + 1] = data[j + mid];
        }
        int a = temp[l];
        int b = temp[r];
        for (i = l, j = r, k = l; k <= r; k++) {
            if (a < b) {
                data[k] = temp[i++];
                a = temp[i];
            } else {
                data[k] = temp[j–];
                b = temp[j];
            }
        }
    }

    /**
     * @param data
     * @param l
     * @param i
     */
    private void insertSort(int[] data, int start, int len) {
        for(int i=start+1;i<start+len;i++){
            for(int j=i;(j>start) && data[j]<data[j-1];j–){
                SortUtil.swap(data,j,j-1);
            }
        }
    }
}

Posted by micas on Jun 28th 2007 | Filed in JavaBasic | Comments (0)

快速排序:

package org.rut.util.algorithm.support;

import org.rut.util.algorithm.SortUtil;

/**
 * @author treeroot
 * @since 2006-2-2
 * @version 1.0
 */
public class QuickSort implements SortUtil.Sort{

    /* (non-Javadoc)
     * @see org.rut.util.algorithm.SortUtil.Sort#sort(int[])
     */
    public void sort(int[] data) {
        quickSort(data,0,data.length-1);       
    }
    private void quickSort(int[] data,int i,int j){
        int pivotIndex=(i+j)/2;
        //swap
        SortUtil.swap(data,pivotIndex,j);
       
        int k=partition(data,i-1,j,data[j]);
        SortUtil.swap(data,k,j);
        if((k-i)>1) quickSort(data,i,k-1);
        if((j-k)>1) quickSort(data,k+1,j);
       
    }
    /**
     * @param data
     * @param i
     * @param j
     * @return
     */
    private int partition(int[] data, int l, int r,int pivot) {
        do{
           while(data[++l]<pivot);
           while((r!=0)&&data[–r]>pivot);
           SortUtil.swap(data,l,r);
        }
        while(l<r);
        SortUtil.swap(data,l,r);       
        return l;
    }

}
改进后的快速排序:

package org.rut.util.algorithm.support;

import org.rut.util.algorithm.SortUtil;

/**
 * @author treeroot
 * @since 2006-2-2
 * @version 1.0
 */
public class ImprovedQuickSort implements SortUtil.Sort {

    private static int MAX_STACK_SIZE=4096;
    private static int THRESHOLD=10;
    /* (non-Javadoc)
     * @see org.rut.util.algorithm.SortUtil.Sort#sort(int[])
     */
    public void sort(int[] data) {
        int[] stack=new int[MAX_STACK_SIZE];
       
        int top=-1;
        int pivot;
        int pivotIndex,l,r;
       
        stack[++top]=0;
        stack[++top]=data.length-1;
       
        while(top>0){
            int j=stack[top–];
            int i=stack[top–];
           
            pivotIndex=(i+j)/2;
            pivot=data[pivotIndex];
           
            SortUtil.swap(data,pivotIndex,j);
           
            //partition
            l=i-1;
            r=j;
            do{
                while(data[++l]<pivot);
                while((r!=0)&&(data[–r]>pivot));
                SortUtil.swap(data,l,r);
            }
            while(l<r);
            SortUtil.swap(data,l,r);
            SortUtil.swap(data,l,j);
           
            if((l-i)>THRESHOLD){
                stack[++top]=i;
                stack[++top]=l-1;
            }
            if((j-l)>THRESHOLD){
                stack[++top]=l+1;
                stack[++top]=j;
            }
           
        }
        //new InsertSort().sort(data);
        insertSort(data);
    }
    /**
     * @param data
     */
    private void insertSort(int[] data) {
        int temp;
        for(int i=1;i<data.length;i++){
            for(int j=i;(j>0)&&(data[j]<data[j-1]);j–){
                SortUtil.swap(data,j,j-1);
            }
        }      
    }

}

Posted by micas on Jun 28th 2007 | Filed in JavaBasic | Comments (0)

用Java实现几种常见的排序算法

用Java语言实现的各种排序,包括插入排序、冒泡排序、选择排序、Shell排序、快速排序、归并排序、堆排序、SortUtil等。

插入排序:

package org.rut.util.algorithm.support;

import org.rut.util.algorithm.SortUtil;
/**
 * @author treeroot
 * @since 2006-2-2
 * @version 1.0
 */
public class InsertSort implements SortUtil.Sort{

    /* (non-Javadoc)
     * @see org.rut.util.algorithm.SortUtil.Sort#sort(int[])
     */
    public void sort(int[] data) {
        int temp;
        for(int i=1;i<data.length;i++){
            for(int j=i;(j>0)&&(data[j]<data[j-1]);j–){
                SortUtil.swap(data,j,j-1);
            }
        }       
    }

}
冒泡排序:

package org.rut.util.algorithm.support;

import org.rut.util.algorithm.SortUtil;

/**
 * @author treeroot
 * @since 2006-2-2
 * @version 1.0
 */
public class BubbleSort implements SortUtil.Sort{

    /* (non-Javadoc)
     * @see org.rut.util.algorithm.SortUtil.Sort#sort(int[])
     */
    public void sort(int[] data) {
        int temp;
        for(int i=0;i<data.length;i++){
            for(int j=data.length-1;j>i;j–){
                if(data[j]<data[j-1]){
                    SortUtil.swap(data,j,j-1);
                }
            }
        }
    }

}

选择排序:

package org.rut.util.algorithm.support;

import org.rut.util.algorithm.SortUtil;

/**
 * @author treeroot
 * @since 2006-2-2
 * @version 1.0
 */
public class SelectionSort implements SortUtil.Sort {

    /*
     * (non-Javadoc)
     *
     * @see org.rut.util.algorithm.SortUtil.Sort#sort(int[])
     */
    public void sort(int[] data) {
        int temp;
        for (int i = 0; i < data.length; i++) {
            int lowIndex = i;
            for (int j = data.length - 1; j > i; j–) {
                if (data[j] < data[lowIndex]) {
                    lowIndex = j;
                }
            }
            SortUtil.swap(data,i,lowIndex);
        }
    }

}
Shell排序:

package org.rut.util.algorithm.support;

import org.rut.util.algorithm.SortUtil;

/**
 * @author treeroot
 * @since 2006-2-2
 * @version 1.0
 */
public class ShellSort implements SortUtil.Sort{

    /* (non-Javadoc)
     * @see org.rut.util.algorithm.SortUtil.Sort#sort(int[])
     */
    public void sort(int[] data) {
        for(int i=data.length/2;i>2;i/=2){
            for(int j=0;j<i;j++){
                insertSort(data,j,i);
            }
        }
        insertSort(data,0,1);
    }

    /**
     * @param data
     * @param j
     * @param i
     */
    private void insertSort(int[] data, int start, int inc) {
        int temp;
        for(int i=start+inc;i<data.length;i+=inc){
            for(int j=i;(j>=inc)&&(data[j]<data[j-inc]);j-=inc){
                SortUtil.swap(data,j,j-inc);
            }
        }
    }

}
 

Posted by micas on Jun 28th 2007 | Filed in Enabling-tech | Comments (0)

/* 冒泡排序算法 */

public class Test
{
    public static void main(String args[])
    {
        int[] m =
        { 2, 8, 43, 3, 33, 1, 35, 34, 6, 9 };
        int[] n = sort(m);
        for (int i = 0; i < m.length; i++)
        {
            System.out.println(n[i] + “\n”);
        }

    }

    /* 冒泡排序算法 */
    public static int[] sort(int[] m)
    {
        int intLenth = m.length;
        /*执行intLenth次*/
        for (int i = 0; i < intLenth; i++)
        {
            /*每执行一次,将最小的数排在后面*/
            for (int j = 0; j < intLenth - i - 1; j++)
            {
                int a = m[j];
                int b = m[j + 1];
                if (a < b)
                {
                    m[j] = b;
                    m[j + 1] = a;
                }
            }
        }
        return m;

    }
}

Posted by micas on Jun 28th 2007 | Filed in Enabling-tech | Comments (0)

J2EE项目危机

避免这10项J2EE危机来确保你的企业JAVA项目成功
摘要

在你着手企业级JAVA 项目开发时,你需要像耍杂技掌控手中的球一样来处理一些问题:与工具商之间的关系,漫长的工程——不论是设计还是开发,还是保持健壮性。每一项都会带来固有的危险,一些是明显的,然而另外一些却不是。但所有这些危机均可避免。本文作者分析了10项危机企业级JAVA项目的最大的危险,并大致指出了避免它们的办法。(4,500字——此处是指英文字数)

By Humphrey Sheil

作者:Humphrey Sheil
原文出处:http://java.sun.com/developer/technicalArticles/J2EE/projectdangers/
翻译:gooing 2005-01-18
http://blog.csdn.net/gooing/
感谢金山词霸和薛叉叉,请指正!
在我作为开发者、高级开发者、架构师的经历中,我遇到过好的、差的甚至是丑陋的企业级JAVA项目。当我问自己,是什么使一个项目成功而使另外的失败,我发现很难得到一个完美的答案,就好像很难用成功来定义所有的软件项目。J2EE项目也不例外。因此,项目被分为不同级别的成功或失败。在这篇文章里,我主要想为您——读者朋友——揭示影响企业级JAVA项目的最大的10项危险。

一些危险只是简单的延迟项目进度,一些却是错误的征兆,而还有一些使项目彻底没有成功的希望。尽管如此,如果具有良好的准备,征程开始前相关的知识和熟悉地形的向导,所有的都可避免。

这篇文章结构简单,我会按以下方式来揭示各种危机:

危机的名称
项目阶段(Project phase):危机所出现的项目阶段
所牵连的项目阶段(Project phase(s) affected):大多情况下,这些危机对随后的“项目阶段”有一种顺带(knock-on)的影响
解决:避免危机的方式以及如何最小化它们的影响
注释:有关该危机我想透露的观点,但不适合以前的分类
如上所注,我们将在企业级JAVA项目背景和它的各个重要阶段中检查每一项危险。这些项目阶段包括:

供应商选择:在你启动J2EE工程之前,挑选你的最佳工具组合的过程——不论是应用服务器还是咖啡品牌
设计:不论是严格的瀑布模型还是”code it and see”(试翻译为:编码和运行查看)方式,我对设计都有这样一个观点:我做了充分的设计,因此我可以轻松的进入开发阶段。当我确切知道我在建造什么和如何建造时,我认为我的设计阶段完成。另外,在进入开发阶段之前,我使用设计模板来保证我对我自己问了所有正确的问题并且有了建议的解决方法。然而,我在该阶段同样也不害怕写代码;有时,这是回答问题的唯一方式,执行和模块化( performance or modularity)。
开发:这个阶段早期有大量工作要做。选择好的工具加上一个良好的设计并不总是意味着开发阶段会非常顺利,但的确会很有用。
稳定性/负荷测试:在这个阶段,系统架构师和项目管理员将关注系统健壮性和构建质量,如确保系统的关键统计——并发用户数,失败的情境等。然而,直到这一阶段,代码质量和运行亦不应被忽略。事实上,你不能留一些差的或慢的代码到健壮性阶段来改。
存在阶段[live]:这并不是真正的项目阶段,it’s a date set in stone(想了半天也不知道怎么翻译:-{)这是关于准备的阶段,也是以前的错误的鬼怪出没的地方,不论是差的设计、开发还是错误的(开发工具)卖主的选择。

供应商选择:在你启动J2EE工程之前,挑选你的最佳工具组合的过程——不论是应用服务器还是咖啡品牌
设计:不论是严格的瀑布模型还是”code it and see”(试翻译为:编码和运行查看)方式,我对设计都有这样一个观点:我做了充分的设计,因此我可以轻松的进入开发阶段。当我确切知道我在建造什么和如何建造时,我认为我的设计阶段完成。另外,在进入开发阶段之前,我使用设计模板来保证我对我自己问了所有正确的问题并且有了建议的解决方法。然而,我在该阶段同样也不害怕写代码;有时,这是回答问题的唯一方式,执行和模块化( performance or modularity)。
开发:这个阶段早期有大量工作要做。选择好的工具加上一个良好的设计并不总是意味着开发阶段会非常顺利,但的确会很有用。
稳定性/负荷测试:在这个阶段,系统架构师和项目管理员将关注系统健壮性和构建质量,如确保系统的关键统计——并发用户数,失败的情境等。然而,直到这一阶段,代码质量和运行亦不应被忽略。事实上,你不能留一些差的或慢的代码到健壮性阶段来改。
存在阶段[live]:这并不是真正的项目阶段,it’s a date set in stone(想了半天也不知道怎么翻译:-{)这是关于准备的阶段,也是以前的错误的鬼怪出没的地方,不论是差的设计、开发还是错误的(开发工具)卖主的选择。

供应商选择:在你启动J2EE工程之前,挑选你的最佳工具组合的过程——不论是应用服务器还是咖啡品牌
设计:不论是严格的瀑布模型还是”code it and see”(试翻译为:编码和运行查看)方式,我对设计都有这样一个观点:我做了充分的设计,因此我可以轻松的进入开发阶段。当我确切知道我在建造什么和如何建造时,我认为我的设计阶段完成。另外,在进入开发阶段之前,我使用设计模板来保证我对我自己问了所有正确的问题并且有了建议的解决方法。然而,我在该阶段同样也不害怕写代码;有时,这是回答问题的唯一方式,执行和模块化( performance or modularity)。
开发:这个阶段早期有大量工作要做。选择好的工具加上一个良好的设计并不总是意味着开发阶段会非常顺利,但的确会很有用。
稳定性/负荷测试:在这个阶段,系统架构师和项目管理员将关注系统健壮性和构建质量,如确保系统的关键统计——并发用户数,失败的情境等。然而,直到这一阶段,代码质量和运行亦不应被忽略。事实上,你不能留一些差的或慢的代码到健壮性阶段来改。
存在阶段[live]:这并不是真正的项目阶段,it’s a date set in stone(想了半天也不知道怎么翻译:-{)这是关于准备的阶段,也是以前的错误的鬼怪出没的地方,不论是差的设计、开发还是错误的(开发工具)卖主的选择。

供应商选择:在你启动J2EE工程之前,挑选你的最佳工具组合的过程——不论是应用服务器还是咖啡品牌
设计:不论是严格的瀑布模型还是”code it and see”(试翻译为:编码和运行查看)方式,我对设计都有这样一个观点:我做了充分的设计,因此我可以轻松的进入开发阶段。当我确切知道我在建造什么和如何建造时,我认为我的设计阶段完成。另外,在进入开发阶段之前,我使用设计模板来保证我对我自己问了所有正确的问题并且有了建议的解决方法。然而,我在该阶段同样也不害怕写代码;有时,这是回答问题的唯一方式,执行和模块化( performance or modularity)。
开发:这个阶段早期有大量工作要做。选择好的工具加上一个良好的设计并不总是意味着开发阶段会非常顺利,但的确会很有用。
稳定性/负荷测试:在这个阶段,系统架构师和项目管理员将关注系统健壮性和构建质量,如确保系统的关键统计——并发用户数,失败的情境等。然而,直到这一阶段,代码质量和运行亦不应被忽略。事实上,你不能留一些差的或慢的代码到健壮性阶段来改。
存在阶段[live]:这并不是真正的项目阶段,it’s a date set in stone(想了半天也不知道怎么翻译:-{)这是关于准备的阶段,也是以前的错误的鬼怪出没的地方,不论是差的设计、开发还是错误的(开发工具)卖主的选择。
图1阐释了这些项目阶段,以及对其有影响的各种因素(尤其是那些“突然的[knock-on]”影响)

 
Figure 1. Enterprise Java project phases
and their most likely reasons for failure.
Click on thumbnail to view full-size
image. (60 KB)
 

危机1:没有理解Java,没有理解EJB,没有理解J2EE
好,现在我将其分解成3个小主题来进一步阐释。

描述:不理解Java

项目阶段:开发阶段

所牵连的项目阶段:设计,稳定阶段,存在阶段

受影响的系统特性:可维护性,可测量性(scalability),执行性

征兆:

重复实现已经包含于JDK核心APIs里的函数功能和类
 

不知道下面所列的任何一项或几项是什么和它们能做什么(下面列出了一些示例)
 

垃圾回收(train, generational, incremental, synchronous, asynchronous)
对象什么时候可以被“垃圾回收”——
Java里面继承特性的使用(及其权衡使用)
方法重载
为什么java.lang.String(此处替代你自己喜爱的类)似乎性能很差
忽略Java引用的语义(与忽略EJB中值的语义相对)
对非基本类型(nonprimitives)使用==而不是实现equals()方法
在不同平台上Java线程的进度如何(for example, pre-emptive or not)
绿色线程VS本地线程
热点[Hotspot](Hotspot <and why old performance tuning techniques negate Hotspot optimizations>)
JIT以及什么时候好的JITs变差(不安装的Java编译器并且你的代码依然运行良好等)
The Collections API
RMI
解决办法:

你需要提高你的Java知识,尤其是了解它的优势和弱点。Java的存在已经远远超除了一门语言本身,同样重要的是理解这平台(JDK and tools).具体的,你应当具有做一名Java 程序员的资格(如果你还没有的话)——你将对你有如此多不了解的东西感到吃惊。更进一步,将它作为你小组的一部分并向其他人推广,这种方式同样很有乐趣。更进一步,创建一份邮件列表,专心于Java技术并且保持下去。(我曾工作过的公司都有这些列表,大多数由于不更新而变的岌岌可危)向你的同伴学习——他们是你最好的资源。

注:

如果你或你团队中的其他成员不理解这门编程语言和这平台,你又怎么能期待建造一个成功的企业级Java应用呢?健壮的Java程序员对于EJB和J2EE如果鸭子对于水一般。与之相对,差的没有经验的程序员将建造一个质量差的J2EE应用。

 

描述:不理解EJB

项目阶段:设计

所牵涉项目阶段:开发,稳定性阶段

受影响的系统特性:可维护性

征兆:

EJBs在第一次被调用后就不再管了(尤其是处于就绪池[ready pool]的无状态SESSION BEANS)
非重用的(Nonreusable)EJBs
相比于容器提供的,开发者不知道可依赖什么
不符合规范的EJBs(fire threads,调用本地库,试图完成I/O操作等)
解决:

为提高你的EJB知识,花一个周末来阅读EJB规范(1.1规范有314页)。然后阅读2.0规范(524页)来了解为什么1.1规范不再适用和2.0规范能带给你什么。关注规范中那些能告诉你——应用开发者——什么是在EJB中合法的行为的部分。18.1和18.2节是开始的好地方。

注:

不要从你的提供商(指应用服务器或其他开发软件的提供商——译者)的眼里看EJB世界。确保你了解符合规范的EJB模型和特殊的实现之间的不同。这将保证在需要时你可以将你的技术带给你的提供商(或其他版本)。

描述:不理解J2EE    

项目阶段:设计

所牵涉项目阶段:开发

受影响的系统特性:可维护性,可度量性(scalability),执行性
征兆:

“什么都是EJB”的设计
手工配置而不是使用容器提供的机制
客户安全实现——J2EE平台或许是在企业计算中最完全和完整的安全架构,从表现一直到后台;它全部能力很少被全部使用的
解决:

学习J2EE关键组件以及每个组件所能带来的优势和劣势。依次涉及各项服务,此处知识和能力一样重要。

注:

只有知识能解决这些问题。好的Java 开发者造就好的EJB开发者——一步步地可以完美地成为J2EE领袖的人。你获得越多的Java/J2EE知识,你在设计和实现方面的能力越强.Things will start to slot into place for you at design time.(想了半天也不知道怎么翻译:-{ )
危机2:过度设计(无论是否是对于EJB)
项目阶段:设计

所涉及的项目阶段:开发

受影响的系统特性:可维护性,可测量性(scalability),可执行性
征兆:

特大型EJBs
开发者无法解释他们的EJBs做什么和它们之间的关系
不可重用的EJBs,组件,或服务——当它们应该重用时
当已经存在的事务可以完成任务时,EJBs 启动新的事务
数据独立性被设定的太高(为了安全的目的)
解决:
解决过度设计的方法可以直接从XP(extreme programming)中找到:局部范围内,设计和编码实现最小的暴露的[bare minimum]部分来满足需求,而不要做的过多。当你需要意识到将来的需求,比如平均负载需求和在系统负载顶峰时候的行为,不要试图“第二次猜测”[second-guess]系统将来需要成为的样子。另外,J2EE平台为你定义了特性如可测度性和服务器底层需要捕获的任务错误。

注:

除了上面的解决方式,使用设计模式——它们会显著的提高你的系统设计。EJB模型本身广泛地使用设计模式。如,每个EJB里的Home接口是一个寻找者和工厂模式的例子[Finder and Factory pattern].一个EJB的远程接口担当实际bean的实现的代理,也是容器截取调用和提供服务如透明化负载均衡的能力关键。忽略设计模式的价值是危险的。

我不断强调的另一种危险是:为使用EJB而使用。你的应用的一些部分在不适合被当作EJB模型时候而被设计为EJB模型,你的整个应用似乎使用EJBs将获得无限价值。这是极度的过分设计,我曾看到完美的servlet 和 JavaBean 应用在并没有好的技术方面的原因而使用EJBs时,变的乱七八糟,不得不重新设计。

危机3:未分离表示逻辑和商业逻辑

项目阶段:设计

所涉及的项目阶段:开发

所影响的系统性能:可维护性,可扩展性,可执行性

症状:

大型且笨拙的JSPs
当商业逻辑改变时,你发现你需要编辑JSP文件
显示需求的改变迫使你编辑和重新部署EJBs和后台组件
解决:

J2EE平台给你将表示逻辑同导航和控制分离并最终与商业逻辑分离的机会,这被称为Model2 结构(参见 Resources )。如果你已经掉进圈套,一种比较呆板的做法或许有用。你应该至少使 那些大部分自我包含的片断保持“垂直瘦小”[thin vertical slices](这是说,我如何布局的一个片断要同如何更改我的用户名和密码分开)。在你系统中使用这种方式来重新组织。

注:

在你的工程中使用一种连接UI框架(如标签库)坚固的设计将帮助你避免逻辑分离问题,不要为你自己需要的GUI框架设计而烦恼,这会为你带来诸多执行方面的好处。依次评估每一种框架,然后选择最适合你的那种。
危机4 :未在你开发的地方部署

项目阶段:开发

所影响的项目阶段:稳定阶段,并行阶段,存在阶段

所影响的系统特性:正常的心智(Your sanity)

征兆:

持续多日及1周的向真正应用系统的迁移
关于运行期的风险是固有的,伴随着诸多未测试的不清晰和主要的情节
在运行期系统上的数据和开发及稳定期间的数据不相同
在开发者机器上无法运行构建[builds]
应用的行为在开发环境、稳定性环境、产品环境不一致
解决:

危机4的解决办法是将你产品的环境如实地复制到你的开发环境。在你打算放置产品的确切的环境上开发——不要在Red Hat Linux 上用JDK1.3开发,然后却布置到 JDK 1.2.2 和 Solaris 7 上。进一步,不要在这个应用服务器上开发却部署到另外的服务器上。同时,得到你产品的数据库的数据的大致印象,并且在其上进行测试,不要依赖人工创造的数据。如果产品数据是敏感的[sensitive],减少其敏感性,装载它。意想不到的产品数据将打破:

数据有效性规则
已经测试的系统行为
系统组件间的契约(尤其是EJB-EJB和EJB-DB之间)
最坏的情况,每一项均会导致异常,空指针和你以前从未见过的行为。

注:
开发者经常到稳定阶段才想起安全性(“耶!屏幕正常,让我们把用户加为确认的员工”)。花费同样的时间来避免这种圈套实现安全性,就像你分离商业逻辑时候做的那样。

实施是一个复杂的过程,充满政治问题和技术问题。你将会碰到你不期望的问题;这就是实施的全部。开发环境和稳定性环境给你在实施前犯错误和找到问题的空间,利用这点,将减少应用实施过程中你的痛苦和风险。

你经历的项目越多,你就越容易知道什么能运行什么不能,为你和你的同伴保留一本项目记事本。在实施过程,你的目标应该是同样的错误不犯两次。

 

危机5:选择错误的(开发工具)提供商

项目阶段:提供商选择

所牵涉的项目阶段:设计,开发,稳定性/负载测试,实施

所影响的系统特性:可测量性,执行性,可维护性,稳定性

征兆:

开发人员花费较长的时间和工具“较劲”[wrestling],而不是有效的使用它们
在执行过程中,重要的系统需要重新设计来避开知道和不知道的bugs
不同工具间差的整合性乃至丝毫不能整合(应用服务器和IDE,IDE和调试工具,源代码控制和构造工具,等等等等)
对于IDE,调试器等,开发者简单的以个人的喜好来选择或放弃
解决:
为了避免危机5,你需要一个好的供应商选择过程。危机10在这里是适用的。

对于IDEs,唯一的评价方法是去使用它。评价J2EE的唯一的方式是构建一个你的观念构架中用到的特性的实现。事实上,当你花费3个月开发和投资到一项特殊的培训的时候,你不会希望在这些工具之间出现BUG.

那么,当你开发的半路上遇到关于工具集的麻烦的时候怎么办?一些工具似乎比其他的更加重要。如果你选择的应用服务器不适合你的需求,你要接受它并改变规范。如果IDE令人恶心,就设置最小级别的代码规范(tabs对空格等等),并让开发者寻找能最大限度提高生产效率的配置。

注:

了解最好的供应商和工具作为一项特殊的任务并非是一个“只做一次”的工作。你需要不断对市场评估。例如,过去的12个月,我曾用过4个不同的IDE,这取决于我的应用服务器平台,而不是我是否写EJB代码。

危机6:不了解你的供应商

项目阶段:供应商选择

所涉及的项目阶段:供应商选择之后的所有阶段

受影响的系统特性:可维护性,可测量性,执行性

征兆:
开发时间比最坏的估计时间长33%
当供应商或实现提供的功能超出“圈子”[作者使用了 box,不懂——译者注]时,开发者重新发明轮子。[Developers reinvent the wheel when the vendor or implementation provides the required functionality out of the box]
解决:

为避免由于不了解供应商而产生的问题,去订阅所有的供应商所能提供的资源,如邮件列表,新闻组,和发行注释(尤其是那些修订BUGS的列表);你将得到无可估量的信息。

一旦你选定了供应商就要马上投资于培训,然后,建立一个快速的概念的实现来打破这个它。[Once you’ve picked your vendors, invest in training as soon as possible, ideally well before the project kicks off. Next, build a quick proof of concept to break the team in gently.原文如此,译的郁闷:-{] 建立两个Ejbs并部署它们,然后通过你的显示层技术(Swing GUI,Jsps 等)调用它们。如果你试着构造你的开发环境同时试着满足一个项目目标,环境的设置将不尽人意。事实上,我曾经看到过没有经过部署过程的项目,原因是“我们没有时间”。当团队不得不每天晚上干到11点仅仅是为了获得一个发布的应用的时候,此处的意义就显得尤为重要。因此,事先花费一些时间将这些细节处理好,在以后的路上你将节约大量时间。对那些说“我们的计划没有给我们这么多的时间”的人,我要说,“你的计划没有给你不做它的时间。”

注: 

在J2EE世界中,工具提供商的技术的可转换性[transferable]如何呢?让我们看一看两个供应商的具体例子——IBM和BEA系统公司——支持EJB1.1的不同的应用服务器。确实,BEA WebLogic 5.1 和 IBM WebSphere 3.5 有多大程度的相似呢?

BEA WebLogic 的配置管理风格与IBM WebSphere 非常不同。
IBM对于WEBSPHERE采用了全GUI环境,与此对应,BEA 对于WebLogic提供了全命令行的控制工具。
IBM WebSphere 对于程序员采用了IIOP 来通讯和抛出CORBA 可见的异常,weblogic根本没有CORBA 层,默认采用t3协议。
这里只是几个不同之处,还有许多。概要:多数的供应商之间的相似就像粉笔和奶油之相似一样。在一种应用服务器上成为一名专家并不意味着你在所有的服务器上都是专家。上面的讨论适合于任何东西:IDEs,调试器,编译工具,配置管理等等。对于一种特殊工具拥有使用经验对于评价其竞争对手是一件好事情。但这并不意味着你可以从一种工具平滑的过度到另一种。尽量给你自己时间来熟悉你的工具。

 

危机7:没有为可测量性或可执行性设计

项目阶段:设计

所涉及的项目阶段:开发,测试,生存期

受影响的系统特性:可测量性,可执行性,可维护性

征兆:

系统慢的不可接受
过度利用服务端状态的系统及不能充分利用供应商集群技术
解决:

对于危机7,在分析阶段你要明确的知道系统的执行性能和测量性能——在进入开发之前就要知道你需要得到的数字。如果你知道你需要每秒处理50个交易,但所有的实体Bean的设计只能提供40个交易/秒,那么你需要为你的系统寻找替代方式,比如存储过程,批处理或重写的OLTP 方面[reworked OLTP aspects ].

尽量求助于你的工具供应商——他们应该知道他们产品的优缺点,并因此而帮助你。

注:

没有为可测量性或可执行性设计经常和危机2(过度设计)相抵触。事实上,它们相互取长补短。对于危机2我的解决方式是只有绝对需要的时候才进行部署。对于确定可测量性和可执行性,你可以在需要的时候设置可能的最大值。

如果你确定大量的测度是一个必需的需求,你可以指定一个支持最大聚合的应用服务器,可能的话,为你的执行提供一个交易缓存。进一步,你可以设计商业对象如Ejbs来最大程度的利用服务器的架构。XP没有这样的问题,你仍然可以在必须的时候再部署.

我回顾这种方式,思考提供这种平衡的方式。当我想一个最简单的系统时,那个系统需要提供客户要求的功能和行为。

 

危机8:陈旧的开发过程

项目阶段:开发

所涉及的项目阶段:稳定性,生存期

受影响的系统特性:可维护性和编码质量

征兆:

一个项目计划像可疑的瀑布模型:“首先,我们进行整体设计,然后,我们坐下花大量时间来编码。”
由于部署过程不存在,部署便成了一个噩梦。
部署的天数等于所花费的开发天数,因为什么都没完成。
在整合时组件未经过充分测试。实际上,整体测试意味着将两个不稳定的组件的绑到一起,然后看它们的堆栈。
解决:
一个好的软件设计方法将拯救你的生命。我经常提到XP;下面的资源包含一个这样的链接(Resources)。你将发现XP覆盖了很大的细节。

注:
我并没有 没经过Junit单元测试和没有用Ant部署的经历——那是两个可以加强XP方法的免费工具。参见: Resources.

危机9:使用框架失败
项目阶段:开发

所涉及的项目阶段:开发过程,稳定性能,生存期

受影响的系统特性:可维护性,可扩展性和编码质量

征兆:

核心库中的Bug在代码里重复使用
没有设定日志标准——因此系统的输出不可读或不能转换成scripts
差的或不协调的异常处理。在一些站点上我看到,终端用户在一些低级错误上被暴露,例如,当用户试图为购物车结帐的时候出现SQLException的堆栈追踪。用户接下来做什么呢?打电话给数据库管理员并强制报告这个错误吗?
下面的任务需要开发者在大量的情况下处理,并且,应该作为使用框架的首要任务:

记录日志
异常处理
获取相关资源的链接(数据库,名字服务等)
建立JSP页面
数据有效性验证
解决:

我对在重型应用中使用轻量级框架坚信不移。事实上,我在JavaWorld的第一篇文章”Frameworks Save the Day” 讨论过在企业开发环境中使用框架的问题。如果你现在已经在开发,马上采用框架仍然将获得重大收益。你将经历重新工作的痛苦,像日志及异常捕获,但就长远来看,你会节约大量时间和金钱。

注:
当你采用框架和面向组件编程时候,考虑不同级别的重用。在第一层,重塑(plumbing),使用0.9或更高的重用因子(reuse factor),这意味着90%的工程将用到它。越是特殊的服务,其重用因子越低。是说,我可能建立一个帐号服务来管理资源使用,希望50%的工程用到它。但对于那些需要它的工程——那些搞开发的男孩将很高兴它在那里!

危机10:将工程计划和设计基于市场广告,而不是技术现实

注:

危机10并未出现在我的列表中,直到我认识到有许多的人而不仅仅是我一个存在对企业java的误解,尤其是那些新鲜的领域。

项目阶段:
所有的项目阶段,尤其是供应商的选择更明显。

所影响的项目阶段:
所有阶段

所影响的项目特性:
可维护性,可扩展性,设计质量,代码质量

征兆:

技术方面的决策占很轻的分量,因为EJB被设计的轻便
供应商选择对于产品未经过是否轻便的试验
在项目生存期需要选择工具
解决:
不要相信在你项目之外的任何既得利益者。这是说:不要相信供应商(除非你已经了解他们了),不要相信供应商提供的白纸。如果你想要一些真实的应用服务器的建议,查询以前的链接:Resources。进一步,下载你想评测的工具,挽起袖子,设计原型。通过提供的例子来运行(任何好的提供商都有例子)。

总之,选择正确的供应商和工具集需要花费时间,尽管你的时间可能并不充裕。将你的选择集中到3个-4个,然后每个都试一下。花费一周的时间来验证你的应用服务器,IDE,部署过程等等,直到用这些工具可以满足你的开发计划时。

注:
如果你对J2EE不熟悉,在项目开始阶段你将很受打击。一开始所做的决定将对整个项目的成功有巨大的影响。一个好的J2EE顾问可能要进行一个重大的供应商选择过程并很好地将你带入设计和开发状态。

只有这10项危机?

10只是一个武断的数字,只是作为一个断点——还有数不清的其他危机存在。确实,我自己仍知道比这多一倍的危机。即使这样,如果你防备了这里所列出的,我保证你的工程可以完美和成功。

如果只从这篇文章中吸取一样东西,我的建议是:没有什么可以替代经验和计划的[There is no substitute for experience and planning]。如果你没有经验,那么你去试,然后得到它。在工程过程中,不要将赌注押到工程开始时候你以及你团队的培训上。开发前就进行一些编码,更好的是在设计之前就做编码。把你的Java和J2EE团队交给经验丰富的人来带以确保整个工程的方向和你团队中那些经验少的成员可以沿着这条路成长起来。

最后,我写的越多,我越清楚我想说的:

软件工程的社会层面
单元测试和整体测试(什么时候测试完成?)
设计模式
异常捕获
唉,我没有那么多的空间,下一篇文章将很快出来。不论如何,祝好运!

结论

好吧,就这么多。上面的互相影响的10项危机,是你在企业Java开发中将要面对或已经面对的大多数(如果不是全部的话)问题的原因。自然的,在你的旅途中还会遇到许多问题,但我相信,我已经揭示了最主要的原因。做个回顾,下面就是按重要程度划分的这10项危机:

没有理解Java,没有理解EJB,没有理解J2EE
过度设计(无论是否是对于EJB)
未分离表示逻辑和商业逻辑
未在你开发的地方部署
选择错误的(开发工具)提供商
不了解你的供应商
没有为可测量性或可执行性设计
陈旧的开发过程
使用框架失败
将工程计划和设计基于市场广告,而不是技术现实

Posted by micas on Jun 28th 2007 | Filed in J2EE | Comments (0)

JDBC的使用部分总结

一.批处理:

1.批处理时即可以用statement ,也可以用preparedstatement,一般可用后者。
  用后者的特点:
   PreparedStatement  ps = con.prepareStatement(sqlURL+”?,?,?,?,null)”);
    ps.addBatch(sqlURL);
      ps.addBatch(sqlURL2);
      ps.addBatch(sqlURL3)
   ps.execute()//是用来执行初始化语句
   ps.executeBatch()//是用来执行ps.addBatch中的语句。
   对于statement也用此特点。但.createStatement不能初始化.但可用stet.updateExecuate(sql) .
2.批处理有一个完整的sql操作过程的需要。它可以决定操作的回不回退,来确定操作的特征:
    使用批处理是要考虑到异常的后果,是否已经到达操作的目的。
3.二个表没办法通过sql语句合并,只是select 和 jion能获取一个二个表的结果集合而已。
   唯一的办法:一个个的读取,一个个的insert。
4.批处理中不能有b/lob类型进行preparedStatement.setC/Blob()。

二.SQL语句:

1.对于update,insert等都可以用?表示当时未用,然后对其进行setxxx(”")即补上.
2.对于integer类型的字段可以采用自动增长的方式:*声明标的方式如下:
  createURL=CREATE TABLE netPage( orderList INT AUTO_INCREMENT, url VARCHAR(200), title VARCHAR(50),    createTime DATE, file TEXT,PRIMARY key(orderList), KEY(url) )
   注当设定二个KEY值时,数据库先检验第一个key,如果没有相同的就不检验第二个,如果有才检验。只有当某行的二个key都一样时才报错。
3.当要对表进行清空要用TRUNCATE TABLE netpagebak,如果用delete *的话,就会当表为空时,回报错 。
4.DELETE netPageBak.* FROM netPageBak,netPage WHERE  netPageBak.url=netPage.url 的意思是:
  从netPageBak中删除含有与netpage中url相同的url行。
5.在用到数据库的字段是要回避含有:的string作为某一个字段的值。会出异常的(sql语法不对)。
6.使用RowSet.getString(int),该int从1开始对应相关的列字段。

三.数据类型:

1.在用到where语句的条件是:=null;将会被认为没有条件一样,即使对应的确实有字段的值为null.一搬在该字段为null时,可用该字段的默认值,或空值。
2。可用limit语句对检索的行数结果限制。例:
  SELECT * FROM netPage WHERE createTime=”" LIMIT 10
  注:LIMIT 接受一个或两个数字参数。参数必须是一个整数常量。如果给定两个参数,第一个参数指定第一个返回记录行的偏移量(从第几行开始)(可选),第二个参数指定返回记录行的最大数目。这是mysql的使用方法,其他数据库有类似的操作。

四.异常:

1。在设计方法来共享同一个connection 时,要注意有关异常产生的情况,可能导致connection没有及时关闭,因此要在每一个异常出现时设置关闭connection
2.java.sql.SQLException: Unable to connect to any hosts due to exception: java.net.ConnectException: Connection refused: connect
at com.mysql.jdbc.Connection.createNewIO(Connection.java:1797)
at com.mysql.jdbc.Connection.<init>(Connection.java:562)
其异常是由于数据库的连接出问题了。

五.数据库大对象:

一.当有大对象的使用:
  1.COLB是代表大的数据(字符型) Blob代表大的二进制数据类型 对于这些大对象而言在初始的时候要付null值否则会出错。
  2.在用到sql语句的时候一定要保证语句的完整性。:
    1)用逗号表示字段之间的间隔。
    2)对于含values的语句注意括符的匹配。
    3)当用字符串表示sql语句是要注意”号来表示字符串。
     例:sqlURL=sqlURL+num+”,’”+hsStr+”‘,’”+title+”‘,’”+date.toString()+”‘,”+null+”);”;
     注:sql结尾可无;
  3.一般不采用blob,clob,而采用long,long raw的原因是:需要平台的支持。  

Posted by micas on Jun 28th 2007 | Filed in SQL | Comments (0)

« Prev - Next »