介面體現的是一種規範和實現分離的設計哲學,充分利用介面可以極好地降低程式各模組之間的耦合性,從而提高系統的可擴充性和可維護性。
下面我們來介紹Java面向介面編程之簡單原廠模式
有一個情境:假設程式中有個computer類需要組合一個輸出裝置。
computer類:需要初始化一個輸出裝置,把需要列印的東西傳遞到輸出裝置,輸出要列印的東西。
package fang;public class Computer {private Output out;public Computer (Output out) {this.out= out;}public void keyIn(String msg) {out.getData(msg);}public void print() {out.out();}}
Output介面:串連computer類和輸出裝置(如印表機等等)的介面。computer通過Output介面傳入要列印的東西(getData())和輸出要列印的東西(out())。
package fang;public interface Output {int MAX_CACHE_LINE = 50;void out();void getData(String msg);//default void print(String ... msgs) {//for(String msg: msgs) {//System.out.println(msg);//}//}//default void test() {//System.out.println("the default test");//}////This static method of interface Output can only be accessed as Output.staticTest//static String staticTest() {//System.out.println("static staticTest in interFace");//return "static staticTest in interFace";//}//private void foo() {//System.out.println("private foo");//}//private static void bar() {//System.out.println("bar private static");//}}
OutputFactory類:(先看代碼,我們再分析)
package fang;public class OutputFactory {public Output getOutput() {return new Printer();}public static void main(String[] args) {OutputFactory of = new OutputFactory();Computer c = new Computer(of.getOutput());c.keyIn("高等數學");c.keyIn("機率論與數理統計");c.print();}}
它其實重要的代碼就是getOutput()這個函數,因為它返回的是一個列印裝置的執行個體。
如果我們想給computer類加上的是Printer(),那麼getOutput()返回的就是Printer;
如果我們想給computer類加上的是BetterPrinter(),那麼getOutput()返回的就是BetterPrinter。
Printer類:
package fang;interface Product{int getProductTime();}public class Printer implements Output,Product{private String[] printData = new String [MAX_CACHE_LINE];private int dataNum=0;public void out() {while(dataNum>0) {System.out.println("印表機列印工作: "+printData[0]);System.arraycopy(printData, 1, printData, 0, --dataNum); }}public void getData(String msg) {if(dataNum>= MAX_CACHE_LINE) {System.out.println("輸出隊列已滿,添加失敗");}else {printData[dataNum++]= msg;//System.out.println(dataNum);}}public int getProductTime() {return 45;}//public static void main(String []args)//{//Output o = new Printer();//o.getData("大學數學");//o.getData("大學物理");//o.out();//Output.staticTest();//o.getData("機率論與數理統計");//o.getData("複變函數");//o.out();//o.print("孫悟空","豬八戒","唐僧");//o.test();//Product p= new Printer();//System.out.println(p.getProductTime());//Object obj = p;//}}
BetterPrinter類:
package fang;public class BetterPrinter implements Output {private String[] printData = new String [MAX_CACHE_LINE*2];private int dataNum=0;public void out() {while(dataNum>0) {System.out.println("高速印表機正在列印: "+printData[0]);System.arraycopy(printData, 1, printData, 0, --dataNum); }}public void getData(String msg) {if(dataNum>= MAX_CACHE_LINE*2) {System.out.println("輸出隊列已滿,添加失敗");}else {printData[dataNum++]= msg;//System.out.println(dataNum);}}}
運行結果:
情況一:OutputFactory輸出的是Printer裝置,列印結果見下:
印表機列印工作: 高等數學印表機列印工作: 機率論與數理統計
情況二:OutputFactory輸出的是BetterPrinter裝置,列印結果見下:
高速印表機正在列印: 高等數學高速印表機正在列印: 機率論與數理統計
通過這種方式,即可把所有產生Output對象的邏輯集中在OutputFactory工廠類中管理,而所有需要使用Output對象的類,只需要與Output介面耦合,而不是與其具體的實作類別耦合。即使系統中有很多類使用了Printer對象,只要OutputFactory類的getOutput()方法產生的Output對象是BetterPrinter對象,則它們全部都會改為使用BetterPrinter對象,而所有程式無需修改,只需要修改OutputFactory工廠類的getOutput()方法實現即可。