<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    當(dāng)柳上原的風(fēng)吹向天際的時(shí)候...

    真正的快樂來源于創(chuàng)造

      BlogJava :: 首頁 :: 聯(lián)系 :: 聚合  :: 管理
      368 Posts :: 1 Stories :: 201 Comments :: 0 Trackbacks
    一.C/S兩端的任務(wù)分離
       考慮到便于信息接收傳遞顯示的因素,交易系統(tǒng)和QQ類似,采用了傳統(tǒng)的C/S模式而不是B/S模式。Client端主要負(fù)責(zé)取得用戶輸入和數(shù)據(jù)顯示,而Server端分為DBServer和MsgServer兩個(gè),前者負(fù)責(zé)數(shù)據(jù)的持久化,后者負(fù)責(zé)消息的傳遞。撇開消息服務(wù)器MsgServer不談的話,數(shù)據(jù)傳遞主要發(fā)生在Client和DBServer之間。
       
    二.C/S兩端的交互方式
       由于C端只負(fù)責(zé)數(shù)據(jù)的輸入和顯示,它必然需要向DBServer端存取數(shù)據(jù),這就有一個(gè)信息載體和交互方式的問題。C端需要向DbServer(以下簡稱DS)傳遞的信息是多種多樣的,簡單命令行形式的數(shù)據(jù)肯定不行,類似JSON的線性形式不夠表現(xiàn)樹狀數(shù)據(jù),只有XML才有豐富的表現(xiàn)能力,它無論是簡單的線性數(shù)據(jù)還是復(fù)雜的樹狀數(shù)據(jù)都能容納,有了dom4j或是jdom的幫助,解析起來也很方便。交互方式上,由于C可能在廣域網(wǎng)中,還可能有防火墻的阻擋,這樣Socket長連接就受到一定程度的限制,要是采用WebService問題就解決了,因?yàn)閃ebService的底層協(xié)議還是http,也走80端口,不會(huì)被防火墻阻擋,這樣,DBServer就成了一臺(tái)放置在公網(wǎng)上的WebService服務(wù)器,為各個(gè)Client提供Webservice服務(wù)。

    三.實(shí)現(xiàn)WebService的軟件選擇
       備選有Axis1/2和XFire兩種方案,選擇的依據(jù)主要是效率。通過一段時(shí)間的使用,發(fā)現(xiàn)XFire的效率確實(shí)比Axis1/2高,估測(cè)同等調(diào)用只占后者的一半左右。其它的易用性,穩(wěn)定性等沒有成為選擇依據(jù),因?yàn)槿绻鸛Fire還不行再換其它的軟件也來得及,下面的設(shè)計(jì)保證了系統(tǒng)不會(huì)依賴于特定的WebService端軟件。

    四.WebSevice端的對(duì)外接口設(shè)計(jì)

    WebService的對(duì)外端口一般是由一個(gè)接口和一個(gè)實(shí)現(xiàn)類組成,實(shí)現(xiàn)類中的函數(shù)是具體實(shí)現(xiàn),接口是調(diào)用者和實(shí)現(xiàn)者共同遵守的規(guī)約;一般來說如果客戶端需要一個(gè)函數(shù)的話,那么服務(wù)器端的接口類要定義這個(gè)函數(shù),實(shí)現(xiàn)類實(shí)現(xiàn)這個(gè)函數(shù)。這樣的方式在交互簡單,數(shù)據(jù)量小的時(shí)侯沒有問題,且使用很方便,但量變引起質(zhì)變,如果交互復(fù)雜,需要的函數(shù)眾多,數(shù)據(jù)量與日俱增的話,問題就來了。其一,這回導(dǎo)致接口類和實(shí)現(xiàn)類函數(shù)越來越多,體積越來越大,對(duì)定位維護(hù)修改帶來很大的不變;其二,接口類和實(shí)現(xiàn)類常會(huì)被修改,而開發(fā)人員之間的協(xié)同等待甚至沖突就日益增多起來,阻滯了開發(fā)效率;其三,也是最重要的,系統(tǒng)的可擴(kuò)展性缺乏,難以動(dòng)態(tài)維護(hù),即使增加多個(gè)服務(wù)器分擔(dān)負(fù)載,也需要手動(dòng)修改大量的代碼。因此,這種傳統(tǒng)的方式在Demo版過后就被放棄了。
    新的方式采用的單接口設(shè)計(jì),即接口類中只定義一個(gè)函數(shù),實(shí)現(xiàn)類實(shí)現(xiàn)這一個(gè)函數(shù),其內(nèi)部采用反射的方式具體調(diào)用在Spring上下文中定義好的Service類來取得結(jié)果,輸入的參數(shù)和返回值都是String,其實(shí)質(zhì)是XML形式的字符串。這樣做的好處是:其一,接口類和實(shí)現(xiàn)類從設(shè)計(jì)開始代碼就處于穩(wěn)定狀態(tài),以后極少維護(hù),不會(huì)越來越大;其二,自然消除了多個(gè)開發(fā)人員需要修改同一文件的沖突問題;其三,如果服務(wù)器負(fù)載過重,可以在實(shí)現(xiàn)類中根據(jù)輸入?yún)?shù)的內(nèi)容做一個(gè)分流,把一些任務(wù)分配到其它服務(wù)器上去,甚至可以采用前端一個(gè)分流服務(wù)器,后面一堆負(fù)責(zé)具體業(yè)務(wù)的服務(wù)器的形式。由于只有一個(gè)函數(shù),這樣修改起來也容易得多。事實(shí)上,采用了這種方式后,完成各個(gè)流程的程序員只負(fù)責(zé)前端表現(xiàn)輸入,后端的Service類等三個(gè)位置的代碼,相互間處于平行狀態(tài),基本沒有交叉,減少了沖突,提高了開發(fā)效率。下面是實(shí)現(xiàn)類的具體代碼。

    五.WebService端實(shí)現(xiàn)類的具體代碼
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;

    import org.apache.log4j.Logger;
    import org.dom4j.DocumentException;
    import org.springframework.beans.factory.NoSuchBeanDefinitionException;

    /**
     * 此類中共有方法為WebService對(duì)外方法,其它方法為輔助此方法而使用
     *
     * 創(chuàng)建日期:2010-2-9 上午09:19:31
     * 修改時(shí)間:2010-2-9 上午09:19:31
     
    */
    public class ServiceImpl implements IService{
        
    // 日志記錄器
        private    static Logger logger = Logger.getLogger(ServiceImpl.class);
        
        
    /**
         * 此函數(shù)將逐步進(jìn)行以下任務(wù)
         * 1.在log文件中記錄請(qǐng)求的XML文本
         * 2.解析文本,得到要訪問的類名,方法名,參數(shù)
         * 3.使用反射調(diào)用類的方法
         * 4.返回結(jié)果
         * 
    @throws InstantiationException
         
    */
        
    public String getResponseXML(String requestXML){
            logger.info(
    "接收到客戶端的請(qǐng)求XML文本:"+requestXML);
            
    // 新建一個(gè)包裝器
            ResponseXMLPackager packager=new ResponseXMLPackager();
            
            
    try {
                
    // 使用解析器解析請(qǐng)求XML文本
                RequestXMLParser parser=new RequestXMLParser(requestXML);
                
                
    // 從解析器中獲取Service服務(wù)類
                packager.setServiceName(parser.getServiceName());
                
                
    // 從解析器中獲取方法名
                packager.setMethodName(parser.getMethodName());
                
                
    // 從解析器中獲取方法參數(shù)
                packager.setArgs(parser.getArgs());
                
                
    // 通過Spring得到實(shí)例
                Object obj=SpringUtil.getBean(packager.getServiceName());
                logger.info(
    "在Spring上下文配置文件中找到了'"+packager.getMethodName()+"'對(duì)應(yīng)的bean.");
                
                
    // 得到實(shí)例對(duì)應(yīng)的類
                Class<?> cls=obj.getClass();
                
                
    // 通過反射得到方法
                Method method = cls.getMethod(packager.getMethodName(), new Class[] {String[].class});
                logger.info(
    "通過反射獲得了'"+packager.getMethodName()+"'對(duì)應(yīng)的方法.");
                
                
    // 通過反射調(diào)用對(duì)象的方法
                String methodResonseXML=(String)method.invoke(obj,new Object[] {packager.getArgs()});
                logger.info(
    "通過反射調(diào)用方法'"+packager.getMethodName()+"'成功.");
                
                
    /**************************
                 * 設(shè)置狀態(tài),備注及方法反饋結(jié)果
                 *************************
    */
                String remark
    ="成功執(zhí)行類'"+packager.getServiceName()+"'的方法'"+packager.getMethodName()+"'";
                packager.setStatus(ResponseXMLPackager.Status_Success);
                packager.setRemark(remark);
                packager.setMethodResonseXML(methodResonseXML);     
                
                logger.info(remark);
            }
    catch (DocumentException e) {
                
    // 解析不了從客戶端傳過來的XML文本時(shí)
                
                String remark
    ="無法解析客戶端的請(qǐng)求XML文本:"+requestXML+".";
                
                packager.setRemark(remark);
                packager.setStatus(ResponseXMLPackager.Status_CanNotParseRequestXML);
                
                logger.error(remark);
            }
    catch (NoSuchBeanDefinitionException e) {
                
    // Spring找不到bean時(shí)            
                String remark="無法在Spring上下文定義文件appCtx.xml中找到id'"+packager.getServiceName()+"'對(duì)應(yīng)的bean.";    
                            
                packager.setRemark(remark);
                packager.setStatus(ResponseXMLPackager.Status_CanNotFoundServiceName);
                
                logger.error(remark);
            }        
            
    catch (NoSuchMethodException e) {
                
    // 找不到方法時(shí)
                
                String remark
    =("類'"+packager.getServiceName()+"'中沒有名為 ‘"+packager.getMethodName()+"’的方法,或是此方法非公有函數(shù),或是參數(shù)不是字符串?dāng)?shù)組形式.");            
                
                packager.setRemark(remark);
                packager.setStatus(ResponseXMLPackager.Status_NotFoundSuchMethod);
                
                logger.error(remark);
            }
    catch (IllegalAccessException e) {
                
    // 當(dāng)訪問權(quán)限不夠時(shí)
                
                String remark
    =("訪問類'"+packager.getServiceName()+"'中名為 ‘"+packager.getMethodName()+"’的方法非法,可能原因是當(dāng)前方法(getResponseXML)對(duì)該方法的訪問權(quán)限不夠.");            
                
                packager.setRemark(remark);
                packager.setStatus(ResponseXMLPackager.Status_CanNotAccessMethod);
                
                logger.error(remark);
            }
    catch (InvocationTargetException e) {
                
    // 當(dāng)調(diào)用的函數(shù)拋出異常時(shí)
                
                Exception tragetException
    =(Exception)e.getTargetException();
                
                
    if(tragetException instanceof BreakException){
                    
    // 程序中斷,不能繼續(xù)進(jìn)行的情況.比如說用戶沒有操作權(quán)限,要找的目標(biāo)不存在等.
                    packager.setRemark(tragetException.getMessage());
                    packager.setStatus(ResponseXMLPackager.Status_Ng);
                    
                    String remark
    =("執(zhí)行類'"+packager.getServiceName()+"'中名為 ‘"+packager.getMethodName()+"’的方法時(shí)被中斷,原因是:"+tragetException.getMessage()+".");    
                    logger.warn(remark);
                }
                
    else{        
                    
    // 程序運(yùn)行過程中拋出異常,如空指針異常,除零異常,主鍵約束異常等.
                    String remark=("執(zhí)行類'"+packager.getServiceName()+"'中名為 ‘"+packager.getMethodName()+"’的方法時(shí),該方法拋出了異常,異常類型為:"+tragetException.getClass().getName()+",異常信息是"+tragetException.getMessage()+".");            
                    
                    packager.setRemark(remark);
                    packager.setStatus(ResponseXMLPackager.Status_MethodThrowException);
                    
                    logger.error(remark);
                }
            }
                    
            
    // 向客戶端返回響應(yīng)XML文本
            return packager.toXML();
        }
    }


    六.Service類中函數(shù)的輸入和輸出
       從上面的代碼可見,客戶端傳過來是一個(gè)XML形式的文本,RequestXMLParser類負(fù)責(zé)從這段文本中解析出具體想調(diào)用的配置在Spring上下文中Service類的beanName,類中的具體函數(shù)名和函數(shù)的參數(shù),然后再用反射的方式調(diào)用之。為了調(diào)用方便,讓每個(gè)Service類的具體參數(shù)都是String[] 形式的(現(xiàn)在看如果采用類似JSON的形式更好一點(diǎn)),在內(nèi)部再獲得其實(shí)際數(shù)據(jù),這樣,來自客戶端的調(diào)用就能順利的到達(dá)目的函數(shù)中。函數(shù)運(yùn)行完畢后,傳出的也是一個(gè)XML形式的字符串,這是為了返回?cái)?shù)據(jù)的方便,到了客戶端后,再進(jìn)行解析變成領(lǐng)域?qū)ο箢愂纠O旅娲a是一個(gè)Service類中函數(shù)的例子:
    /**
     * 添加一個(gè)Tmp對(duì)象到數(shù)據(jù)庫
     * 
    @param args
     * 
    @return
     * 
    @throws Exception
     
    */
    public String add(String[] args) throws Exception{
        String name
    =args[0];
        
        
    // 同名檢測(cè)
        if(hasSameName(name)){
            
    throw new BreakException("已經(jīng)有和"+name+"同名的對(duì)象存在了.");
        }
        
        
    int age=Integer.parseInt(args[1]);
        
    float salary=Float.parseFloat(args[2]);
        String picture
    =args[3];
        
        Tmp tmp
    =new Tmp(name,age,salary,picture);
        dao.create(tmp);
        
        
    return tmp.toXML();



    七.領(lǐng)域?qū)ο笈cXML之間的相互轉(zhuǎn)化

    由于DB服務(wù)器和Client之間傳遞的是XML形式的文本,但內(nèi)部使用的都是領(lǐng)域?qū)ο螅敲矗虚g需要兩次轉(zhuǎn)化過程。以取得一個(gè)Tmp對(duì)象為例,在服務(wù)器端,dao從數(shù)據(jù)庫取得記錄后會(huì)形成Tmp領(lǐng)域?qū)ο蟮膶?shí)例,這個(gè)實(shí)例會(huì)轉(zhuǎn)化成XML傳到客戶端;客戶端得到這段XML文本會(huì)把它還原成領(lǐng)域?qū)ο蟆R韵麓a闡述了這兩個(gè)過程:
    // 服務(wù)器端領(lǐng)域?qū)ο蟮幕悾膖oXML()函數(shù)使得實(shí)例轉(zhuǎn)化為XML,它的子類只要實(shí)現(xiàn)changePropertytoXML()這個(gè)抽象接口就能得到此項(xiàng)功能。
    public abstract class BaseDomainObj{
        
    // 領(lǐng)域?qū)ο蟮奈ㄒ蛔R(shí)別標(biāo)志
        protected long id;
        
        
    // 名稱
        protected String name;
        
        
    // 對(duì)象對(duì)應(yīng)的記錄被添加到數(shù)據(jù)庫的時(shí)間(入庫時(shí)間)
        protected String addTime;
        
        
    // 對(duì)象對(duì)應(yīng)的記錄最近被更新的時(shí)間(更新時(shí)間)
        protected String refreshTime;
        
        
    // 備注
        protected String remark;
        
        
    // 節(jié)點(diǎn)名
        protected String nodeName;
        
        
    // 記錄是否有效,若為false則說明無效,常改變此值來隱藏或是顯示一個(gè)對(duì)象
        protected boolean valid;
        
        
    /**
         * 無參構(gòu)造函數(shù)
         
    */
        
    public BaseDomainObj(){
            
    this(0);
        }
        
        
    /**
         * 指定id的構(gòu)造函數(shù)
         * 
    @param id
         
    */
        
    public BaseDomainObj(long id){
            
    this.id=id;
            String currTime
    =getCurrTime();
            addTime
    =currTime;
            refreshTime
    =currTime;
            valid
    =true;
            remark
    ="";
        }
        
        
    /**
         * 將對(duì)象轉(zhuǎn)化為XML形式
         * 
    @return
         
    */
        
    public String toXML() {
            StringBuilder sb
    =new StringBuilder();
            
            sb.append(
    "<"+nodeName+">");
            sb.append(
    "<id>"+id+"</id>");
            sb.append(
    "<name>"+name+"</name>");
            sb.append(
    "<addTime>"+addTime+"</addTime>");
            sb.append(
    "<refreshTime>"+refreshTime+"</refreshTime>");
            sb.append(
    "<remark>"+remark+"</remark>");
            sb.append(
    "<valid>"+valid+"</valid>");
            sb.append(changePropertytoXML());        
            sb.append(
    "</"+nodeName+">");
            
            
    return sb.toString();
        }
        
        
    /**
         * 將屬性轉(zhuǎn)化為XML,強(qiáng)制子類實(shí)現(xiàn)
         * 
    @return
         
    */
        
    protected abstract String changePropertytoXML();
        
        
    /**
         * 取得當(dāng)前時(shí)間
         
    */
        
    private static String getCurrTime() {
            Date date 
    = new Date();
            Format formatter 
    = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            
    return formatter.format(date);
        }

        
    /*************************
         * 以下為setter/getter
         ************************
    */
        
        ..
    }

    // 具體的Tmp對(duì)象,重點(diǎn)是changePropertytoXML()這個(gè)函數(shù)。
    public class Tmp extends BaseDomainObj{
        
    // 年齡
        private int age;
        
        
    // 薪水
        private float salary;
        
        
    /**
         * 無參構(gòu)造函數(shù)
         
    */
        
    public Tmp(){
            
    this("",0,0.0f);
        }
        
        
    /**
         * 三參數(shù)構(gòu)造函數(shù)
         * 
    @param name
         * 
    @param age
         * 
    @param salary
         
    */
        
    public Tmp(String name,int age,float salary){
            nodeName
    ="Tmp";
            
            
    this.name=name;
            
    this.age=age;
            
    this.salary=salary;
        }
        

        @Override
        
    protected String changePropertytoXML() {
            StringBuilder sb
    =new StringBuilder();
            
            sb.append(
    "<age>"+age+"</age>");
            sb.append(
    "<salary>"+salary+"</salary>");
            
            
    return sb.toString();
        }

        
    /***************************
         * 以下為setter/getter部分
         **************************
    */
        
        
    public int getAge() {
            
    return age;
        }


        
    public void setAge(int age) {
            
    this.age = age;
        }


        
    public float getSalary() {
            
    return salary;
        }


        
    public void setSalary(float salary) {
            
    this.salary = salary;
        }
    }

    這樣,在得到一個(gè)Tmp對(duì)象的實(shí)例后,調(diào)用其toXML函數(shù)就能得到這個(gè)實(shí)例的XML形式表現(xiàn)文本。“六”中的函數(shù)就是這樣做的。

    傳出的XML文本實(shí)例:
    <Tmp>
        
    <id>1</id>
        
    <name>0</name>
        
    <addTime>2010-02-15 23:39:06</addTime>
        
    <refreshTime>2010-02-15 23:39:06</refreshTime>
        
    <remark></remark>
        
    <valid>true</valid>
        
    <age>30</age>
        
    <salary>15000.0</salary>
    </Tmp>


    上面這段文本傳回到客戶端后怎么再把它變成實(shí)例呢,有了Apache的BeanUtils包任務(wù)就簡單多了。下面請(qǐng)看客戶端的Tmp類及其基類:
    // 客戶端Tmp類:
    public class Tmp extends BaseDomainObj{
        
        
    // 年齡
        private String age;
        
        
    // 薪水
        private String salary;
        
        
        @Override
        
    public Object[] toArray() {
            
    return new Object[]{id,name,age,salary,addTime,refreshTime,valid,remark};
        }


        
    public String getAge() {
            
    return age;
        }


        
    public void setAge(String age) {
            
    this.age = age;
        }


        
    public String getSalary() {
            
    return salary;
        }


        
    public void setSalary(String salary) {
            
    this.salary = salary;
        }
    }

    // Tmp類的基類:
    public abstract class BaseDomainObj{
        
    // 領(lǐng)域?qū)ο蟮奈ㄒ蛔R(shí)別標(biāo)志
        protected String id;
        
        
    // 名稱
        protected String name;
        
        
    // 對(duì)象對(duì)應(yīng)的記錄被添加到數(shù)據(jù)庫的時(shí)間(入庫時(shí)間)
        protected String addTime;
        
        
    // 對(duì)象對(duì)應(yīng)的記錄最近被更新的時(shí)間(更新時(shí)間)
        protected String refreshTime;
        
        
    // 備注
        protected String remark;
        
        
    // 記錄是否有效,若為false則不該進(jìn)入
        protected String valid;
        
        
    /**
         * ?無參構(gòu)造函數(shù)
         
    */
        
    public BaseDomainObj(){
            
        }
        
        
    /**
         * 有參構(gòu)造函數(shù),使用此函數(shù)傳入一個(gè)XML,得到相應(yīng)對(duì)象
         * 
    @param xml
         * 
    @throws DocumentException
         
    */
        
    public BaseDomainObj(String xml) throws DocumentException{
            fromXML(xml);
        }
        
        
    /**
         * 將對(duì)象轉(zhuǎn)化為數(shù)組形式,便于在表格中顯示
         * 
    @return
         
    */
        
    public abstract Object[] toArray();
        
        
    /**
         * 使用BeanUtils將XML的節(jié)點(diǎn)轉(zhuǎn)化到屬性中
         * 
    @param xml
         * 
    @throws DocumentException
         
    */
        @SuppressWarnings(
    "unchecked")
        
    public void fromXML(String xml) throws DocumentException{
            Document doc
    =DocumentHelper.parseText(xml);        
            
            Element root
    =doc.getRootElement();        
            List
    <Element> elms=root.elements();
            
            
    for(Element elm:elms){
                
    try {
                    BeanUtils.setProperty(
    this,elm.getName(),elm.getText());
                } 
    catch (IllegalAccessException e) {
                    e.printStackTrace();
                } 
    catch (InvocationTargetException e) {
                    e.printStackTrace();
                }
            }
        }

        
    public String getId() {
            
    return id;
        }

        
    public void setId(String id) {
            
    this.id = id;
        }

        
    public String getName() {
            
    return name;
        }

        
    public void setName(String name) {
            
    this.name = name;
        }

        
    public String getAddTime() {
            
    return addTime;
        }

        
    public void setAddTime(String addTime) {
            
    this.addTime = addTime;
        }

        
    public String getRefreshTime() {
            
    return refreshTime;
        }

        
    public void setRefreshTime(String refreshTime) {
            
    this.refreshTime = refreshTime;
        }

        
    public String getRemark() {
            
    return remark;
        }

        
    public void setRemark(String remark) {
            
    this.remark = remark;
        }

        
    public String getValid() {
            
    return valid;
        }

        
    public void setValid(String valid) {
            
    this.valid = valid;
        }
    }

       
    重要的是上面的黑體部分,只要我們保證XML的字段和Tmp對(duì)象中的字段是一一對(duì)應(yīng)的,fromXML函數(shù)就能保證完成XML到對(duì)象的轉(zhuǎn)換,對(duì)于負(fù)責(zé)具體業(yè)務(wù)的程序員,在代碼里如下做就可以了:
    String objXML=”;// 從WebService端取出的Tmp對(duì)象XML文本
    Tmp tmp=new Tmp(objXML);// 這樣,對(duì)象就出來了.
     

    小結(jié):
    一.框架設(shè)計(jì)者一定要定義好框架的任務(wù),限制具體程序員的行為,否則項(xiàng)目的可讀性可維護(hù)性就是一句空話。
    二.框架一定要完成主干的任務(wù)的流程,而具體程序員只負(fù)責(zé)枝節(jié),換言之,具體程序員只該負(fù)責(zé)簡單的規(guī)定好了的任務(wù),如某函數(shù)的具體實(shí)現(xiàn)。
    三.好的框架完成后,其他人應(yīng)該能像填空一樣完成任務(wù),要讓他們?cè)谕瓿扇蝿?wù)時(shí)不需要思考具體的來龍去脈。
    四.好的框架能讓完成任務(wù)的程序員盡量平行,減少相互間的交流成本。實(shí)際上,框架和工廠流水線的設(shè)計(jì)某種程度上是相通的。
    五.隨著數(shù)據(jù)量和規(guī)模的增大,一些問題會(huì)逐漸顯山露水,這就需要框架設(shè)計(jì)者有前瞻性的眼光。
    六.如果框架已經(jīng)不能滿足需求,帶來很多問題時(shí),設(shè)計(jì)者需要有把前設(shè)計(jì)推到重來重新組建新框架的勇氣和毅力,當(dāng)斷不斷,修修補(bǔ)補(bǔ),蹣跚前行,反受其害。
    posted on 2010-05-19 14:22 何楊 閱讀(1903) 評(píng)論(0)  編輯  收藏

    只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 国产精品综合专区中文字幕免费播放 | 青青青免费国产在线视频小草| 最近2019中文字幕免费直播| 成年人免费的视频| 国产精品嫩草影院免费| 国产成人亚洲综合无码| 亚洲精品~无码抽插| 1区1区3区4区产品亚洲| 美女视频黄免费亚洲| 四虎一区二区成人免费影院网址| a毛片免费播放全部完整| 麻豆国产精品免费视频| 中文字幕亚洲情99在线| 国产成人亚洲综合无| a级大片免费观看| 7723日本高清完整版免费| 免费永久国产在线视频| 亚洲精品二区国产综合野狼| 亚洲一区二区影视| 高潮毛片无遮挡高清免费| 99精品免费观看| 搡女人免费视频大全| 亚洲中文久久精品无码| 亚洲午夜久久久精品电影院| 亚洲av色福利天堂| 99亚偷拍自图区亚洲| 精品国产呦系列在线观看免费 | 无码A级毛片免费视频内谢| 波霸在线精品视频免费观看| 1000部禁片黄的免费看| 日日夜夜精品免费视频| 亚洲va无码va在线va天堂| 亚洲AV无码一区二区三区牛牛| 久久国产乱子伦精品免费午夜| 91视频国产免费| 国产亚洲色婷婷久久99精品91| 日本亚洲精品色婷婷在线影院| 国产高潮流白浆喷水免费A片 | 国产三级在线观看免费| 亚洲精品乱码久久久久久按摩| 亚洲中文字幕无码爆乳app|