tbwshc

          #

          xml解析方式

          xml解析方式
          dom:(document objectb model),文檔對象模型,是w3c組織推薦的解析的xml的一種方式
          sax:(simple api for xml),不是官方標準,但是xml社區(qū)事實上的標準,幾乎所有的xml解析器都支持它

          xml解析開發(fā)包
          Jaxp(sun公司),dom4j,Jdom

          dom和sax解析的原理
                在dom中,解析文檔的結構類似為一棵樹,文檔、文檔中的根、元素、元素內容、屬性、屬性值等都是以對象模型的形式表示的。Dom能夠在內存中保存整個文檔的模型,可以方便對xml元素。
                當sax分析器對xml文檔進行分析時,觸發(fā)一系列事件,并激活相應的事件處理函數(shù),從上到下的順序讀取,讀取一行就處理一行。它不允許對xml文件隨機存取,沒有把xml文檔完全加載到內存,占用內存少。

          dom和sax解析方法的區(qū)別:
          1.dom解析的優(yōu)點是對文檔增刪改查比較方便,缺點占用內存比較大。
          2.sax解析的優(yōu)點占用內存少,解析速度快,缺點是只適合做文檔的讀取,不適合做文檔的增刪改查。

          posted @ 2012-07-27 14:57 chen11-1 閱讀(1103) | 評論 (0)編輯 收藏

          用 java實現(xiàn)定時重啟windows指定服務

          package com.test.processManagement;  

           

          import java.io.BufferedReader;  

          import java.io.FileNotFoundException;  

          import java.io.FileOutputStream;  

          import java.io.IOException;  

          import java.io.InputStream;  

          import java.io.InputStreamReader;  

          import java.io.PrintStream;  

          import java.text.ParseException;  

          import java.text.SimpleDateFormat;  

          import java.util.Date;  

          import java.util.Timer;  

          import java.util.TimerTask;  

           

          /**
          * <title>ServRebootScheWin</title>
          *  
          * <project>Exam</project>
          *  
          * <package>com.test.processManagement</package>
          *  
          * <file>ServRebootScheWin.java</file>
          *  
          * <date>2012-7-11</date>
          *  
          * <brief>本程序用于每天定時重啟windows系統(tǒng)上的指定服務,并記錄日志</brief>
          *  
          * @author Wero
          *  
          */


          public
          class ServRebootScheWin {  

           

          public
          static
          void main(String[] args) {  

          // store the console output


          final PrintStream console = System.out;  

          if (args.length < 2) {  
                      LOG("參數(shù)不全,程序將退出...");  
                      Runtime.getRuntime().exit(-1);  
                  }  

           

          final String timeStr = args[0];// 每tb天重啟時間(HH:mm:ss)


          final String servName = args[1];// 服務名


          if (args.length >= 3) {  

          try {  
                          System.setOut(new PrintStream(new FileOutputStream(args[2])));  
                      } catch (FileNotFoundException e) {  
                          System.setOut(console);  
                          LOG("日志文件無法建立...");  
                      }  
                  }  

           

          // convert time string to Date type

                  Date date = null;  

          try {  
                      date = new SimpleDateFormat("HH:mm:ss").parse(timeStr);  
                  } catch (ParseException e1) {  
                      LOG("日期格式(HH:mm:ss)錯誤,程序將退出...");  
                      Runtime.getRuntime().exit(-1);  
                  }  

           

          // schedule the specific windows service to reboot at specific time


          // every day

                  rebootEveryDayTime(date, servName);  

           

          // add shutdown hook to recover system.out to console when program exits

                  Runtime.getRuntime().addShutdownHook(new Thread() {  

          @Override


          public
          void run() {  
                          System.setOut(console);  
                      }  
                  });  
              }  

           

          private
          static
          void rebootEveryDayTime(Date date, final String servName) {  

          new Timer().schedule(new TimerTask() {  

          public
          void run() {  

          try {  
                              reboot(servName);  
                          } catch (Exception e) {  
                              LOG("重啟出現(xiàn)異常:" + e.getMessage());  
                          }  
                      }  
                  }, date, 24 * 60 * 60 * 1000);  
              }  

           

          private
          static
          void reboot(String servName) throws IOException, InterruptedException {  
                  LOG("重啟服務:" + servName);  
                  Process procStop;  
                  Process procStart;  

          int stopState = -1;  

          int startState = -1;  

           

          // stop the specific service

                  procStop = Runtime.getRuntime().exec("net stop \"" + servName + "\"");  


                  stopState = getProcExecStat(procStop);  
                  LOG(getProcOutput(procStop));  

           

          // wait for 10 seconds 


          try {  
                      Thread.sleep(10 * 1000);  
                  } catch (InterruptedException e) {  
                      LOG("線程等待時中斷...");  
                      e.printStackTrace();  
                  }  

           

          // restart

                  procStart=Runtime.getRuntime().exec("net start \"" + servName + "\"");  
                  startState = getProcExecStat(procStart);  
                  LOG(getProcOutput(procStart));  

           

          //if stop exec and start exec both return with failed flag,exists


          if (stopState != 0 && startState != 0) {  
                      LOG("重啟失敗,請確認服務名是否有效,程序將退出...");  
                  } else {  
                      LOG("重啟成功.");  
                  }  
              }  

           

          private
          static
          int getProcExecStat(Process proc) {  

          try {  

          return proc.waitFor();  
                  } catch (InterruptedException e) {  
                      LOG("線程等待時中斷...");  
                      e.printStackTrace();  
                  }  

          return -1;  
              }  

           

          private
          static String getProcOutput(Process proc) throws IOException, InterruptedException {  
                  InputStream is = proc.getInputStream();  
                  String line;  
                  StringBuffer strResult = new StringBuffer();  


                  BufferedReader reader = new BufferedReader(new InputStreamReader(is));  

          while ((line = reader.readLine()) != null) {  
                      strResult.append(line);  
                  }  
                  is.close();  

           

          return strResult.toString().trim();  
              }  

           

          private
          static
          void LOG(String info) {  

          if (info != null && !info.equals("")) {  
                      System.out.println("windows服務監(jiān)控器--------" + getCurrentTime() + "----------->" + info);  
                  }  
              }  

           

          private
          static String getCurrentTime() {  
                  SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");  

          return sdf.format(new Date());  
              }  

           

          // public enum ExecuteStates {


          //


          // SUCCEED(0, ""), STATERR_STOPPED(1, "服務已停止"), STATERR_STATED(3, "服務已開始"),


          // STATERR_NOTFOUND(


          // 2, "服務名無效");


          //


          // ExecuteStates(int code, String desc) {


          // this.code = code;


          // this.desc = desc;


          // }


          //


          // private final int code;


          // private final String desc;


          //


          // // regular get method


          // public String getDesc() {


          // return desc;


          // }


          //


          // public static String getDescByCode(int code){


          // for (ExecuteStates e:ExecuteStates.values()){


          // if(e.code==code){


          // return e.desc;


          // }


          // }


          // return null;


          // }


          // }

           


          posted @ 2012-07-25 15:30 chen11-1| 編輯 收藏

          文件FTP上傳支持斷點續(xù)傳demo

          package cn.eason.util.common;


          import java.io.File;
          import java.io.FileInputStream;
          import java.io.FileOutputStream;
          import java.io.IOException;
          import java.io.InputStream;
          import java.io.OutputStream;
          import java.io.PrintWriter;


          import org.apache.commons.net.PrintCommandListener;
          import org.apache.commons.net.ftp.FTP;
          import org.apache.commons.net.ftp.FTPClient;
          import org.apache.commons.net.ftp.FTPFile;
          import org.apache.commons.net.ftp.FTPReply;


          /**************************************************************
          * 文件名稱: ContinueFTP.java
          * 功能描述: ftp文件上傳功能,依賴commons-net-3.1.jar實現(xiàn)
          * 創(chuàng)建日期: 2012-5-21
          * 創(chuàng)建地址: 西安
          * 作者:  Eric.Hao
          **************************************************************/
          public class ContinueFTP {
                 
                  private FTPClient ftpClient = new FTPClient();
                 
                  public ContinueFTP(){
                         
                          //設置將過程中使用到的命令輸出到控制臺
                          this.ftpClient.addProtocolCommandListener(new PrintCommandListener(new PrintWriter(System.out)));
                  }


                  /**
               * java編程中用于連接到FTP服務器
               * @param hostname 主機名
               * @param port 端口
               * @param username 用戶名
               * @param password 密碼
               * @return 是否連接成功
               * @throws IOException
               */
                   public boolean connect(String hostname,int port,String username,String password)
                           throws IOException {
                           //連接到FTP服務器
                           ftpClient.connect(hostname, port);
                           //如果采用默認端口,可以使用ftp.connect(url)的方式直接連接FTP服務器
                           if(FTPReply.isPositiveCompletion(ftpClient.getReplyCode()))
                           {
                               
                                   if(ftpClient.login(username, password))
                                   {
                                            return true;
                               }
                           }
                         
                                    disconnect();
                                    return false;


                   }


                   /**
                    * 從FTP服務器上下載文件,支持斷點續(xù)傳功能
                    * @param remote 遠程文件路徑
                    * @param local 本地文件路徑
                    * @param mode tb傳輸方式:PassiveMode方式,ActiveMode方式
                    * @return 是否成功
                    * @throws IOException
                    */
                   public DownloadStatus download(String remote,String local,String mode) throws IOException{


                                   //設置ftp傳輸方式
                                       if(mode.equalsIgnoreCase("P")){
                                               //PassiveMode傳輸
                                               ftpClient.enterLocalPassiveMode();
                                       }
                                       else {
                                               //ActiveMode傳輸
                                               ftpClient.enterLocalActiveMode();
                                       }
                   
                                       //設置以二進制流的方式傳輸
                            ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
                            
                            //下載狀態(tài)
                            DownloadStatus result;   
                            
                            //本地文件列表
                            File f = new File(local);
                            
                            //檢查遠程文件是否存在   
                            FTPFile[] files = ftpClient.listFiles(new String(remote.getBytes("GBK"),"iso-8859-1"));   


                            if(files.length != 1){
                                System.out.println("遠程文件不存在");   
                                return DownloadStatus.Remote_File_Noexist;   
                            }
                            
                            //獲得遠端文件大小
                            long lRemoteSize = files[0].getSize();
                            
                            //構建輸出對象
                        OutputStream ut = null ;
                        
                            //本地存在文件,進行斷點下載 ;不存在則新下載
                            if(f.exists()){
                                    
                                    //構建輸出對象
                                out = new FileOutputStream(f,true);
                                
                                //本地文件大小
                                long localSize = f.length();   


                                System.out.println("本地文件大小為:"+localSize);
                                
                                
                                //判定本地文件大小是否大于遠程文件大小   
                                if(localSize >= lRemoteSize){
                                    System.out.println("本地文件大于遠程文件,下載中止");   
                                    return DownloadStatus.Local_Bigger_Remote;   
                                }
                                
                                //否則進行斷點續(xù)傳,并記錄狀態(tài)   
                                ftpClient.setRestartOffset(localSize);   
                                
                                InputStream in = ftpClient.retrieveFileStream(new String(remote.getBytes("GBK"),"iso-8859-1"));   
                                
                                byte[] bytes = new byte[1024];   
                                long step = lRemoteSize /100;  
                                
                                //存放下載進度
                                long process=localSize /step;   
                                int c;   
                                while((c = in.read(bytes))!= -1){   
                                    out.write(bytes,0,c);   
                                    localSize+=c;   
                                    long nowProcess = localSize /step;   
                                    if(nowProcess > process){   
                                        process = nowProcess;   
                                        if(process % 10 == 0)   
                                            System.out.println("下載進度:"+process);   
                                        //TODO 更新文件下載進度,值存放在process變量中   
                                    }   
                                }
                                //下載完成關閉輸入輸出流對象
                                in.close();   
                                out.close();   
                                boolean isDo = ftpClient.completePendingCommand();   
                                if(isDo){   
                                    result = DownloadStatus.Download_From_Break_Success;   
                                }else {   
                                    result = DownloadStatus.Download_From_Break_Failed;   
                                }   


                            }else {
                                    out = new FileOutputStream(f);   
                                InputStream in= ftpClient.retrieveFileStream(new String(remote.getBytes("GBK"),"iso-8859-1"));   
                                byte[] bytes = new byte[1024];   
                                long step = lRemoteSize /100;   
                                long process=0;   
                                long localSize = 0L;   
                                int c;   
                                while((c = in.read(bytes))!= -1){   
                                    out.write(bytes, 0, c);   
                                    localSize+=c;   
                                    long nowProcess = localSize /step;   
                                    if(nowProcess > process){   
                                        process = nowProcess;   
                                        if(process % 10 == 0)   
                                            System.out.println("下載進度:"+process);   
                                        //TODO 更新文件下載進度,值存放在process變量中   
                                    }   
                                }   
                                in.close();   
                                out.close();   
                                boolean upNewStatus = ftpClient.completePendingCommand();   
                                if(upNewStatus){   
                                    result = DownloadStatus.Download_New_Success;   
                                }else {   
                                    result = DownloadStatus.Download_New_Failed;   
                                }   
                            }
                            return result;
                        }
                          
                        /**
                         * 上傳文件到FTP服務器,支持斷點續(xù)傳
                         * @param local 本地文件名稱,絕對路徑
                         * @param remote 遠程文件路徑,使用/home/directory1/subdirectory/file.ext 按照Linux上的路徑指定方式,支持多級目錄嵌套,支持遞歸創(chuàng)建不存在的目錄結構
                         * @param mode 傳輸方式:PassiveMode方式,ActiveMode方式
                         * @return 上傳結果
                         * @throws IOException
                         */
                        public UploadStatus upload(String local,String remote,String mode) throws IOException{
                            //設置PassiveMode傳輸
                            ftpClient.enterLocalPassiveMode();
                            //設置以二進制流的方式傳輸
                            ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
                            UploadStatus result;
                            //對遠程目錄的處理
                            String remoteFileName = remote;
                            if(remote.contains("/")){
                                remoteFileName = remote.substring(remote.lastIndexOf("/")+1);
                                String directory = remote.substring(0,remote.lastIndexOf("/")+1);
                                if(!directory.equalsIgnoreCase("/")&&!ftpClient.changeWorkingDirectory(directory)){
                                    //如果遠程目錄不存在,則遞歸創(chuàng)建遠程服務器目錄
                                    int start=0;
                                    int end = 0;
                                    if(directory.startsWith("/")){
                                        start = 1;
                                    }else{
                                        start = 0;
                                    }
                                    end = directory.indexOf("/",start);
                                    while(true){
                                        String subDirectory = remote.substring(start,end);
                                        if(!ftpClient.changeWorkingDirectory(subDirectory)){
                                            if(ftpClient.makeDirectory(subDirectory)){
                                                ftpClient.changeWorkingDirectory(subDirectory);
                                            }else {
                                                System.out.println("創(chuàng)建目錄失敗");
                                                return UploadStatus.Create_Directory_Fail;
                                            }
                                        }
                                           
                                        start = end + 1;
                                        end = directory.indexOf("/",start);
                                           
                                        //檢查所有目錄是否創(chuàng)建完畢
                                        if(end <= start){
                                            break;
                                        }
                                    }
                                }
                            }
                               
                            //檢查遠程是否存在文件
                            FTPFile[] files = ftpClient.listFiles(remoteFileName);
                            if(files.length == 1){
                                long remoteSize = files[0].getSize();
                                File f = new File(local);
                                long localSize = f.length();
                                if(remoteSize==localSize){
                                    return UploadStatus.File_Exits;
                                }else if(remoteSize > localSize){
                                    return UploadStatus.Remote_Bigger_Local;
                                }
                                   
                                //嘗試移動文件內讀取指針,實現(xiàn)斷點續(xù)傳
                                InputStream is = new FileInputStream(f);
                                if(is.skip(remoteSize)==remoteSize){
                                    ftpClient.setRestartOffset(remoteSize);
                                    if(ftpClient.storeFile(remote, is)){
                                        return UploadStatus.Upload_From_Break_Success;
                                    }
                                }
                                //如果斷點續(xù)傳沒有成功,則刪除服務器上文件,重新上傳
                                if(!ftpClient.deleteFile(remoteFileName)){
                                    return UploadStatus.Delete_Remote_Faild;
                                }
                                is = new FileInputStream(f);
                                if(ftpClient.storeFile(remote, is)){     
                                    result = UploadStatus.Upload_New_File_Success;
                                }else{
                                    result = UploadStatus.Upload_New_File_Failed;
                                }
                                is.close();
                            }else {
                                InputStream is = new FileInputStream(local);
                                if(ftpClient.storeFile(remoteFileName, is)){
                                    result = UploadStatus.Upload_New_File_Success;
                                }else{
                                    result = UploadStatus.Upload_New_File_Failed;
                                }
                                is.close();
                            }
                            return result;
                        }
                   
               /**
                * 斷開與遠程服務器的連接
                * @throws IOException
                */
               public void disconnect() throws IOException{
                   if(ftpClient.isConnected()){
                       ftpClient.disconnect();
                   }
               }

          posted @ 2012-07-25 15:29 chen11-1 閱讀(2221) | 評論 (3)編輯 收藏

          SpringBird Erp系統(tǒng)快速開發(fā)平臺(組織機構,權限管理)、代碼生成器……

          SpringBird Erp系統(tǒng)快速開發(fā)平臺基于通用的三層架構,數(shù)據(jù)訪問層采用了無Sql注入風險的IBatis.net,表現(xiàn)層采用了微軟最新的Asp.net mvc3 Razor模板解析引擎和輕量級的Jquery easyui,服務層采用了接口編程,整體使用成熟可靠的Ioc、Aop框架Spring.net進行服務層、數(shù)據(jù)訪問層和表現(xiàn)層之間的整合,Erp系統(tǒng)快速開發(fā)平臺默認包含組織機構和權限管理功能。  安裝方式
              1、安裝.net framework 4.0
              2、建立數(shù)據(jù)庫Erp,用戶名/密碼:sa/sa
              3、執(zhí)行Erp.sql
              4、將文件夾Erp拷貝到C:\inetpub\wwwroot下
              5、打開IIS7管理器,將默認網(wǎng)站下的Erp轉換為應用程序,應用程序池選擇ASP.NET v4.0集成模式
              6、將文件夾PermissionWs拷貝到C:\inetpub\wwwroot下
              7、打開IIS7管理器,將默認網(wǎng)站下的PermissionWs轉換為應用程序,應用程序池選擇ASP.NET v4.0 Classic經(jīng)典模式
              8、在瀏覽器中輸入http://localhost/Erp/,賬號/密碼:Admin/123456
            版本1.0.0.4,2011-8-11發(fā)布 下載  http://files.cnblogs.com/springbird/Erp.1.0.0.4.7z
            SpringBird 代碼生成器基于通用的三層架構,數(shù)據(jù)訪問層采用了無Sql注入風險的IBatis.net,表現(xiàn)層采用了微軟的WinForm,服務層采用了接口編程,整體使用成熟可靠的Ioc、Aop框架Spring.net進行服務層、數(shù)據(jù)訪問層和表現(xiàn)層之間的整合,模板定義使用NVelocity模板引擎。
            消息中間件利用高效可靠的消息傳遞機制進行平臺無關的數(shù)據(jù)交流,并基于數(shù)據(jù)通信來進行分布式系統(tǒng)的集成。通過提供消息傳遞和消息排隊模型,它可以在分布式環(huán)境下擴展進程間的通信。SpringBird 基礎平臺架構之消息中間件(Mom,Message Oriented Middleware)基于通用的三層架構,tb數(shù)據(jù)訪問層采用了無Sql注入風險的IBatis.net,表現(xiàn)層采用了微軟最新的Asp.net mvc3 Razor模板解析引擎和輕量級的Jquery easyui,服務層采用了接口編程,整體使用成熟可靠的Ioc、Aop框架Spring.net進行服務層、數(shù)據(jù)訪問層和表現(xiàn)層之間的整合。

          posted @ 2012-07-25 15:27 chen11-1| 編輯 收藏

          JAVA SSH框架 學習

          在Struts + Spring + Hibernate的組合框架模式中,三者各自的特點都是什么?
          Struts 的MVC設計模式可以使我們的邏輯變得很清晰。
          Spring 的IOC和AOP可以使我們的產(chǎn)品在最大限度上解藕。
          hibernate的當然就是實體對象的持久化了
          典型的J2EE三層結構,分為表現(xiàn)層、中間層(業(yè)務邏輯層)和數(shù)據(jù)服務層。三層體系將業(yè)務規(guī)則、數(shù)據(jù)訪問及合法性校驗等工作放在中間層處理。客戶端不直接與數(shù)據(jù)庫交互,而是通過組件與中間層建立連接,再由中間層與數(shù)據(jù)庫交互。
          表現(xiàn)層是傳統(tǒng)的JSP技術,自1999年問世以來,經(jīng)過多年的發(fā)展tb其廣泛的應用和穩(wěn)定的表現(xiàn),為其作為表現(xiàn)層技術打下了堅實的基礎。
          中間層采用的是流行的Spring+Hibernate,為了將控制層與業(yè)務邏輯層分離,又細分為以下幾種。
          Web層,就是MVC模式里面的“C”(controller),負責控制業(yè)務邏輯層與表現(xiàn)層的交互,調用業(yè)務邏輯層,并將業(yè)務數(shù)據(jù)返回給表現(xiàn)層作組織表現(xiàn),該系統(tǒng)的MVC框架采用Struts。
          Service層(就是業(yè)務邏輯層),負責實現(xiàn)業(yè)務邏輯。業(yè)務邏輯層以DAO層為基礎,通過對DAO組件的正面模式包裝,完成系統(tǒng)所要求的業(yè)務邏輯。
          DAO層,負責與持久化對象交互。該層封裝了數(shù)據(jù)的增、刪、查、改的操作。
          PO,持久化對象。通過實體關系映射工具將關系型數(shù)據(jù)庫的數(shù)據(jù)映射成對象,很方便地實現(xiàn)以面向對象方式操作數(shù)據(jù)庫,該系統(tǒng)采用Hibernate作為ORM框架。
          Spring的作用貫穿了整個中間層,將Web層、Service層、DAO層及PO無縫整合,其數(shù)據(jù)服務層用來存放數(shù)據(jù)。
          一個良好的框架可以讓開發(fā)人員減輕重新建立解決復雜問題方案的負擔和精力;它可以被擴展以進行內部的定制化;并且有強大的用戶社區(qū)來支持它。框架通常能很好的解決一個問題。然而,你的應用是分層的,可能每一個層都需要各自的框架。僅僅解決UI問題并不意味著你能夠很好的將業(yè)務邏輯和持久性邏輯和UI 組件很好的耦合。

          不可否認,對于簡單的應用,采用ASP或者PHP的開發(fā)效率比采用J2EE框架的開發(fā)效率要高。甚至有人會覺得:這種分層的結構,比一般采用JSP + Servlet的系統(tǒng)開發(fā)效率還要低。
          筆者從一下幾個角度來闡述這個問題。
          — 開發(fā)效率:軟件工程是個特殊的行業(yè),不同于傳統(tǒng)的工業(yè),例如電器、建筑及汽車等行業(yè)。這些行業(yè)的產(chǎn)品一旦開發(fā)出來,交付用戶使用后將很少需要后續(xù)的維護。但軟件行業(yè)不同,軟件產(chǎn)品的后期運行維護是個巨大的工程,單純從前期開發(fā)時間上考慮其開發(fā)效率是不理智的,也是不公平的。眾所周知,對于傳統(tǒng)的ASP和 PHP等腳本站點技術,將整個站點的業(yè)務邏輯和表現(xiàn)邏輯都混雜在ASP或PHP頁面里,從而導致頁面的可讀性相當差,可維護性非常低。即使需要簡單改變頁面的按鈕,也不得不打開頁面文件,冒著破壞系統(tǒng)的風險。但采用嚴格分層J2EE架構,則可完全避免這個問題。對表現(xiàn)層的修改即使發(fā)生錯誤,也絕對不會將錯誤擴展到業(yè)務邏輯層,更不會影響持久層。因此,采用J2EE分層架構,即使前期的開發(fā)效率稍微低一點,但也是值得的。
          — 需求的變更:以筆者多年的開發(fā)經(jīng)驗來看,很少有軟件產(chǎn)品的需求從一開始就完全是固定的。客戶對軟件需求,是隨著軟件開發(fā)過程的深入,不斷明晰起來的。因此,常常遇到軟件開發(fā)到一定程度時,由于客戶對軟件需求發(fā)生了變化,使得軟件的實現(xiàn)不得不隨之改變。當軟件實現(xiàn)需要改變時,是否可以盡可能多地保留軟件的部分,盡可能少地改變軟件的實現(xiàn),從而滿足客戶需求的變更?答案是——采用優(yōu)秀的解耦架構。這種架構就是J2EE的分層架構,在優(yōu)秀的分層架構里,控制層依賴于業(yè)務邏輯層,但絕不與任何具體的業(yè)務邏輯組件耦合,只與接口耦合;同樣,業(yè)務邏輯層依賴于DAO層,也不會與任何具體的DAO組件耦合,而是面向接口編程。采用這種方式的軟件實現(xiàn),即使軟件的部分發(fā)生改變,其他部分也盡可能不要改變。
          注意:即使在傳統(tǒng)的硬件行業(yè),也有大量的接口規(guī)范。例如PCI接口、顯卡或者網(wǎng)卡,只要其遵守PCI的規(guī)范,就可以插入主板,與主板通信。至于這塊卡內部的實現(xiàn),不是主板所關心的,這也正是面向接口編程的好處。假如需要提高電腦的性能,需要更新顯卡,只要更換另一塊PCI接口的顯卡,而不是將整臺電腦拋棄。如果一臺電腦不是采用各種接口組合在一起,而是做成整塊,那將意味著即使只需要更新網(wǎng)卡,也要放棄整臺電腦。同樣,對于軟件中的一個個組件,當一個組件需要重構時,盡量不會影響到其他組件。實際上,這是最理想的情況,即使采用目前最優(yōu)秀的架構,也會有或多或少的影響,這也是軟件工程需要努力提高的地方。
          技術的更新,系統(tǒng)重構:軟件行業(yè)的技術更新很快,雖然軟件行業(yè)的發(fā)展不快,但小范圍的技術更新特別快。一旦由于客觀環(huán)境的變化,不得不更換技術時,如何保證系統(tǒng)的改變最小呢?答案還是選擇優(yōu)秀的架構。
          在傳統(tǒng)的Model 1的程序結構中,只要有一點小的需求發(fā)生改變,將意味著放棄整個頁面。或者改寫。雖然前期的開發(fā)速度快,除非可以保證以后永遠不會改變應用的結構,否則不要采用Model 1的結構。
          采用Hibernate作為持久層技術的最大的好處在于:可以完全以面向對象的方式進行系統(tǒng)分析、系統(tǒng)設計。
          DAO模式需要為每個DAO組件編寫DAO接口,同時至少提供一個實現(xiàn)類,根據(jù)不同需要,可能有多個實現(xiàn)類。用Spring容器代替DAO工廠
          通常情況下,引入接口就不可避免需要引入工廠來負責DAO組件的生成。Spring實現(xiàn)了兩種基本模式:單態(tài)模式和工廠模式。而使用Spring可以完全避免使用工廠模式,因為Spring就是個功能非常強大的工廠。因此,完全可以讓Spring充當DAO工廠。
          由Spring充當DAO工廠時,無須程序員自己實現(xiàn)工廠模式,只需要將DAO組件配置在Spring容器中,由ApplicationContext負責管理DAO組件的創(chuàng)建即可。借助于Spring提供的依賴注入,其他組件甚至不用訪問工廠,一樣可以直接使用DAO實例。
          優(yōu)點:
          Struts跟Tomcat、Turbine等諸多Apache項目一樣,是開源軟件,這是它的一大優(yōu)點。使開發(fā)者能更深入的了解其內部實現(xiàn)機制。
          除此之外,Struts的優(yōu)點主要集中體現(xiàn)在兩個方面:Taglib和頁面導航。Taglib是Struts的標記庫,靈活動用,能大大提高開發(fā)效率。另外,就目前國內的JSP開發(fā)者而言,除了使用JSP自帶的常用標記外,很少開發(fā)自己的標記,或許Struts是一個很好的起點。
          關于頁面導航,我認為那將是今后的一個發(fā)展方向,事實上,這樣做,使系統(tǒng)的脈絡更加清晰。通過一個配置文件,即可把握整個系統(tǒng)各部分之間的聯(lián)系,這對于后期的維護有著莫大的好處。尤其是當另一批開發(fā)者接手這個項目時,這種優(yōu)勢體現(xiàn)得更加明顯。
          缺點:
          Taglib是Struts的一大優(yōu)勢,但對于初學者而言,卻需要一個持續(xù)學習的過程,甚至還會打亂你網(wǎng)頁編寫的習慣,但是,當你習慣了它時,你會覺得它真的很棒。
          Struts將MVC的Controller一分為三,在獲得結構更加清晰的同時,也增加了系統(tǒng)的復雜度。
          Struts從產(chǎn)生到現(xiàn)在還不到半年,但已逐步越來越多運用于商業(yè)軟件。雖然它現(xiàn)在還有不少缺點,但它是一種非常優(yōu)秀的J2EE MVC實現(xiàn)方式,如果你的系統(tǒng)準備采用J2EE MVC架構,那么,不妨考慮一下Struts。

          posted @ 2012-07-25 15:25 chen11-1| 編輯 收藏

          AJAX的學習與理解 .

          1>:今天重新回到對AJAX的認識,首先從AJAX的由來說起,由于感覺自己才疏學淺,

                我感覺只有了解了WEB的發(fā)展歷史,我們才能更好地理解并運用AJAX。

          2>:其實AJAX最大的應用就是我們要理解XMLHttpRequest這個對象。XMLHttpRequest可以提供不重新加載頁面的情況下更新網(wǎng)頁,在頁面加載后在客戶端向服務器請數(shù) 據(jù), 在  頁面加載后在服務器端接受數(shù)據(jù),在后臺向客戶端發(fā)送數(shù)據(jù)。XMLHttpRequest 對象提供了對 HTTP 協(xié)議的完全的訪問,包括做出 POST 和 HEAD 請求以及普通的 GET 請求的能力。XMLHttpRequest 可以同步或異步返回 Web 服務器的響應,并且能以文本或者一個 DOM 文檔形式返回內容。

          3>:我們如何創(chuàng)建一個XMLHttpRequest對象呢?

               首先我們要知道XMLHttpRequest對象開始時有微軟開發(fā)的一個基于IE5,IE6的一個插件,所以他在IE瀏覽器中肯定有自己的創(chuàng)建方式,IE中把他實現(xiàn)成一個ActiveX對象,但其他瀏覽器如果也想使用  XMLHttpRequest對象,就必須依靠JAVASCRIPT創(chuàng)建本地對象。我們在使用時不需要判斷瀏覽器的類型,只需要看瀏覽器提供對ActiveX的支持。

          下面就是XMLHttpRequest的創(chuàng)建方式:

          [javascript] view plaincopyprint?
          01.function createXHR() 
          02.{ 
          03. if(window.ActiveXObject) 
          04. { 
          05.  xmlHttpRequest=new ActiveXObject("Microsoft.XMLHTTP"); 
          06. } 
          07. else if(window.XMLHttpRequest) 
          08. { 
          09.  xmlHttpRequest=new XMLHttpRequest(); 
          10. } 
          11. if(null==xmlHttpRequest) 
          12. {  
          13.  alert("瀏覽器不支持"); 
          14. } 
          15.} 
           function createXHR()
           {
            if(window.ActiveXObject)
            {
             xmlHttpRequest=new ActiveXObject("Microsoft.XMLHTTP");
            }
            else if(window.XMLHttpRequest)
            {
             xmlHttpRequest=new XMLHttpRequest();
            }
            if(null==xmlHttpRequest)
            {
             alert("瀏覽器不支持");
            }
           }4>:介紹XMLHttpRequest的常用屬性、方法:

          百度其實是個好東西,我沒必要復制粘貼:大家可以參考http://baike.baidu.com/view/1105115.htm

          5>:XMLHttpRequest的應用:

          其實要理解AJAX并學會運用我們只要掌握三方面內容,第一就是XMLHttpRequest對象的創(chuàng)建。第二就是如何從表單獲取值并傳到服務器。第三就是如何從后臺獲取數(shù)據(jù)顯示在前臺。大家想想AJAX的應用是不是就是圍繞這三方面。

          下面我們來簡單說一下如何從表單獲取值的問題:其實只要稍微了解點JavaScript的熱你都知道我們DOM文檔模型,通過操縱文檔對象模型中對象的屬性并調用其方法,可以使腳本按照一定的方式顯示W(wǎng)eb頁并與用戶的動作進行交互。

          我們常用的就是document.getElementById("id").value.來獲取網(wǎng)頁中的數(shù)據(jù)。其他的大家用到就百度。

          我們獲取到值之后就是把這個值傳給后臺:這里我們一般采用get:方式提交,采用url傳參。通過調用:xmlHttpRequest.open("get","url?paramater="+value,true);

          最后就是如何從后臺獲取值傳到前臺顯示:這里是通過xmlHttpRequest.responseText(返回一個字符串)xmlHttpRequest.responseXML返回一個XML文件。

          我們可以通過解析這兩種值插入到頁面中:通常我們用到的顯示在htbml中方式是:通過document.getElementById("id").value=xmlHttpRequest.responseText;

          或者document.getElementById("id").innerHTML=xmlHttpRequest.responseText;

          知道了這些我們先做一個簡單地例子:

          [javascript] view plaincopyprint?
          01.<script type="text/javascript"> 
          02.    var xmlHttpRequest=null; 
          03.    function createXHR() 
          04.    { 
          05.        if(window.ActiveXObject) 
          06.        { 
          07.            xmlHttpRequest=new ActiveXObject("Microsoft.XMLHTTP"); 
          08.        } 
          09.        else if(window.XMLHttpRequest) 
          10.        { 
          11.            xmlHttpRequest=new XMLHttpRequest(); 
          12.        } 
          13.        if(null!=xmlHttpRequest) 
          14.        {    
          15.            var v1=document.getElementById("num1").value; 
          16.            var v2=document.getElementById("num2").value; 
          17.            xmlHttpRequest.open("get","servlet/AjaxServlet?v1="+v1+"&v2="+v2,true); 
          18.            xmlHttpRequest.onreadystatechange=callback; 
          19.            xmlHttpRequest.send(null); 
          20.        } 
          21.    } 
          22.    function callback() 
          23.    { 
          24.        if(xmlHttpRequest.readyState==4) 
          25.        { 
          26.            if(xmlHttpRequest.status==200) 
          27.            { 
          28.                var responseText=xmlHttpRequest.responseText; 
          29.                document.getElementById("num3").innerHTML=responseText;//innerHTML不能小寫  
          30.            } 
          31.        } 
          32.    } 
          33.    </script> 
          <script type="text/javascript">
           var xmlHttpRequest=null;
           function createXHR()
           {
            if(window.ActiveXObject)
            {
             xmlHttpRequest=new ActiveXObject("Microsoft.XMLHTTP");
            }
            else if(window.XMLHttpRequest)
            {
             xmlHttpRequest=new XMLHttpRequest();
            }
            if(null!=xmlHttpRequest)
            { 
             var v1=document.getElementById("num1").value;
             var v2=document.getElementById("num2").value;
             xmlHttpRequest.open("get","servlet/AjaxServlet?v1="+v1+"&v2="+v2,true);
             xmlHttpRequest.onreadystatechange=callback;
             xmlHttpRequest.send(null);
            }
           }
           function callback()
           {
            if(xmlHttpRequest.readyState==4)
            {
             if(xmlHttpRequest.status==200)
             {
              var responseText=xmlHttpRequest.responseText;
              document.getElementById("num3").innerHTML=responseText;//innerHTML不能小寫
             }
            }
           }
           </script>[html] view plaincopyprint?
          01.<form method="" action=""> 
          02.    <table border="1" borderstyle="solid" cellpacing="0" > 
          03.        <tr><td><input type="text" id="num1"/></td></tr> 
          04.        <tr><td><input type="text" id="num2"/></td></tr> 
          05.        <tr><td><input type="button" value="submit" onclick="createXHR()"/></td></tr> 
          06.        <tr><td><span id="num3"></span></td></tr> 
          07.    </table>  
          08.   </form> 
          <form method="" action="">
              <table border="1" borderstyle="solid" cellpacing="0" >
               <tr><td><input type="text" id="num1"/></td></tr>
               <tr><td><input type="text" id="num2"/></td></tr>
               <tr><td><input type="button" value="submit" onclick="createXHR()"/></td></tr>
               <tr><td><span id="num3"></span></td></tr>
              </table>
             </form>以上代碼有借鑒http://blog.csdn.net/csh624366188/article/details/7670500大家也可以去看。

           

          還有兩哥問題一:如何將結果顯示在下拉列表,第二如何讀取XML文件,這個稍后介紹。

           

          posted @ 2012-07-24 16:49 chen11-1 閱讀(1586) | 評論 (0)編輯 收藏

          關于Jquery中的鏈式編程和動畫效果(注意事項) .

          1.

          其實我本身對于鏈式編程一直不怎么感冒,因為看起來邏輯不怎么清晰,今天就將一個鏈式編程給拆開了,結果發(fā)現(xiàn),其實JQuery的鏈式編程原來還是不一樣的,這讓我想起了java中的鏈式編程,以前也沒怎么考慮過,現(xiàn)在想想,原來自己一直在誤區(qū)當中。


          想要說的就是,Jquery中的鏈式編程,其執(zhí)行順序是從后往前執(zhí)行的。例如,在做類似qq的分組顯示時,用Jquery語句:

          $(this).siblings("li[class!=header]").hide().next().show("fast");

          就是不可以的,要把它換為

          $(this).next().show().siblings("li[class!=header]").hide();


          2.

          關于動畫效果,開始也沒怎么考慮,今天發(fā)現(xiàn)還是不太一樣的。

          比如說:

          $(this).next().show();

          alert(123)

           

          $(this).next().show("fast");

          alert(123)

          二者是不一樣的,沒有加fast,其立即執(zhí)行,因此,很tb可能是先執(zhí)行后面的語句,再執(zhí)行本語句。也就是說,加了速度的參數(shù),產(chǎn)生的是一段延遲。

          posted @ 2012-07-24 16:48 chen11-1| 編輯 收藏

          函數(shù)式編程的10年演化:越來越純

          在過去10年中,函數(shù)式編程的定義一直在慢慢改變,在“Wikipedia page on Functional Programming”上可以顯著地反映出來。

          在2003年8月14號之前的定義是:函數(shù)式編程作為一種模式,強調函數(shù)的使用。例如在2011年10月14號,維基百科用了220個單詞進行定義,在開頭這樣描述到:

          函數(shù)式編程是一種編程風格,它關注的是函數(shù)表達式的計算,而不是執(zhí)行命令。在這些語言上,表達式把函數(shù)與基本功能相結合。

          函數(shù)式編程語言是一種支持和鼓勵將電腦運算當成函數(shù)計算,比較古老的函數(shù)式編程莫過于Lisp,較現(xiàn)代的Scheme,ML,Haskell,Erlang,Clean。Lisp是第一個函數(shù)式編程語言,它和Scheme,ML,Haskell一樣。

          這樣的定義一直維持到2003年8月14號,新百科全書在內容制作上有了結構化調整。Luxor把新百科全書的定義與維基百科相融合,創(chuàng)建了一個新的頁面并且用了1640個單詞進行重新定義,開頭定義到:

          函數(shù)式編程是一種編程范式,把計算看作是一種數(shù)學函數(shù)計算。與命令式編程相比,tb函數(shù)式編程關注的是函數(shù)表達式的計算而不是執(zhí)行命令。在這些語言上,表達式把函數(shù)與基本功能相結合。

          在這一點上,函數(shù)式編程并不強調函數(shù)的使用,相反,它意味著編程要與數(shù)學函數(shù)相結合。在這個定義里還隱藏著另外一個意思:函數(shù)越來越純粹。這一條在定義里并沒有明確的表達出來。直到2006年5月29號:

          函數(shù)式編程是一種編程范式,把計算看作是一種數(shù)學函數(shù)計算。函數(shù)式編程關注的是函數(shù)定義而不是實現(xiàn)狀態(tài)機,與過程式編程相比,它強調命令的連序執(zhí)行。一個純函數(shù)程序不會去修改狀態(tài)產(chǎn)生的值(適用于命令式編程),它會構造新的值(但不會覆蓋現(xiàn)有值)。

          對函數(shù)式編程或函數(shù)式編程語言沒有統(tǒng)一的共識。函數(shù)式編程語言的重要特征:高階和一級函數(shù)、閉包、遞歸。其他還包括編程語言連續(xù)性、Hindley-Milner類型診斷系統(tǒng)、懶惰計算和單體。

          這里還有一些小區(qū)別,關于(普通)函數(shù)編程和“純”形式的函數(shù)編程,避免使用不穩(wěn)定的狀態(tài)。在2006年5月29號01:07分,在沒有任何征兆的情況下,一個叫ideogram的用戶進行了微小但是非常有意義的修改:

          •函數(shù)式編程是一種編程風格,把計算看作是一種數(shù)學函數(shù)計算并且避免狀態(tài)和可變數(shù)據(jù)。
          •函數(shù)式編程關注函數(shù)定義,與過程式編程相比,它強調命令的連序執(zhí)行。
          •函數(shù)式編程的依賴λ演算(lambda calculus),Lisp和較新的Haskell。常常提到的是避免狀態(tài)和副作用(它提供對引用透明),高階函數(shù),遞歸和閉包。
          該賬戶僅僅在編輯前幾天創(chuàng)建,后來就一直處于禁止狀態(tài)。

          最近,也就是在2012年7月14號,定義頁面又出現(xiàn)了新的變化:

          在計算機科學領域,函數(shù)式編程是一種編程范式,把計算看作是一種數(shù)學函數(shù)計算并且避免狀態(tài)和可變數(shù)據(jù)。它強調函數(shù)的應用,與命令式編程語言相比,強調狀態(tài)的變化。函數(shù)式編程根源于λ 演算,一個正式的函數(shù)式編程系統(tǒng)在20世紀30年代被開發(fā),用來研究函數(shù)的定義,函數(shù)的應用和遞歸。許多函數(shù)式編程語言可以看作是對λ演算進行的闡述。

          在實際操作中,數(shù)學函數(shù)和“函數(shù)”概念之間在命令式編程上的差異主要表現(xiàn)為命令式函數(shù)編程存在改變程序狀態(tài)值這一缺點。因此,他們缺乏引用透明,相同的語言表達式根據(jù)執(zhí)行應用程序狀態(tài),在不同的時間可以產(chǎn)生不同的值。相反,在函數(shù)代碼上,函數(shù)的輸出值僅僅依賴于函數(shù)的輸入?yún)?shù),所以,輸入同一個參數(shù)X兩次,那么輸出結果都是Y。消除副作用也更容易理解和預測程序的行為,這是函數(shù)編程語言發(fā)展的一個重要推動。

          [1]Hudak, Paul。“概念, 發(fā)展和函數(shù)式編程語言的應用”。ACM Computing Surveys 21 (3): 359–411。上述內容的含義是什么?這一變化是如何產(chǎn)生的?我們正卷入一場(小的)科學革命中,幕后推手又是誰?

          根據(jù)最新的定義,ML和Lisp不在是函數(shù)式語言。用這些語言的子函數(shù)去寫一些程序來避免可變狀態(tài)的使用。第一個需求是在ML中使用“ref”或者在Lisp中使用分配和構造突變。然而,對于ML和Lisp來說并不足夠,許多標準庫都存在負面作用,對于任何IO庫來說,都是如此。結果就是,程序在一個范圍內可以很方便地編寫比較單一的功能與風格,但這也是相當有限的。

           

          posted @ 2012-07-24 16:45 chen11-1| 編輯 收藏

          Java程序員應該了解的10個面向對象設計原則

          面向對象設計原則是OOPS(Object-Oriented Programming System,面向對象的程序設計系統(tǒng))編程的核心,但大多數(shù)Java程序員追逐像Singleton、Decorator、Observer這樣的設計模式,而不重視面向對象的分析和設計。甚至還有經(jīng)驗豐富的Java程序員沒有聽說過OOPS和SOLID設計原則,他們根本不知道設計原則的好處,也不知道如何依照這些原則來進行編程。

          眾所周知,Java編程最基本的原則就是要追求高內聚和低耦合的解決方案和代碼模塊設計。查看Apache和Sun的開放源代碼能幫助你發(fā)現(xiàn)其他Java設計原則在這些代碼中的實際運用。Java Development Kit則遵循以下模式:BorderFactory類中的工廠模式、Runtime類中的單件模式。你可以通過Joshua Bloch的《Effective Java》一書來了解更多信息。我個人偏向的另一種面向對象的設計模式是Kathy Sierra的Head First Design Pattern以及Head Firstb Object Oriented Analysis and Design。

          雖然實際案例是學習設計原則或模式的最佳途徑,但通過本文的介紹,沒有接觸過這些原則或還在學習階段的Java程序員也能夠了解這10個面向對象的設計原則。其實每條原則都需要大量的篇幅才能講清楚,但我會盡力做到言簡意賅。

          原則1:DRY(Don't repeat yourself)

          即不要寫重復的代碼,而是用“abstraction”類來抽象公有的東西。如果你需要多次用到一個硬編碼值,那么可以設為公共常量;如果你要在兩個以上的地方使用一個代碼塊,那么可以將它設為一個獨立的方法。SOLID設計原則的優(yōu)點是易于維護,但要注意,不要濫用,duplicate 不是針對代碼,而是針對功能。這意味著,即使用公共代碼來驗證OrderID和SSN,二者也不會是相同的。使用公共代碼來實現(xiàn)兩個不同的功能,其實就是近似地把這兩個功能永遠捆綁到了一起,如果OrderID改變了其格式,SSN驗證代碼也會中斷。因此要慎用這種組合,不要隨意捆綁類似但不相關的功能。

          原則2:封裝變化

          在軟件領域中唯一不變的就是“Change”,因此封裝你認為或猜測未來將發(fā)生變化的代碼。OOPS設計模式的優(yōu)點在于易于測試和維護封裝的代碼。如果你使用Java編碼,可以默認私有化變量和方法,并逐步增加訪問權限,比如從private到protected和not public。有幾種Java設計模式也使用封裝,比如Factory設計模式是封裝“對象創(chuàng)建”,其靈活性使得之后引進新代碼不會對現(xiàn)有的代碼造成影響。

          原則3:開閉原則

          即對擴展開放,對修改關閉。這是另一種非常棒的設計原則,可以防止其他人更改已經(jīng)測試好的代碼。理論上,可以在不修改原有的模塊的基礎上,擴展功能。這也是開閉原則的宗旨。

          原則4:單一職責原則

          類被修改的幾率很大,因此應該專注于單一的功能。如果你把多個功能放在同一個類中,功能之間就形成了關聯(lián),改變其中一個功能,有可能中止另一個功能,這時就需要新一輪的測試來避免可能出現(xiàn)的問題。

          原則5:依賴注入或倒置原則

          這個設計原則的亮點在于任何被DI框架注入的類很容易用mock對象進行測試和維護,因為對象創(chuàng)建代碼集中在框架中,客戶端代碼也不混亂。有很多方式可以實現(xiàn)依賴倒置,比如像AspectJ等的AOP(Aspect Oriented programming)框架使用的字節(jié)碼技術,或Spring框架使用的代理等。

          原則6:優(yōu)先利用組合而非繼承

          如果可能的話,優(yōu)先利用組合而不是繼承。一些人可能會質疑,但我發(fā)現(xiàn),組合比繼承靈活得多。組合允許在運行期間通過設置類的屬性來改變類的行為,也可以通過使用接口來組合一個類,它提供了更高的靈活性,并可以隨時實現(xiàn)。《Effective Java》也推薦此原則。

          原則7:里氏代換原則(LSP)

          根據(jù)該原則,子類必須能夠替換掉它們的基類,也就是說使用基類的方法或函數(shù)能夠順利地引用子類對象。LSP原則與單一職責原則和接口分離原則密切相關,如果一個類比子類具備更多功能,很有可能某些功能會失效,這就違反了LSP原則。為了遵循該設計原則,派生類或子類必須增強功能。

          原則8:接口分離原則

          采用多個與特定客戶類有關的接口比采用一個通用的涵蓋多個業(yè)務方法的接口要好。設計接口很棘手,因為一旦釋放接口,你就無法在不中斷執(zhí)行的情況下改變它。在Java中,該原則的另一個優(yōu)勢在于,在任何類使用接口之前,接口不利于實現(xiàn)所有的方法,所以單一的功能意味著更少的實現(xiàn)方法。

          原則9:針對接口編程,而不是針對實現(xiàn)編程

          該原則可以使代碼更加靈活,以便可以在任何接口實現(xiàn)中使用。因此,在Java中最好使用變量接口類型、方法返回類型、方法參數(shù)類型等。《Effective Java》 和《head first design pattern》書中也有提到。

          原則10:委托原則

          該原則最典型的例子是Java中的equals() 和 hashCode() 方法。為了平等地比較兩個對象,我們用類本身而不是客戶端類來做比較。這個設計原則的好處是沒有重復的代碼,而且很容易對其進行修改。

          總之,希望這些面向對象的設計原則能幫助你寫出更靈活更好的代碼。理論是第一步,更重要的是需要開發(fā)者在實踐中去運用和體會。

           

          posted @ 2012-07-24 16:43 chen11-1 閱讀(937) | 評論 (0)編輯 收藏

          對互聯(lián)網(wǎng)創(chuàng)新的看法 .


          最近對如何在互聯(lián)網(wǎng)創(chuàng)新進行了許多討論,現(xiàn)在記下一些感想:
          一:前提條件
          最好是能解決市場中沒有滿足的需求,首先確定使用用戶群,之后定向推廣,有很大可能用戶爆發(fā)增長。


          能促進人與人之間的溝通,拉近人與人之間的距離,打破溝通障礙;


          產(chǎn)品要簡單,上手快。不要有太多門檻,每一級門檻都會流失大部分用戶。


          在自己強項和特長的基礎上做產(chǎn)品;


          創(chuàng)新不是憑空創(chuàng)造,更多的是很多小的改進的積累;


          產(chǎn)品使用符合大眾習慣,而不是開發(fā)者習慣。


          小產(chǎn)品如果要快速發(fā)展,最好抓住簡單,有趣,奇特,搞怪。。。這些特點去設計,產(chǎn)品可以簡單,但是要做出精品,好用而且讓人印象深刻。需要拋棄復雜思路和做法。


          最好能幫助用戶解決改進生活中的一個或者幾個問題,而不是純娛樂。


          二:關于創(chuàng)造

          創(chuàng)造不是憑空的,而是許多在現(xiàn)有基礎上小的創(chuàng)新積累的結果,量變產(chǎn)生質變,才會產(chǎn)生偉大的創(chuàng)造。去了解硅谷公司的創(chuàng)新歷史會知道這一點。
          點點網(wǎng)是給小資的,4399(www.4399.com)是為更廣大的底層用戶服務的,同樣服務底層的還有 擲出窗外(http://www.zccw.info/)后兩者的訪問量都是巨大的,擲出窗外服務器都頂不住了。這是兩種創(chuàng)新思維,前者緊跟硅谷;tb后者貼近中國底層基礎需求;兩種思路,兩種設計和展示方式。
          互聯(lián)網(wǎng)網(wǎng)站需要操作簡單,設計簡單,零門檻;手機app也需要很簡單,越簡單,功能單一,會容易傳播;
          網(wǎng)站展示應該簡單,復雜的結果是使用門檻高,傳播門檻高,擋住了大部分用戶。需要的砍掉多余的設計,為用戶呈現(xiàn)月簡單越好,設計顏色也應該盡量的少,例如thislife和google的白色很百搭很大眾。
          網(wǎng)站的名字,如果類似 google 或者自己創(chuàng)造的一個詞,沒有特殊意義才會更容易賦予很多意義。
          手機視頻app的爆發(fā)期在3G用戶量超過2G并且資費很便宜的時候,目前還處于前夜。相信很多大公司在做準備了。
          互聯(lián)網(wǎng)的另外很多機會在垂直領域,這些領域需要有很強的專業(yè)背景和資源,才可能在這個領域內做到最好;

          三 關于國內網(wǎng)的差距
          國外會以互動方式展示功能,功能使用的時候再展現(xiàn)出來,例如評論;而不是把所有功能都列出來web1.0的展示方式;

          國外的網(wǎng)站在模擬現(xiàn)實環(huán)境,例如把照片排列在一面墻上,網(wǎng)站背景模擬的是白色的墻,照片掛到墻上,貼近現(xiàn)實生活,用戶易懂。
          網(wǎng)站也在盡可能在模擬觸屏的滑動效果;

          很簡單易懂的表達方式,團隊有很高的交互式設計能力;很有蘋果風格;

          功能用到的時候再展現(xiàn)給用戶,而不是擺出所有功能讓用戶自助選擇;如果把網(wǎng)站比喻為餐廳的話,國外很多網(wǎng)站的服務很到位,服務水平很高,國內網(wǎng)站像是小吃部,體驗不好。

          網(wǎng)站,app設計的最終目標是與真實環(huán)境越像越好,用戶上手也會很快,他們的設計思路是:盡可能的模擬真實世界,無論是視覺上還是操作上;

          差距在哪里? 技術上差距應該不大,差距在同一個思想如何表達給用戶,國外強的地方是他們的表達方式和思維方式;點點網(wǎng)許朝軍有過一句話:the product is the story we tell to the world。 國內很多創(chuàng)業(yè)者有很多故事,但是故事講的方式不好,理解和認可的人少。

           

          posted @ 2012-07-20 15:06 chen11-1 閱讀(905) | 評論 (0)編輯 收藏

          僅列出標題
          共20頁: First 上一頁 9 10 11 12 13 14 15 16 17 下一頁 Last 
          主站蜘蛛池模板: 阿勒泰市| 潞西市| 江永县| 合肥市| 安远县| 昌都县| 穆棱市| 林芝县| 泊头市| 赣榆县| 丹江口市| 东乡| 嘉义市| 台南县| 门源| 阿克苏市| 镇巴县| 陆丰市| 启东市| 广宗县| 古交市| 清河县| 陆河县| 长汀县| 阜平县| 潞西市| 铁岭县| 惠来县| 太仓市| 宝兴县| 巩留县| 临沂市| 林芝县| 东乌珠穆沁旗| 乐安县| 衡阳县| 邯郸县| 盱眙县| 福清市| 分宜县| 马鞍山市|