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

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

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

    和風(fēng)細(xì)雨

    世上本無難事,心以為難,斯乃真難。茍不存一難之見于心,則運(yùn)用之術(shù)自出。

    #

    異常機(jī)制概述

    異常機(jī)制綜述

    在運(yùn)行過程中,應(yīng)用程序可能遭遇各種嚴(yán)重程度不同的問題.異常提供了一種在不弄亂程序的情況下檢查錯(cuò)誤的巧妙方式.它也提供了一種直接報(bào)告錯(cuò)誤的機(jī)制,而不必檢查標(biāo)志或者具有此作用的域.異常把方法能夠報(bào)告的錯(cuò)誤作為方法約定的一個(gè)顯式部分.
    異常能夠被程序員看到,由編譯器檢查,并且由重載方法的子類保留.
    如果遇到意外的錯(cuò)誤將拋出異常,然后異常被方法調(diào)用棧上的子句捕獲.如果異常未被捕獲,將導(dǎo)致執(zhí)行線程的終止.

    異常的體系結(jié)構(gòu)

    毫無疑問,在java中異常是對象,它必定繼承Throwable及其子類.Throwable中含有一個(gè)用于描述異常的字符串.Exception是Throwable的一個(gè)最常用子類,另一個(gè)子類是Error.而RuntimeException繼承自Exception.


    異常的種類

    非檢查型異常(Unchecked Exception):
    非檢查型異常反映了程序中的邏輯錯(cuò)誤,不能從運(yùn)行中合理恢復(fù).
    標(biāo)準(zhǔn)的運(yùn)行時(shí)異常和錯(cuò)誤構(gòu)成非檢查型異常,它們繼承自RuntimeException和Error.
    非檢查型異常不用顯示進(jìn)行捕獲.

    檢查型異常(Checked Exception):
    這種異常描述了這種情況,雖然是異常的,但被認(rèn)為是可以合理發(fā)生的,如果這種異常真的發(fā)生了,必須調(diào)用某種方法處理.
    Java異常大多是檢查型異常,繼承自Exception類,你自己定義的異常必須是繼承Exception的檢查型異常.
    檢查型異常必須進(jìn)行顯示捕獲.

    自定義異常

    繼承Exception即可定義自己的異常,以下是一種常見寫法
    public class DBXmlFileReadException extends Exception{
      public DBXmlFileReadException(String   msg){
        super(msg);
      }
    }

    拋出異常

    在Java語句中,可以用throw語句拋出異常,如throw new NoSuchElementException();
    拋出的對象必須是Throwable類的子類型.

    拋出異常的策略:
    1) 如果拋出后不可能得到處理,可以拋出Error.
    2) 如果你想讓其它類自由選擇是否處理這個(gè)異常,就可以拋出RuntimeException.
    3) 如果你要求類的用戶必須處理這個(gè)異常,則可以拋出Exception.

    異常拋出后的控制權(quán)轉(zhuǎn)移

    一旦發(fā)生異常,異常發(fā)生點(diǎn)后的動作將不會發(fā)生.此后將要發(fā)生的操作不是在catch塊和finally塊.

    當(dāng)異常拋出時(shí),導(dǎo)致異常發(fā)生的語句和表達(dá)式就被稱為突然完成.語句的突然完成將導(dǎo)致調(diào)用鏈逐漸展開,直到該異常被捕獲.

    如果該異常沒有捕獲,執(zhí)行線程將中止.

    Try,catch和finally

    異常由包含在try塊中的語句捕獲:
        try{
          正常執(zhí)行語句
        }
        catch(XException e){
          異常執(zhí)行語句一
        }
        catch(XXException e){
          異常執(zhí)行語句二
        }
        catch(XXXException e){
          異常執(zhí)行語句三
        }
        finally{
          中止語句
        }

    Try中的語句體要么順利完成,要么執(zhí)行到拋出異常.
    如果拋出異常,就要找出對應(yīng)于異常類或其父類的catch子句,如果未能找到合適的catch子句,異常就從try語句中擴(kuò)散出來,進(jìn)入到外層可能對它進(jìn)行處理的try語句.
    Catch子句可以有多個(gè),只要這些子句捕獲的異常類型不同.
    如果在try中有finally子句,其代碼在try把所有其它處理完成之后執(zhí)行.
    無論是正常完成或是出現(xiàn)異常,甚至是通過return或者break這樣的控制語句結(jié)束,finally子句總是被執(zhí)行.
    Catch子句和finally子句在try語句之后至少有一個(gè),不要求全部出現(xiàn).

    More…

    在catch語句中捕獲通用的異常Exception通常不是最佳策略,因?yàn)樗鼤⑺挟惓_M(jìn)行等同處理.
    不能把基類異常的catch語句放到子類異常的catch語句之前,編譯器會在運(yùn)行之前就檢查出這樣的錯(cuò)誤.
    Try…catch對每個(gè)catch語句都從頭到尾檢查,如果找到處理同類異常的catch子句,此catch塊中的語句將得以執(zhí)行,而不再處理同層次的其它c(diǎn)atch塊.
    如果catch或finally拋出另一個(gè)異常,程序?qū)⒉粫偃z查try的catch子句.
    Try...catch語句可以嵌套,內(nèi)層拋出的異常可被外層處理.

    Throws子句

    函數(shù)能拋出的檢查型異常用throws聲明,它后面可以是帶用逗號隔開的一系列異常類型.僅僅那些在方法中不被捕獲的異常必須列出.

    private void readObject(java.io.ObjectInputStream s)
            throws java.io.IOException, ClassNotFoundException {
            // Read in any hidden serialization magic
            s.defaultReadObject();

            // Read in size
            int size = s.readInt();

            // Initialize header
            header = new Entry<E>(null, null, null);
            header.next = header.previous = header;

            // Read in all elements in the proper order.
            for (int i=0; i<size; i++)
                 addBefore((E)s.readObject(), header);
            }
    }

    More…

    Throws子句的約定是嚴(yán)格強(qiáng)制性的,只能拋出throws子句中聲明的異常類型,拋出其它類型的異常是非法的,不管是直接利用throw,還是調(diào)用別的方法間接的拋出.
    RuntimeException和Error是僅有的不必由throws子句列出的異常.
    調(diào)用函數(shù)的函數(shù)要么處理對聲明的異常進(jìn)行處理,要么也聲明同樣的異常,將收到的異常拋向上層.

    對檢查型異常通常進(jìn)行的幾種處理
    1) 用e.printStackTrace()輸出異常信息.
    2) 將異常記錄到日志中以備查,如logger.error(e.getMessage()).
    3) 試圖進(jìn)行異常恢復(fù).
    4) 告知維護(hù)者和用戶發(fā)生的情況.

    posted @ 2008-02-21 20:09 和風(fēng)細(xì)雨 閱讀(251) | 評論 (0)編輯 收藏

    嵌套類和匿名類概述

    內(nèi)部類的出現(xiàn)

    當(dāng)進(jìn)行Java開發(fā)時(shí),有時(shí)需要實(shí)現(xiàn)一個(gè)僅包含1-2個(gè)方法的接口.在AWT和Swing開發(fā)中經(jīng)常出現(xiàn)這種情況,例如當(dāng)一個(gè)display組件需要一個(gè)事件回調(diào)方法如一個(gè)按鈕的ActionListener時(shí). 如果使用普通的類來實(shí)現(xiàn)此操作,最終會得到很多僅在單個(gè)位置上使用的小型類.
    內(nèi)部類用于處理這種情況,java允許定義內(nèi)部類,而且可在Gui外使用內(nèi)部類.

    內(nèi)部類的定義和實(shí)現(xiàn)

    內(nèi)部類是指在另一個(gè)類內(nèi)部定義的一個(gè)類.可以將內(nèi)部類定義為一個(gè)類的成員.
    public class Linker{
      public class LinkedNode{
        private LinkedNode prev;
        private LinkedNode next;
        private String content;
       
        public LinkedNode(String content){
          this.content=content;
        }
      }
     
      public Linker(){
        LinkedNode first=new LinkedNode("First");
        LinkedNode second=new LinkedNode("Second");
       
        first.next=second;
        second.prev=first;
      }
    }

    定義在一個(gè)類方法中的內(nèi)部類

    public class Hapiness{
      interface Smiler{
        public void smile();
      }
     
      public static void main(String[] args){
        class Happy implements Smiler{
          public void smile(){
            System.out.println(":-}");
          }
        }
       
        Happy happy=new Happy();
        happy.smile();
      }
    }

    匿名類

    對很多情況而言,定義在方法內(nèi)部的類名意義不大,它可以保持為匿名的,程序員關(guān)心的只是它的實(shí)例名.
    如:
    Runnable runner=new Runnable(){
         public void  run(){
              // Run statememnt
         }
    }


    理解匿名類

    匿名類并不難理解,它只是把類的定義過程和實(shí)例的創(chuàng)建過程混合而已,上頁的語句實(shí)際上相當(dāng)于如下語句:
    // 定義類
    Public class Runner implements Runnable{
         public void run(){
             // do sth
          }
    }

    // 創(chuàng)建實(shí)例
    Runner runner=new Runner();

    使用匿名類的篩選解耦過程

    需求:從公司的職員列表中,找出男性且年齡大于22的成員.

    傳統(tǒng)寫法:

       List allmembers=company.getMembers();// 取得所有成員
        List results=new ArrayList();// 結(jié)果列表
       
        for(Iterator it=allmembers.iterator();it.hasNext();){
         Member member=(Member)it.next();
        
         if(member.getAge()>22 && member.isMale()){  // 篩選,這里是把查詢條件和遴選過程融合在一起,條件一變立即就得加個(gè)分支.
          results.add(member);
         }
       }
    傳統(tǒng)方法的缺陷

    這種寫法沒有錯(cuò),但是不是面向?qū)ο蟮膶懛?它有以下缺陷:
    1.查詢條件和篩選過程沒有分離.
    2.這樣寫的后果使Company變成了一個(gè)失血模型而不是領(lǐng)域模型.
    3.換查詢條件的話,上面除了"篩選"一句有變化外其它都是模板代碼,重復(fù)性很高.

    使用匿名類實(shí)現(xiàn)的OO化查詢

    真正符合OO的查詢應(yīng)該是這樣:

       MemberFilter filter1=new MemberFilter(){
        public boolean accept(Member member) {
             return member.isMale() && member.getAge()>22;
        }
       };
      
       List ls=company.listMembers(filter1);
     

    這段代碼成功的把查詢條件作為一個(gè)接口分離了出去,接口代碼如下:

    public interface MemberFilter{
      public boolean accept(Member member);
    }

    查詢函數(shù)的變化

    而類Company增加了這樣一個(gè)函數(shù):

    public List searchMembers(MemberFilter memberFilter){
       List retval=new ArrayList();
       
        for(Iterator it=members.iterator();it.hasNext();){
         Member member=(Member)it.next();
        
         if(memberFilter.accept(member)){
          retval.add(member);
        }
       } 
      
       return retval;
    }
    這就把模板代碼歸結(jié)到了類內(nèi)部,外面不會重復(fù)書寫了.Company也同時(shí)擁有了數(shù)據(jù)和行為,而不是原來的數(shù)據(jù)容器了.

    匿名類的例子二

    用匿名類處理分類匯總的方法 分類匯總是統(tǒng)計(jì)中常用,舉例來說如統(tǒng)計(jì)學(xué)生成績,及格不及格的歸類,分優(yōu)良中差等級歸類等,每個(gè)單項(xiàng)代碼很好寫,但是如果分類匯總的項(xiàng)目多了,能一種匯總寫一個(gè)函數(shù)嗎? 比如說有些科目60分才算及格,有些科目50分就算;有些老師喜歡分優(yōu)良中差四等,有些老師卻喜歡分ABCD;不一而足,如果每個(gè)都寫一個(gè)函數(shù)無疑是個(gè)編寫和維護(hù)惡夢. 如果我們用匿名類把分類匯總的規(guī)則和分類匯總的過程分別抽象出來,代碼就清晰靈活多了,以下代碼講述了這個(gè)過程.

    基本類Student

    public class Student{
        private String name;
        private int score;
       
        public Student(String name,int score){
            this.name=name;
            this.score=score;
        }
       
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public int getScore() {
            return score;
        }
        public void setScore(int score) {
            this.score = score;
        }   
    }

    用于分類匯總的類

    它強(qiáng)制子類實(shí)現(xiàn)getKey和getvalue兩個(gè)方法:
    public abstract class ClassifyRule {
        public Student student;
       
        public ClassifyRule(){       
        }   

        public void setStudent(Student student) {
            this.student = student;
        }
       
        abstract public String getKey();
        abstract public int getValue();
    }

    對Student進(jìn)行統(tǒng)計(jì)處理的StudentService類

    注意getSum方法,它保留了篩選過程,篩選規(guī)則則不在其中:
    import java.util.ArrayList;
    import java.util.Hashtable;
    import java.util.List;

    public class StudentService {
        private List<Student> students;

        public StudentService() {
            students = new ArrayList<Student>();
        }

        public void add(Student student) {
            students.add(student);
        }

        public Hashtable<String, Integer> getSum(ClassifyRule rule) {
            Hashtable<String, Integer> ht = new Hashtable<String, Integer>();

            for (Student student : students) {
                rule.setStudent(student);
                String key = rule.getKey();
                int value = rule.getValue();

                if (ht.containsKey(key)) {
                    Integer oldValue = ht.remove(key);
                    oldValue += value;
                    ht.put(key, oldValue);
                } else {
                    ht.put(key, value);
                }
            }

            return ht;
        }
    }

    測試代碼,注意其中篩選規(guī)則的創(chuàng)建

    public class Test {
        public static void main(String[] args) {
            // 初始化
            StudentService service = new StudentService();
            service.add(new Student("Andy", 90));
            service.add(new Student("Bill", 95));
            service.add(new Student("Cindy", 70));
            service.add(new Student("Dural", 85));
            service.add(new Student("Edin", 60));
            service.add(new Student("Felix", 55));
            service.add(new Student("Green", 15));

            // 60分及格篩選
            ClassifyRule rule60 = new ClassifyRule() {
                public String getKey() {
                    return student.getScore() >= 60 ? "及格" : "不及格";
                }

                public int getValue() {
                    return 1;
                }
            };

            System.out.println("60分及格篩選");
            printHt(service.getSum(rule60));

            // 50分及格篩選
            ClassifyRule rule50 = new ClassifyRule() {
                public String getKey() {
                    return student.getScore() >= 50 ? "及格" : "不及格";
                }

                public int getValue() {
                    return 1;
                }
            };

            System.out.println("\n50分及格篩選");
            printHt(service.getSum(rule50));

            // 分"優(yōu)良中差"等級
            ClassifyRule ruleCn = new ClassifyRule() {
                public String getKey() {
                    String retval = "";

                    int score = student.getScore();
                    if (score >= 90) {
                        retval = "優(yōu)";
                    } else if (score >= 80) {
                        retval = "良";
                    } else if (score >= 60) {
                        retval = "中";
                    } else if (score > 0) {
                        retval = "差";
                    }

                    return retval;
                }

                public int getValue() {
                    return 1;
                }
            };

    測試代碼

     System.out.println("\n分優(yōu)良中差等級篩選");
            printHt(service.getSum(ruleCn));

            // 分"ABCD"等級
            ClassifyRule ruleWest = new ClassifyRule() {
                public String getKey() {
                    String retval = "";

                    int score = student.getScore();
                    if (score >= 90) {
                        retval = "A";
                    } else if (score >= 80) {
                        retval = "B";
                    } else if (score >= 60) {
                        retval = "C";
                    } else if (score > 0) {
                        retval = "D";
                    }

                    return retval;
                }

                public int getValue() {
                    return 1;
                }
            };

            System.out.println("\n分ABCD等級篩選");
            printHt(service.getSum(ruleWest));
        }

        private static void printHt(Hashtable ht) {
            for (Iterator it = ht.keySet().iterator(); it.hasNext();) {
                String key = (String) it.next();
                Integer value = (Integer) ht.get(key);
                System.out.println("Key=" + key + " Value=" + value);
            }
        }
    }

    測試結(jié)果如下:

     

    60分及格篩選
    Key=及格 Value=5
    Key=不及格 Value=2

    50分及格篩選
    Key=及格 Value=6
    Key=不及格 Value=1

    分優(yōu)良中差等級篩選
    Key=優(yōu) Value=2
    Key=良 Value=1
    Key=中 Value=2
    Key=差 Value=2

    分ABCD等級篩選
    Key=A Value=2
    Key=D Value=2
    Key=C Value=2
    Key=B Value=1

    小結(jié)

    內(nèi)部類也叫嵌套類,一般不提倡書寫,但它在java核心類中都存在,如接口Map中的Entry,我們應(yīng)該了解并能解讀這種方法.

    匿名類相對而言有用得多,在解耦合和事件回調(diào)注冊中很常見,大家應(yīng)該對它的運(yùn)用融會貫通.

    posted @ 2008-02-21 20:03 和風(fēng)細(xì)雨 閱讀(265) | 評論 (0)編輯 收藏

    常用開發(fā)術(shù)語表

    Abstract class:抽象類
    Abstract method:抽象方法
    Annotation:注釋
    Anonymous class:匿名類
    API(Application Programming Interface):應(yīng)用編程接口,由方法和語言構(gòu)成的庫.
    ArrayList:實(shí)現(xiàn)了List接口的動態(tài)數(shù)組
    Assertion:斷言
    Atrribute map:屬性映射
    Autoboxing:自動裝箱,表示一個(gè)內(nèi)置類型如int和它的包裝類如Integer之間的自動轉(zhuǎn)換

    Boolean function:布爾函數(shù)
    Bytecode:字節(jié)碼

    Casting:類型強(qiáng)制轉(zhuǎn)換
    Channel:頻道
    ClassCastException:當(dāng)一個(gè)對象引用強(qiáng)制轉(zhuǎn)換程一個(gè)不兼容的類型時(shí)出現(xiàn)的異常.
    Collection:一個(gè)表示對象組或集合的接口
    CSV(Comma-separated values):一種用于存儲表格數(shù)據(jù)的文件形式
    Complier:編譯器
    Compose:合成
    Composite function:復(fù)合函數(shù),通過多個(gè)函數(shù)創(chuàng)建的一個(gè)函數(shù)

    Decimal:十進(jìn)制
    Deep:深度
    DOM(Document Object Model):文檔對象模型,一種采用樹形表示來處理XML數(shù)據(jù)的API.
    Database:數(shù)據(jù)庫

    Edge:邊
    Element:元素,XML文檔中的一個(gè)節(jié)點(diǎn).
    Encapsulation:封裝
    End tag:結(jié)束標(biāo)簽
    Enum:枚舉
    Escaping:轉(zhuǎn)義

    Function:函數(shù)
    Fuzzy search:模糊搜索

    Generic:泛型
    Graph:圖
    GUI:用戶圖形界面
    Grid computing:網(wǎng)格計(jì)算
    Group:組

    HashMap:一個(gè)將鍵值映射到值的查找對象
    Heap memory:堆內(nèi)存
    HTML(Hyper Text Markup Language):超文本標(biāo)記語言
    HTTP(HyperText Tranfer Protocol):超文本傳輸協(xié)議

    Inheritance:繼承
    Inner class:內(nèi)部類
    Iterator:允許迭代到任何Collection類的一個(gè)接口

    JDBC(Java Database Connectivity):java數(shù)據(jù)庫連接,一種屬于Java核心庫的用于操作關(guān)系數(shù)據(jù)庫的API.
    JDK(Java Development Kit):java開發(fā)工具包
    JRE(Java Runtime Environment):java運(yùn)行時(shí)環(huán)境
    JSP(Java Server Page):java服務(wù)頁
    JVM(Java Virtual machine):Java虛擬機(jī)
    JavaDoc:屬于JDK的一種文檔生成工具
    JavaScript:運(yùn)行于客戶端,用于HTML處理的一種輕量級教本語言,語法部分類似于Java.

    Layout:布局
    Lexical analysis:詞法分析
    Linked List:鏈表

    Matcher:一個(gè)用于正則表達(dá)式模式匹配的Java類
    Metadata:元數(shù)據(jù)
    Millisecond:微妙

    Namespace:命名空間
    Neural network:神經(jīng)網(wǎng)絡(luò)
    Node:節(jié)點(diǎn)

    Object-oriented programmming:面向?qū)ο缶幊?br /> Object pool:可以從中獲得對象的一個(gè)實(shí)例池
    Origin:原點(diǎn)
    Override:子類覆寫父類的方法

    Parser:分析器
    Patch:補(bǔ)丁
    Pattern:模式
    Polymorphism:多態(tài)性
    Port:端口
    Predicate:謂詞
    Prefix:前綴
    Procedural language:過程式語言,如C
    Property:屬性

    Real time:實(shí)時(shí)
    Recursive:遞歸
    Reference:引用
    Reflection:反射
    Regular expression:正則表達(dá)式
    Relative:相對
    Resource:資源
    Runnable:多線程編程使用的一個(gè)接口.

    Syntax:語法
    Screen scraping:屏幕抓取
    Split:分割
    State:狀態(tài)
    Static:靜態(tài)
    Sequence:序列
    Swing:構(gòu)建在AWT上更高級的圖形用戶界面
    Synchronized:同步,用于線程安全協(xié)作的技術(shù)

    Tag:標(biāo)簽
    Thread:進(jìn)程
    Tiger : Sun給Java1.5的代號
    Token:標(biāo)記
    Translation:平移
    Triple:三元組
    Type:類型

    Unicode:統(tǒng)一字符界面
    Unit testing:單元測試

    Visitor pattern:訪問者模式

    WAR(Web Application Archive):Web應(yīng)用程序歸檔
    Web Service:Web服務(wù)
    Weight:權(quán)
    Well-formed:格式良好的
    Whitespace:空白符

    XML(Extensible Markup Language):一種描述分級數(shù)據(jù)結(jié)構(gòu)的文本標(biāo)記語言

    posted @ 2008-02-21 19:57 和風(fēng)細(xì)雨 閱讀(307) | 評論 (1)編輯 收藏

    類的設(shè)計(jì)概述

    編寫程序前的設(shè)計(jì)與思考

    1.分析業(yè)務(wù),從業(yè)務(wù)流和業(yè)務(wù)規(guī)則中歸納出領(lǐng)域?qū)ο?這些對象一般放在src/com/yourname/domain下.
    2.根據(jù)業(yè)務(wù),考慮為領(lǐng)域?qū)ο筇峁┩暾姆?wù)需要那些服務(wù)類.這些對象一般放在src/com/yourname/service下.
    3.思考從輸入開始,到輸出結(jié)束,程序要運(yùn)行正常,服務(wù)類需要那些屬性和方法,這些成員代表什么意義具有什么價(jià)值,方法的參數(shù)的返回值分別是什么.
    4.思考要讓服務(wù)類為領(lǐng)域?qū)ο箢愄峁┩暾者m的服務(wù),領(lǐng)域?qū)ο箢愋枰鲈鯓拥恼{(diào)整,需要?dú)w納那些共同的基類.這里可以繪出領(lǐng)域類和服務(wù)類的靜態(tài)類圖協(xié)助思考.
    5.考慮還需要那些實(shí)用類來幫助實(shí)現(xiàn)程序.這些對象一般放在src/com/yourname/util下.
    6.在領(lǐng)域類和服務(wù)類的基礎(chǔ)上設(shè)計(jì)持久層,控制層和表現(xiàn)層(當(dāng)前階段暫時(shí)不會接觸).

    軟件設(shè)計(jì)的通用原則

    Domain first:先歸納程序的領(lǐng)域?qū)ο?歸納出來才清楚程序要做什么.
    Service second:其次歸納程序的服務(wù)對象,歸納出來才知道該怎么去做.
    前兩步完成后可以說設(shè)計(jì)已經(jīng)完成了大半.
    Persistence the third:再次再考慮數(shù)據(jù)如何持久化到持久層中,比如說數(shù)據(jù)庫表結(jié)構(gòu)的設(shè)計(jì).
    Presentation the last:最后考慮表現(xiàn)層的東西,比如說界面方案.

    現(xiàn)代軟件設(shè)計(jì)的核心-類的設(shè)計(jì)

    從上兩步可以看出,軟件設(shè)計(jì)其實(shí)就是類的設(shè)計(jì)工作,類設(shè)計(jì)的結(jié)果直接影響著軟件的方方面面,所謂持久層設(shè)計(jì),表現(xiàn)層設(shè)計(jì)都是類設(shè)計(jì)的泛化和深化,所以說類設(shè)計(jì)直接影響著軟件的興衰成敗.
    那么關(guān)于類設(shè)計(jì)的準(zhǔn)則和評價(jià)標(biāo)準(zhǔn)是什么呢?

    類設(shè)計(jì)的五條基本準(zhǔn)則

    單一職責(zé)原則(The single responsibility principle): 一個(gè)類有且只有一個(gè)中心目的,它為一個(gè)中心目的所設(shè)計(jì),只能因?yàn)橹行哪康南嚓P(guān)原因而改變.
    開放-封閉原則(The open-close principle):類高度內(nèi)聚,和其它類的耦合程度小,應(yīng)該可以在不改變類的情況下,改變類所在的環(huán)境.
    里斯科夫替換原則(The Liskov substitution principle):派生類的行為為基類所規(guī)定和限制,避免使派生類的方法非法化或者退化它們.基類的使用者不需要了解派生類就能正確的通過接口使用它們.
    依賴關(guān)系倒置原則(The dependecy inversion principle):基于抽象類和接口而不是具體的類形成設(shè)計(jì)構(gòu)架,因?yàn)槌橄箢惡徒涌谙鄬唧w類而言更不容易被改動.
    接口隔離原則(The interface segregation principle):給對象的每個(gè)使用者一個(gè)單獨(dú)的接口.其中只包含它們需要的方法,不要設(shè)計(jì)一個(gè)包含很多方法的接口讓不需要這些接口的類去實(shí)現(xiàn)它們.

    類的評價(jià)標(biāo)準(zhǔn)-抽象相關(guān)

    類是否有一個(gè)中心目的.
    類的命名是否恰當(dāng),其名字是否表現(xiàn)了其中心目的.
    類的接口是否展現(xiàn)了一致的抽象.
    類的接口是否讓人明白的知道該如何使用它.
    類的接口是否足夠抽象,是你能不必顧慮它是如何進(jìn)行服務(wù)的.
    類提供的服務(wù)是否足夠完整,能讓其它類無須了解動用其內(nèi)部結(jié)構(gòu).
    是否已經(jīng)去除無關(guān)信息.
    是否考慮過把類進(jìn)一步分解成組件類?是否已經(jīng)盡可能將其分解.
    再修改類時(shí)是否維持了其接口的完整性.

    類的評價(jià)標(biāo)準(zhǔn)--封裝相關(guān)

    是否把類成員的可訪問性降至最小.
    是否避免暴露類中的數(shù)據(jù)成員.
    類是否已經(jīng)盡可能的對其它類隱藏了實(shí)現(xiàn)細(xì)節(jié).
    類是否避免對其使用者,包括其派生類如何使用它做了假設(shè).
    類是否不依賴其它類,它是松耦合的嗎?

    典型的設(shè)計(jì)的臭味

    僵化性(Rigidiry):類之間耦合嚴(yán)重,系統(tǒng)幾乎很難改變,改變一處就不得不改動其它地方,甚至引起無休止的連鎖反應(yīng).
    易碎性(Fragility):改變系統(tǒng)的某個(gè)部分,會破壞許多完全無關(guān)的部分.這一般由不必要的語法結(jié)構(gòu)引起,如過度復(fù)雜的循環(huán)和分支.
    固化性(Immobility):很難將系統(tǒng)分解成可供其它系統(tǒng)使用的組件,細(xì)化不夠會引起這樣的問題.
    粘稠性(Viscosity):開發(fā)環(huán)境總是和輸入輸出和庫粘在一起.永遠(yuǎn)走不出編輯->編譯->測試這一無休止的循環(huán),分層不清晰會引起這樣的問題.
    不必要的復(fù)雜性(Needless Complexity):很多充滿著智慧的代碼結(jié)構(gòu)目前還不需要,但有一天可能會排上用場,喜歡事先考慮幽靈需求的程序員經(jīng)常給代碼帶來這樣的異味.
    不必要的重復(fù)(Needless Repetition): 系統(tǒng)充斥著重復(fù)代碼,看上去象只會VC大法(Ctrl+C,Ctrl+V)的程序員寫的,懶惰不思考是造成這個(gè)問題的根源.
    不透明性(Opacity):代碼不能體現(xiàn)創(chuàng)建人的意圖.

    何謂良好的設(shè)計(jì)

    設(shè)計(jì)良好的系統(tǒng)應(yīng)該容易理解,容易改變,容易重用.它實(shí)現(xiàn)起來沒有任何特殊的困難,簡明扼要而經(jīng)濟(jì).它不會散發(fā)出代碼臭味,公司樂于生產(chǎn)這樣的系統(tǒng),客戶樂于使用這樣的系統(tǒng),維護(hù)人員樂于維護(hù)這樣的系統(tǒng).

    設(shè)計(jì)良好的現(xiàn)代軟件特征

    最小的復(fù)雜度:整個(gè)系統(tǒng)可以分解為簡單而易于理解的各個(gè)部分.
    易于維護(hù):程序有良好的可維護(hù)性.
    松散耦合,通過應(yīng)用類接口中的合理抽象,封裝性以及信息隱藏等原則,設(shè)計(jì)出相互關(guān)聯(lián)盡可能最少的類.
    適應(yīng)變化: 能在不改變系統(tǒng)基本構(gòu)架的基礎(chǔ)上,適應(yīng)未來的變化,有良好的擴(kuò)展性,程序可擴(kuò)展,可重用.
    有明晰的層次,每層各司其職,有良好分工.
    高扇入低扇出:系統(tǒng)很好的利用了較低層次上的工具類,重復(fù)代碼很少或沒有.
    有良好的規(guī)范:無論多少人參與了項(xiàng)目,從代碼看來猶如出自一人之手.
    使用標(biāo)準(zhǔn)技術(shù).

    posted @ 2008-02-21 19:30 和風(fēng)細(xì)雨 閱讀(1539) | 評論 (0)編輯 收藏

    鏈表講解

    集合框架的繼承體系

    Java2中包含了6個(gè)集合接口,這些接口的通用目的實(shí)現(xiàn)類,以及一個(gè)集合實(shí)用類Collections,共同組成了集合框架的核心.
    6個(gè)集合接口如下:
    Collection及其以下的List,Set,以及Set下的SortedSet
    Map及其以下的SortedMap

    鏈表的通用實(shí)現(xiàn)

    ArrayList:線程不安全的動態(tài)數(shù)組類,批量查詢速度快,單個(gè)查找速度慢.
    Vector:線程安全的動態(tài)數(shù)組類,效率比ArrayList低下.
    LinkedList:動態(tài)鏈表類,適于在隊(duì)列首尾頻繁增刪成員的場合.

    鏈表的創(chuàng)建

    List<Member> ls=new ArrayList<Member>();// 1.5版本及以上

    List ls=new ArrayList();// 1.5版本以下

    之所以將ls類型指定為List<Member>而不是ArrayList<Member>是因?yàn)?如果情況變化, ArrayList需要修改成Vector或LinkedList時(shí)無須修改其它代碼,僅修改實(shí)例類型即可.

    向List中添加元素

    添加單個(gè)元素
    ls.add(new Member("Andy",21));

    從別的鏈表中添加多個(gè)元素
    List<Member> ls2=new ArrayList<Member>();
    ls2.add(new Member("Felex",21));
    ls2.add(new Member("Gates",23));
    ls.addAll(ls2);

    注意:
    1.5及其以上版本中,添加的元素必須和定義時(shí)一致,如ls的類型是List<Member>,那么向其中添加的元素必須是Member或其子類.
    1.5以下版本中,對添加的元素不作檢查,只要是Object即可,如果是基本類型則需裝箱成類類型.如ls.add(new Integer(8));

    刪除鏈表中元素

    ls.remove(member); // 直接刪除對象,member=new Member("Edin",28)
    ls.remove(2);           // 刪除第三個(gè)元素
    ls.clear();                // 將已有數(shù)據(jù)全部清除

    對鏈表進(jìn)行遍歷

    1) 1.5中獨(dú)有的遍歷方法,代碼最短,使用最方便
    for(Member member:ls){
         // member就是依次取出的每個(gè)元素
    }

    2) 常規(guī)方法,多用于需要取得下標(biāo)的場合,各版本均適用
    for(int i=0;i<ls.size();i++){
        Member member=ls.get(i);// member就是依次取出的每個(gè)元素, 1.5及其以上版本適用, ls.size()為鏈表長度
        Member member=(Member)ls.get(i);// 1.5以下版本適用
    }

    3) 使用Iterator對鏈表進(jìn)行遍歷的方法,各版本均適用
    for(Iterator it=ls.iterator();it.hasNext();){
        Member member=(Member)it.next();
    }

    鏈表的其它常用的方法

    ls.contains(Object o);// 返回鏈表中是否包含某元素
    ls.indexOf(Object o);// 返回對象o是鏈表中的第幾號元素
    isEmpty();// 返回鏈表中是否有元素

    對鏈表進(jìn)行排序
    1)讓List中元素必須已經(jīng)實(shí)現(xiàn)Comparable接口:
    public class Member implements Comparable {
      private String name;

      private int age;

      public Member(String name, int age) {
        this.name = name;
        this.age = age;
      }

      public int compareTo(Object obj) {
        Member another = (Member) obj;
        return this.name.compareTo(another.name);// 按名稱排序,如果是this.age-another.age則按年齡排序
      }
     
      public String toString(){
        return "Member name="+name+" age="+age;
      }
    }

    2)排序過程
    List<Member> ls=new ArrayList<Member>();

    ls.add(new Member("Felex",21));
    ls.add(new Member("Gates",23));
    ls.add(new Member("Andy",21));
    ls.add(new Member("Bill",23));
    ls.add(new Member("Cindy",24));
    ls.add(new Member("Dell",27));

    Collections.sort(ls);

    for(Member member:ls){
          System.out.println(member);
    }

    輸出:
    Member name=Andy age=21
    Member name=Bill age=23
    Member name=Cindy age=24
    Member name=Dell age=27
    Member name=Felex age=21
    Member name=Gates age=23

    // 如果需要逆序可以使用Collections.reverse(ls);

    鏈表與數(shù)組之間的轉(zhuǎn)換

    1) List轉(zhuǎn)換成數(shù)組
    List<String> ls=new ArrayList<String>();

    ls.add("Felex");
    ls.add("Gates");
    ls.add("Andy");
    ls.add("Bill");
    ls.add("Cindy");
    ls.add("Dell");

    Object[] arr=ls.toArray();
    for(Object obj:arr){
          System.out.println((Object)obj);
    }

    輸出為:
    Felex
    Gates
    Andy
    Bill
    Cindy
    Dell

    2) 數(shù)組轉(zhuǎn)換成List
    String[] arr={"Andy","Bill","Cindy","Dell"};
    List<String> ls=Arrays.asList(arr);
    for(String str:ls){
         System.out.println(str);
    }

    輸出:
    Andy
    Bill
    Cindy
    Dell

    posted @ 2008-02-21 19:26 和風(fēng)細(xì)雨 閱讀(484) | 評論 (0)編輯 收藏

    Hashtable基本用法概述

    Hashtable-哈希表類

    以哈希表的形式存儲數(shù)據(jù),數(shù)據(jù)的形式是鍵值對.
    特點(diǎn):
    查找速度快,遍歷相對慢
    鍵值不能有空指針和重復(fù)數(shù)據(jù)

    創(chuàng)建
    Hashtable<Integer,String> ht=new Hashtable<Integer,String>();

    添值

    ht.put(1,"Andy");
    ht.put(2,"Bill");
    ht.put(3,"Cindy");
    ht.put(4,"Dell");
    ht.put(5,"Felex");
    ht.put(6,"Edinburg");
    ht.put(7,"Green");

    取值

    String str=ht.get(1);
    System.out.println(str);// Andy

    對鍵進(jìn)行遍歷

    Iterator it = ht.keySet().iterator();

    while (it.hasNext()) {
        Integer key = (Integer)it.next();
        System.out.println(key);
    }

    對值進(jìn)行遍歷

    Iterator it = ht.values().iterator();

    while (it.hasNext()) {
        String value =(String) it.next();
        System.out.println(value);
    }

    取Hashtable記錄數(shù)

    Hashtable<Integer,String> ht=new Hashtable<Integer,String>();

    ht.put(1,"Andy");
    ht.put(2,"Bill");
    ht.put(3,"Cindy");
    ht.put(4,"Dell");
    ht.put(5,"Felex");
    ht.put(6,"Edinburg");
    ht.put(7,"Green");

    int i=ht.size();// 7

    刪除元素

    Hashtable<Integer,String> ht=new Hashtable<Integer,String>();

    ht.put(1,"Andy");
    ht.put(2,"Bill");
    ht.put(3,"Cindy");
    ht.put(4,"Dell");
    ht.put(5,"Felex");
    ht.put(6,"Edinburg");
    ht.put(7,"Green");

    ht.remove(1);
    ht.remove(2);
    ht.remove(3);
    ht.remove(4);

    System.out.println(ht.size());// 3


    Iterator it = ht.values().iterator();

    while (it.hasNext()) {
            // Get value
        String value =(String) it.next();
        System.out.println(value);
    }

    輸出:
    3
    Green
    Edinburg
    Felex

     

    posted @ 2008-02-21 19:20 和風(fēng)細(xì)雨 閱讀(13854) | 評論 (2)編輯 收藏

    接口與抽象類概述

    類,抽象類與接口

    類,抽象類與接口都是Java中實(shí)現(xiàn)繼承和多態(tài)的手段.
    類強(qiáng)調(diào)的是繼承
    接口強(qiáng)調(diào)的是規(guī)范
    抽象類兼而有之

    什么是接口

    接口是一種特殊的類,它只有方法定義而沒有實(shí)現(xiàn),實(shí)現(xiàn)的任務(wù)完全交給子類完成.
    接口以interface標(biāo)志.
    繼承接口用implements關(guān)鍵字實(shí)現(xiàn).
    接口可以繼承接口.
    接口可以有成員,但成員全是public static final類型的.
    接口沒有構(gòu)造函數(shù).
    接口給Java提供了多繼承機(jī)制

    接口例子—Knockable

    public interface Knockable{
            public static final String Sound="Bang!";
            public void knock();
    }

    接口例子-實(shí)現(xiàn)接口

    public class Hammer implements Knockable{
        public void knock(){
               System.out.println(Sound);
        }
    }

    接口例子-實(shí)現(xiàn)多個(gè)接口

    public interface Knockable{
        public static final String Sound="Bang!";
        public void knock();
    }

    public interface Clampable {
        public void clamp();
    }

    public class Pliers implements Knockable,Clampable{
       public void clamp(){
             // do sth
       }

       public void knock(){
            System.out.println(Sound);
       }
    }

    接口繼承接口例子

    public interface Knockable{
          public static final String Sound="Bang!";
          public void knock();
    }

    public interface Hitable extends Knockable{
          public void hit();
    }

    public class Stick implements Hitable{
          public void knock(){
              //  do sth
          }

          public void hit(){
              // do sth
          }
    }

    什么叫抽象類

    類中具有抽象方法的類為抽象類.抽象方法以abstract在函數(shù)前修飾,只有定義沒有實(shí)現(xiàn),這一點(diǎn)和接口一致.
    抽象類在類名前需加上abstract修飾符以標(biāo)識.
    抽象類不能生成實(shí)例.
    抽象類的繼承性和類一致.

    抽象類的實(shí)現(xiàn)

    public abstract class Gun{
      protected String cannon;
      protected List<Bullet> bullets;
       
      public abstract void shoot();
     
      public void addBullet(Bullet bullet){
        if(bullets==null){
          bullets=new LinkedList<Bullet>();
        }
       
        bullets.add(bullet);
      }
    }

    繼承抽象類

    public class Rifle extends Gun{
      public void shoot(){
        // Shoot Sth
      }
     
      public void reload(){
        if(bullets!=null){
          bullets.clear();
        }
       
        addBullet(new Bullet());
        addBullet(new Bullet());
        addBullet(new Bullet());
        addBullet(new Bullet());
        addBullet(new Bullet());
        addBullet(new Bullet());
      }
    }

    繼承抽象類并實(shí)現(xiàn)接口

    public abstract class Gun{
      protected String cannon;
      protected List<Bullet> bullets;
       
      public abstract void shoot();
     
      public void addBullet(Bullet bullet){
        if(bullets==null){
          bullets=new LinkedList<Bullet>();
        }
       
        bullets.add(bullet);
      }
    }

    public interface Thornable{
      public void thorn();
    }

    public class SpringFieldRifle extends Gun implements Thornable{
      public void thorn(){
        // thorn sth
      }
     
      public void shoot(){
        // shoot sth
      }
    }

    抽象類繼承抽象類實(shí)現(xiàn)接口的例子

    public abstract class Gun{
      protected String cannon;
      protected List<Bullet> bullets;
       
      public abstract void shoot();
     
      public void addBullet(Bullet bullet){
        if(bullets==null){
          bullets=new LinkedList<Bullet>();
        }
       
        bullets.add(bullet);
      }
    }

    public interface Handable{
      public void hold();
    }

    public abstract class HandGun extends Gun implements Handable{

    }

    public class BlackStar extends HandGun{
      public void hold(){
        // Hold the gun
      }
     
      public void shoot(){
        // Shoot Sth
      }
    }

    抽象類,接口,類的區(qū)別

    繼承好比家學(xué)淵源,所謂"忠厚傳家久,詩書繼世長",家長總會潛移默化的影響下一代,下一代也會在不經(jīng)意中學(xué)習(xí)前輩的特點(diǎn),但因?yàn)槟晟俜直婺芰Σ桓呒由鲜酪讜r(shí)移有些優(yōu)點(diǎn)已經(jīng)不再是有點(diǎn)甚至?xí)兂扇秉c(diǎn),下一代會把前輩的優(yōu)缺點(diǎn)不分良莠的繼承下來.這也是日后出現(xiàn)問題的根源.

    接口好比拜師學(xué)藝,"入了這個(gè)門,就得說這行話",比如相聲界說學(xué)逗唱四門是必須要學(xué)的,但是"師傅領(lǐng)進(jìn)門,修行在個(gè)人",學(xué)得怎么樣還全看自己,指望不費(fèi)力的繼承什么是不可能的,具體功夫還得個(gè)人來過. 因?yàn)槭亲约簛?具體實(shí)現(xiàn)成什么樣自由度也很大,比如四門功課中的"唱",原指唱太平歌詞,但因?yàn)閻勐牭纳?現(xiàn)在相聲演員已經(jīng)不要求這個(gè)了,改為唱歌唱戲的唱,其實(shí)嚴(yán)格界定的話是"學(xué)"的一種.這也無所謂對錯(cuò),郭德剛堅(jiān)持唱太平歌詞也行,笑林唱流行歌曲也不錯(cuò),總之實(shí)現(xiàn)了就可以,實(shí)現(xiàn)得怎么樣則留給實(shí)踐來檢驗(yàn).一個(gè)類可以同時(shí)實(shí)現(xiàn)多個(gè)接口,就和藝人拜幾個(gè)師傅是沒有問題的,郭德剛就同時(shí)實(shí)現(xiàn)了大鼓和相聲兩個(gè)接口.

    抽象類則介于繼承和接口之間,既可不費(fèi)力的從上一代繼承,也可強(qiáng)制實(shí)現(xiàn)某接口,有如某大師收自己的孩子為徒,當(dāng)然相聲界不讓這么干,其它曲藝行業(yè)還是可以的,比如京劇界的梅蘭芳和其子梅葆玖,既有言傳身教,也有強(qiáng)制實(shí)現(xiàn),綜合了繼承和接口的特點(diǎn).

    抽象類,接口,類的詳細(xì)區(qū)別

    接口 抽象類
    可以繼承自 接口 抽象類,類 抽象類,類
    可以實(shí)現(xiàn)自 一個(gè)或多個(gè)接口 一個(gè)或多個(gè)接口
    有否成員 只有static final成員 均可 均可
    是否有構(gòu)造函數(shù)
    可否實(shí)例化 不可 不可
    意圖 規(guī)范行為 繼承成員+規(guī)范行為 繼承成員


    抽象類,接口和類在繼承體系中的位置

    抽象類,接口一般來說都是從一般類總結(jié)歸納出來的抽象共性的東西,類則是實(shí)際具體的東西.
    一般來說,應(yīng)該把合理抽象出的抽象類,接口放在類繼承體系的上層,子類依靠類來實(shí)現(xiàn).

    posted @ 2008-02-21 19:09 和風(fēng)細(xì)雨 閱讀(458) | 評論 (0)編輯 收藏

    僅列出標(biāo)題
    共10頁: First 上一頁 2 3 4 5 6 7 8 9 10 
    主站蜘蛛池模板: 一级毛片免费一级直接观看| 久久综合国产乱子伦精品免费| 亚洲一区二区高清| 国产成年无码久久久免费| 亚洲卡一卡2卡三卡4麻豆| 亚洲成av人在片观看| 人妻丰满熟妇无码区免费 | 红杏亚洲影院一区二区三区 | 国产亚洲精品成人AA片新蒲金| 三年片在线观看免费观看大全一| 亚洲一区中文字幕在线观看| 久久亚洲国产精品123区| 永久黄色免费网站| 香蕉视频在线观看免费| 亚洲综合无码一区二区三区| 免费在线观看黄网站| h视频在线免费看| 一个人看www免费高清字幕| 亚洲国产成人久久综合一区| 精品亚洲成α人无码成α在线观看 | 亚洲国产区男人本色在线观看| 中文字幕中韩乱码亚洲大片| 免费观看AV片在线播放| 在线看片免费人成视频播| 相泽南亚洲一区二区在线播放| 精品亚洲aⅴ在线观看| 亚洲性久久久影院| 免费精品一区二区三区在线观看| 一区二区三区四区免费视频 | 亚洲成年网站在线观看| 亚洲AV无码AV男人的天堂| 国产成人啪精品视频免费网| 最近2019免费中文字幕6| 巨胸喷奶水视频www免费视频| 亚洲综合色婷婷在线观看| 亚洲三级电影网站| 永久亚洲成a人片777777| 在线观看亚洲免费视频| 97在线线免费观看视频在线观看| 一级毛片在线免费观看| 99麻豆久久久国产精品免费|