天天看點

接口與設計模式

          Java接口是一系列方法的聲明,是一些方法特征的集合,一個接口隻有方法的特征沒有方法的實作,是以這些方法可以在不同的地方被不同的類實作,而這些實作可以具有不同的行為(功能)。

           接口展現了規範與實作分離的設計哲學,面向接口的設計模式也日益深入人心,下面提供了幾個完整的例子,示範了接口的優秀設計,并介紹了java常用的兩種設計模式:工廠模式和指令模式。

          筆者的開發環境為:java version "1.8.0_40"

 1.

//輸出裝置接口
public interface OutputSet
{
	//接口的成員變量隻能是常量
	int MAT_CACHE=50; //最大緩存
	
	//接口定義的普通方法隻能是public的抽象方法
	void out();
	void getData(String msg);
	//在接口中定義預設方法,需要default修飾--需要至少java8的版本支援
	default void print(String...msgs)
	{
		for(String msg : msgs)
			System.out.println(msg);
	}
	//在接口中定義類方法,需要static修飾--需要至少java8的版本支援
	static String type()
	{
		return " 标準輸出裝置 ";
	}
}
           

2.

//産品接口
public interface Product
{
	int getProduceTime();
}
           

3.至此,可以運作下面的類進行測試:

//列印機類  筆者測試環境:java version "1.8.0_40"
public class Printer implements OutputSet,Product
{
	public static void main(String[] args)
	{
	
		OutputSet out=new Printer();
		out.getData("第1張需要列印的檔案");
		out.getData("第2張需要列印的檔案");
		out.out();
		out.getData("第3張需要列印的檔案");
		out.getData("第4張需要列印的檔案");
		out.getData("第5張需要列印的檔案");
		out.getData(OutputSet.type());
		out.out();
		
	}
	private String[] printData=new String[MAT_CACHE];
	private int printNum=0;
	public void out()
	{
		while(printNum>0)
		{
			System.out.println("列印機列印:"+printData[0]);
			//把作業隊列整體前移一位,并将剩下的需要列印數字減1
			/*
			System.arraycopy方法
			public static void arraycopy
								(Object src,int srcPos,Object dest,int destPos, int length)
		    從指定源數組中複制一個數組,複制從指定的位置開始,到目标數組的指定位置結束。
			參數:
				src - 源數組。
				srcPos - 源數組中的起始位置。
				dest - 目标數組。
				destPos - 目标資料中的起始位置。
				length - 要複制的數組元素的數量。 
			*/
			System.arraycopy(printData,1,printData,0,--printNum);
		}
	}
	//重寫被實作接口的預設方法
	public void getData(String msg)
	{
		if(printNum>MAT_CACHE)
		{
			System.out.println("輸出隊列已滿,添加失敗!");
		}
		else
		{
			printData[printNum++]=msg;
		}
	}
	public int getProduceTime()
	{
		return 10;
	}
}
           

4.

/*
	面向接口程式設計--簡單工廠模式
	接口展現了規範與實作分離的設計哲學。
*/
//計算機類:需要添加輸出裝置,已經實作了與Printer類的松耦合,隻是與OutputSet接口耦合
public class Computer
{
	private OutputSet out;
	public Computer(OutputSet o)
	{
		out=o;
	}
	//模拟擷取輸入的方法
	public void keyin(String msg)
	{
		out.getData(msg);
	}
	//模拟列印方法
	public void print()
	{
		out.out();
	}
}
           

5.至此,可以運作下面的類測試工廠模式:

//工廠類負責生成OutputSet對象
public class OutputSetFactory
{
	public OutputSet getOutputSet()
	{
		//需要為電腦更新裝置時,隻需要在工廠類裡更改方法(改進工藝)即可
		return new Printer();
		//return new BetterPrinter();
	}
	public static void main(String[] args)
	{
		OutputSetFactory of=new OutputSetFactory();
		Computer c=new Computer(of.getOutputSet());
		c.keyin("計算機輸入1");
		c.keyin("計算機輸入2");
		c.keyin("計算機輸入3");
		c.print();
	}
}
           

6.加入下面的類,隻需更改工廠類裡的一個方法即可(詳見工廠類注釋)

//更好的列印機類  筆者測試環境:java version "1.8.0_40"
public class BetterPrinter implements OutputSet,Product
{
	private String[] printData=new String[MAT_CACHE];
	private int printNum=0;
	public void out()
	{
		while(printNum>0)
		{
			System.out.println("更好的列印機列印:"+printData[0]);
			System.arraycopy(printData,1,printData,0,--printNum);
		}
	}
	//重寫被實作接口的預設方法
	public void getData(String msg)
	{
		if(printNum>MAT_CACHE)
		{
			System.out.println("輸出隊列已滿,添加失敗!");
		}
		else
		{
			printData[printNum++]=msg;
		}
	}
	public int getProduceTime()
	{
		return 10;
	}
}
           

下面是指令模式

7.

//面向接口程式設計--簡單指令模式
//操作int數組的接口
public interface Command
{
	//封裝“處理行為的方法”
	void process(int[] target);
}
           

8.

//處理數組的處理類
public class ProcessArray
{
	public void process(int[] target,Command cmd)
	{
		cmd.process(target);
	}
}
           

9.

//列印數組的操作類
public class PrintCommand implements Command
{
    public void process(int[] target)
    {
        for(int tar : target)
            System.out.println("疊代輸出目标數組"+tar);
    }

}
           

10.

//擷取數組元素和的操作類
public class AddCommand implements Command
{
    public void process(int[] target)
    {
        int sum=0;
        for(int tar : target)
            sum+=tar;
        System.out.println("數組元素和"+sum);
    }
}

           

11.至此可以測試指令模式:

//測試類
public class CommandTest
{
    public static void main(String[] args)
    {
        ProcessArray pa=new ProcessArray();
        int[] target={5,0,8,10};
        pa.process(target,new PrintCommand());
        pa.process(target,new AddCommand());
    }
}
           

繼續閱讀