1. 程式人生 > >JAVA面向介面程式設計

JAVA面向介面程式設計


1.介面的概念:java中,介面是一個特殊的抽象類,接口裡面的所有方法都是抽象方法,所有屬性都是常量。只定義了方法,但是沒有方法的具體實現。
2.介面的思想:介面的思想是指將外部的呼叫和內部的實現隔離開來,也就是“封裝隔離”
3.介面的好處:因為介面將外部的呼叫和內部的實現隔離開來,所以當改變內部的但是沒有改變介面,這樣就不會對外部的應用有所影響。讓系統變得更加靈活。
往常,在使用介面的時候會建立一個實現類的例項,將其賦值給介面物件
Api api = new Impl();
這樣與面向介面程式設計的思想相違背,因為使用者在呼叫的時候,不僅知道介面是Api,而且還知道實現類是Impl。而介面的思想是“封裝隔離”,使用者應該是隻知道介面而不知道具體的實現類。
而把new Impl()去掉的時候又無法得到介面物件,所以為了解決這個問題,我們用到了簡單工廠。

簡單工廠
1.簡單工廠的定義:提供一個建立物件例項的功能,而無需關心其具體實現。被建立例項的型別可以是介面,抽象類,也可以是具體的類。
2.簡單工廠的思路:在模組內部建造一個類,這個類專門用來建立介面,然後把建立好的介面返回給客戶端,這樣外部應用可以通過這個類來得到相應的介面物件。

/*
定義一個介面
*/
public interface Api{
    public void func();
}

/*
定義一個實現類
*/
public class Impl implements Api{
    public void func(){
        System.out.println("這是一個實現類");
    }
}

/*
建立一個工廠類
*/
public class Factory{
    public static Api createApi(){
        return new Impl();
    }
}

/*
客戶端
*/
public class Client{
    public static void main(String[] args){
        Api api = Factory.createApi();
        api.func();
    }
}


問題:如果我們一個介面有多個實現類,或者在原有的基礎上新增了一個實現類,那麼就需要去修改工廠類的createApi方法,這樣也是很不方便。
解決方法:使用配置檔案
使用最簡單的配置檔案:定義一個名稱為“Factory.properties”的配置檔案,放在和Factory同一包下,內容是ImplClass=com.api.Impl
工廠類的實現改成:
/**
* 工廠類,用來創造Api物件
*/  
public class Factory {  
/**
 * 具體的創造Api的方法,根據配置檔案的引數來建立介面
 * @return 創造好的Api物件
 */  
public static Api createApi(){  
    //直接讀取配置檔案來獲取需要建立例項的類  
    //至於如何讀取Properties,還有如何反射這裡就不解釋了  
    Properties p = new Properties();  
    InputStream in = null;  
    try {  
        in = Factory.class.getResourceAsStream("Factory.properties");  
        p.load(in);  
    } catch (IOException e) {  
        System.out.println("裝載工廠配置檔案出錯了,具體的堆疊資訊如下:");  
        e.printStackTrace();  
    }finally{  
        try {  
            in.close();  
        } catch (IOException e) {  
            e.printStackTrace();  
        }  
    }  
    //用反射去建立,那些例外處理等完善的工作這裡就不做了  
    Api api = null;  
    try {  
        api = (Api)Class.forName(p.getProperty("ImplClass")).newInstance();  
    } catch (InstantiationException e) {  
        e.printStackTrace();  
    } catch (IllegalAccessException e) {  
        e.printStackTrace();  
    } catch (ClassNotFoundException e) {  
        e.printStackTrace();  
    }  
    return api;  
}  
}