Java程序的設計思想

**

Java程序的設計思想

**

設計思想的基本原則:

1、面向接口編程
2、優先使用對象組合而非繼承
3、分層結構
4、層之間交互的基本原則

重點內容

一、 面向接口編程

接口及相關機制最基本的作用:通過接口可以實現不相關類的相同行爲,而不需要考慮這些類之間的層次關係。根據接口可以瞭解對象的交互界面,而不需要了解對象所屬的類。
面向對象程序設計講究“提高內聚,鬆散耦合”,那麼不同的程序模塊怎麼相互訪問呢,就是通過接口,也就是接口是各部分對外的統一外觀。接口在Java程序設計中體現的思想就是封裝隔離,因爲接口只是描述一個統一的行爲,所以開發人員在面向接口編程時並不關心具體的實現。
內聚就是指組件所有功能儘量在內部實現,所需要的功能儘量在內部都能夠找到,即使是小到一個類也一樣,一個方法所需要的其它方法儘量在該類內部都實現了。
耦合是指組件之間的橫向聯繫,即一個組件要使用別的組件的功能。此時,如果別的組件修改了,那麼當前組件也要進行修改。當然,我們也不可能把所有的功能都在內部實現,跟外部完全沒有任何交互(除非只寫一個HelloWorld)。類的設計有一個原則,就是類的功能要單一(不能把所有的功能都寫在一個類中)。因此,這兩者間要進行權衡。這樣,一個組件在設計時肯定是要和其它組件耦合的,爲了減少耦合時產生的連動影響同時又要保持內聚性,採用面向接口編程是比較合理的解決方案,接口體現的“封裝隔離”的設計思想,其中的封裝就是提高內聚,而隔離就是減少耦合。組件中設計時,內部實現都封裝隱藏起來,對外只提供接口(如果組件修改了,只要接口沒變,使用該組件的其它組件就不用修改。一方面讓組件間的耦合鬆散了,另一方面也實現對組件內部實現的封裝)。

接口本身不會增加程序的功能(因爲它沒有實現代碼),但是採用接口可以讓整個程序的體系結構更加靈活,它的作用不要體現在體系結構設計上,使用程序更容易擴展。
這裏寫圖片描述

二、分層

① 表現層功能:展示數據、人機交互、收集參數調用邏輯層。
② 邏輯層功能:進行數據的邏輯校驗、進行邏輯判斷、實現業務功能、處理相關功能、處理後續流程、組織數據返回給表現層。
③ 數據層功能:實現數據持久化、實現對象和持久化數據的雙向映射。
這裏寫圖片描述

設計模式

單例

餓漢式 
不管是否已經生成,先new一個:

class Single{
    private static final Single s = new Single();
    private Single(){
            }
    public static Single getInstance(){
        return s;
    }
}

懶漢式
先判斷是否爲null,沒有再new

class Single2 {
    private static Single2 s = null;
    private Single2(){
            }
    public static Single2 getInstance() {//可以在此處添加synchronized,確保線程安全
        if(s==null)
            s=new Single2();
        return s;
    }
}

緩存在單例中的使用

//單例+緩存---控制池大小,每個對象的key值由該類內部指定

public class A {
    //1創建一個單例的池
    private static Map<Integer, A> pool = new HashMap<Integer, A>(); //池--集合:  Map:key-value

    //當前對象的序號
    private static int num=0;

    //總數量
    private final static int MAX_SIZE=3;

    public synchronized static A getInstance(){
        //2根據num到池中去獲取obj
        A obj = pool.get(num);
        if(obj==null){
            obj = new A();
            pool.put(num, obj);
        }
        num = (num+1)%MAX_SIZE;  //範圍: 0 ~ MAX_SIZE-1
        //3如果該obj存在則返回,否則創建一個新的放入池中並返回
        return obj;
    }

}

值對象

基本的編寫步驟
第1步:寫一個類,實現可序列化(如果以後數據是往數據庫裏存的,那麼可以不序列化,節省資源)
第2步:私有化所有屬性,保持一個默認構造方法(public無參)
第3步:爲每個屬性提供get()、set()方法(如果是boolean型變量,最好把get改成is)
第4步:推薦覆蓋實現equals()、hashCode()和toString()方法
值對象的本質是“封裝數據”

裝飾模式

在不對原有對象類進行修改的基礎上,給一個或多個已有的類對象提供增強額外的功能。
以MyBufferedReader爲例
版本1


/*
 *增強FileReader類,使它具有如下功能:
 * (1) 提供帶緩衝的myRead()方法,對原有的read()方法進行增速;
 (2)提供一個能夠每次讀取一行字符的myReadLine()方法。
 */
public class MyBufferedReader {
    private char[] cbuf = new char[1024];// 緩存
    private int pos = 0; // 當前讀取的位置
    private int count = 0;// 記錄緩存中當前的字符總數
    // 封裝一個FileReader對象,幫助我們實現從文件中讀取一批數據
    private FileReader r = null;
    public MyBufferedReader(FileReader r) {
        super();
        this.r = r;
    }
    /*
     * 從緩存中讀取一個字符數據返回
     * 所讀取的字符,如果到達文件末尾則返回-1
     */
    public int myRead() throws IOException {
        // 從文件中把數據讀取到緩存buf[]中
        if (count <= 0) {
            // System.out.println("**********");
            count = r.read(cbuf);
            if (count == -1) {
                return -1;
            }
            pos = 0;
        }
        char ch = cbuf[pos];
        pos++;
        count--;
        return ch;
    }
    // 回車字符: \r 13
    // 換行字符: \n 10
    public String myReadLine() throws IOException {
        StringBuilder sb = new StringBuilder();
        int ch = 0;
        // 有回車換行符部分
        while ((ch = myRead()) != -1) {
            if (ch == '\r') {
                continue;
            }
            if (ch == '\n') {
                return sb.toString();
            }
            sb.append((char) ch);
        }
        if (sb.length() != 0) {// 最後一行(沒有回車換行符)
            return sb.toString();
        }
        return null;// 最後或空文件
    }

    public void close() throws IOException {
        r.close();
    }
}

版本2

/* 版本2: 增強InputStreamReader類,使它具有:
 * (1) 提供帶緩衝的myRead()方法,對原有的read()方法進行增速;
   (2)提供一個能夠每次讀取一行字符的myReadLine()方法。
 */
public class MyBufferedReader {
    private char[] cbuf= new char[1024];//緩存
    private int pos=0; //當前讀取的位置
    private int count=0;//記錄緩存中當前的字符總數
    //封裝一個InputStreamReader對象,幫助我們實現從文件中讀取一批數據
    private InputStreamReader r = null; //★1★
    public MyBufferedReader(InputStreamReader r) { //★2★
        super();
        this.r = r;
    }
    /*
     * 從緩存中讀取一個字符數據返回
     * 所讀取的字符,如果到達文件末尾則返回-1
     */
    public int myRead() throws IOException{
        //從文件中把數據讀取到緩存buf[]中
        if(count<=0){
            //System.out.println("**********");
            count = r.read(cbuf);
            if(count==-1){
                return -1;
            }
            pos=0;
        }
        char ch = cbuf[pos];
        pos++;
        count--;
        return ch;
    }
    //回車字符: \r  13
    //換行字符: \n  10
    public String myReadLine() throws IOException{
        StringBuilder sb=new StringBuilder();
        int ch=0;
        //有回車換行符部分
        while( (ch=myRead())!=-1){ 
            if(ch=='\r'){
                continue;
            }
            if(ch=='\n'){
                return sb.toString();
            }
            sb.append((char)ch);
        }
        if(sb.length()!=0){//最後一行(沒有回車換行符)
            return sb.toString();
        }
        return null;//最後或空文件
    }
    public void close() throws IOException{
        r.close();
    }
}

版本3

/*
 * 同時增強FileReader、InputStreamReader和PipedReader類,使它具有:
 * (1) 提供帶緩衝的myRead()方法,對原有的read()方法進行增速;
 (2)提供一個能夠每次讀取一行字符的myReadLine()方法。
 */
public class MyBufferedReader extends Reader { // ★3★ ---
    private char[] cbuf = new char[1024];// 緩存
    private int pos = 0; // 當前讀取的位置
    private int count = 0;// 記錄緩存中當前的字符總數
    // 封裝一個Reader對象,幫助我們實現從文件中讀取一批數據
    private Reader r = null; // ★1★
    public MyBufferedReader(Reader r) { // ★2★
        super();
        this.r = r;
    }
    /* 從緩存中讀取一個字符數據返回
     * 所讀取的字符,如果到達文件末尾則返回-1
     */
    public int myRead() throws IOException {
        // 從文件中把數據讀取到緩存buf[]中
        if (count <= 0) {
            // System.out.println("**********");
            count = r.read(cbuf);
            if (count == -1) {
                return -1;
            }
            pos = 0;
        }
        char ch = cbuf[pos];
        pos++;
        count--;
        return ch;
    }
    // 回車字符: \r 13
    // 換行字符: \n 10
    public String myReadLine() throws IOException {
        StringBuilder sb = new StringBuilder();
        int ch = 0;
        // 有回車換行符部分
        while ((ch = myRead()) != -1) {
            if (ch == '\r') {
                continue;
            }
            if (ch == '\n') {
                return sb.toString();
            }
            sb.append((char) ch);
        }
        if (sb.length() != 0) {// 最後一行(沒有回車換行符)
            return sb.toString();
        }
        return null;// 最後或空文件
    }
    public void close() throws IOException {
        r.close();
    }
    @Override
    public int read(char[] cbuf, int off, int len) throws IOException {
        int num = 0;
        int ch = myRead();
        if (ch == -1) {
            return -1;
        }
        for (int i = off; i < len; i++) {
            num++;
            cbuf[i] = (char) ch;
            ch = myRead();
            if (ch == -1) {
                break;
            }
        }
        return num;
    }
}

這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章