工厂模式 java场景_研磨设计模式之简单工厂模式(场景问题)
簡單工廠不是一個標準的設計模式,但是它實在是太常用了,簡單而又神奇,所以還是需要好好掌握的,就當是對學習設計模式的熱身運動吧。為了保持一致性,我們盡量按照學習其它模式的步驟來進行學習。
1 ?場景問題
大家都知道,在Java應用開發中,要“面向接口編程”。
那么什么是接口?接口有什么作用?接口如何使用?一起來回顧一下:
1.1 ?接口回顧
(1)Java中接口的概念
在Java中接口是一種特殊的抽象類,跟一般的抽象類相比,接口里面的所有方法都是抽象方法,接口里面的所有屬性都是常量。也就是說,接口里面是只有方法定義而不會有任何方法實現。
(2)接口用來干什么 ? ? ? ?通常用接口來定義實現類的外觀,也就是實現類的行為定義,用來約束實現類的行為。接口就相當于一份契約,根據外部應用需要的功能,約定了實現類應該要實現的功能,但是具體的實現類除了實現接口約定的功能外,還可以根據需要實現一些其它的功能,這是允許的,也就是說實現類的功能包含但不僅限于接口約束的功能。
通過使用接口,可以實現不相關類的相同行為,而不需考慮這些類之間的層次關系,接口就是實現類對外的外觀。
(3)接口的思想
根據接口的作用和用途,濃縮下來,接口的思想就是“封裝隔離”。
通常提到封裝是指對數據的封裝,但是這里的封裝是指“對被隔離體的行為的封裝”,或者是“對被隔離體的職責的封裝”;而隔離指的是外部調用和內部實現,外部調用只能通過接口進行調用,而外部調用是不知道內部具體實現的,也就是說外部調用和內部實現是被接口隔離開的。
(4)使用接口的好處 ? ? ? ?由于外部調用和內部實現被接口隔離開了,那么只要接口不變,內部實現的變化就不會影響到外部應用,從而使得系統更靈活,具有更好的擴展性和可維護性,這也就是所謂“接口是系統可插拔性的保證”這句話的意思。
(5)接口和抽象類的選擇
既然接口是一種特殊的抽象類,那么在開發中,何時選用接口,何時選用抽象類呢?
對于它們的選擇,在開發中是一個很重要的問題,特別總結兩句話給大家:優先選用接口
在如下情況應選擇抽象類:既要定義子類的行為,又要為子類提供公共的功能
1.2 ?面向接口編程
面向接口編程是Java編程中的一個重要原則。
在Java 程序設計里面,非常講究層的劃分和模塊的劃分。通常按照三層來劃分Java程序,分別是表現層、邏輯層、數據層,它們之間都要通過接口來通訊。
在每一個層里面,又有很多個小模塊,一個小模塊對外也應該是一個整體,那么一個模塊對外也應該提供接口,其它地方需要使用到這個模塊的功能,都應該通過此接口來進行調用。這也就是常說的“接口是被其隔離部分的外觀”。基本的三層結構如圖1所示:
圖1 ?基本的三層結構示意圖
在一個層內部的各個模塊交互也要通過接口,如圖2所示:
圖2 ?一個層內部的各個模塊交互示意圖
各個部分的接口具體應該如何去定義,具體的內容是什么,不去深究,那是需要具體問題具體分析的,這里只是來學習設計的方法。
上面頻頻提到“組件”,那么什么是組件呢?先簡單的名詞解釋一下:
所謂組件:從設計上講,組件就是能完成一定功能的封裝體。小到一個類,大到一個系統,都可以稱為組件,因為一個小系統放到更大的系統里面去,也就當個組件而已。事實上,從設計的角度看,系統、子系統、模塊、組件等說的其實是同一回事情,都是完成一定功能的封裝體,只不過功能多少不同而已。
繼續剛才的思路,大家會發現,不管是一層還是一個模塊或者一個組件,都是一個被接口隔離的整體,那么下面我們就不去區分它們,統一認為都是接口隔離體即可,如圖3所示:
圖3 ?接口隔離體示意圖
既然在Java中需要面向接口編程,那么在程序中到底如何使用接口,來做到真正的面向接口編程呢?
1.3 ?不用模式的解決方案
回憶一下,以前是如何使用接口的呢,假設有一個接口叫Api,然后有一個實現類Impl實現了它,在客戶端怎么用這個接口呢?
通常都是在客戶端創建一個Impl的實例,把它賦值給一個Api接口類型的變量,然后客戶端就可以通過這個變量來操作接口的功能了,此時具體的結構圖如圖4:
圖4 ?基本的接口和實現
還是用代碼來說明,會更清楚一些。
(1)先定義接口Api,示例代碼如下:
Java代碼/**
* 某個接口(通用的、抽象的、非具體的功能)
*/
public interface Api {
/**
* 某個具體的功能方法的定義,用test1來演示一下。
* 這里的功能很簡單,把傳入的s打印輸出即可
* @param s 任意想要打印輸出的字符串
*/
public void test1(String s);
}
(2)既然有了接口,自然就要有實現,定義實現Impl,示例代碼如下:
Java代碼/**
* 對接口的實現
*/
public class Impl implements Api{
public void test1(String s) {
System.out.println("Now In Impl. The input s=="+s);
}
}
(3)那么此時的客戶端怎么寫呢?
按照Java的知識,接口不能直接使用,需要使用接口的實現類,示例代碼如下:
Java代碼/**
* 客戶端:測試使用Api接口
*/
public class Client {
public static void main(String[] args) {
Api api = new Impl();
api.test1("哈哈,不要緊張,只是個測試而已!");
}
}
1.4 ?有何問題
上面寫得沒錯吧,在Java的基礎知識里面就是這么學的,難道這有什么問題嗎?
請仔細看位于客戶端的下面這句話:
Java代碼Api api = new Impl();
然后再想想接口的功能和思想,發現什么了?仔細再想想?
你會發現在客戶端調用的時候,客戶端不但知道了接口,同時還知道了具體的實現就是Impl。而接口的思想是“封裝隔離”,而Impl這個實現類,應該是被接口Api封裝并同客戶端隔離開的,也就是說,客戶端根本就不應該知道具體的實現類是Impl。
有朋友說,那好,我就把Impl從客戶端拿掉,讓Api真正的對實現進行“封裝隔離”,然后我們還是面向接口來編程。可是,新的問題出現了,當他把“new Impl()”去掉過后,發現他無法得到Api接口對象了,怎么辦呢?
把這個問題描述一下:在Java編程中,出現只知接口而不知實現,該怎么辦?
就像現在的Client,它知道要使用Api接口,但是不知由誰實現,也不知道如何實現,從而得不到接口對象,就無法使用接口,該怎么辦呢?
請看下節:解決方案
本文鏈接:研磨設計模式之簡單工廠模式(場景問題),轉自:http://chjavach.iteye.com/blog/800325
總結
以上是生活随笔為你收集整理的工厂模式 java场景_研磨设计模式之简单工厂模式(场景问题)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java向有序数组里插数_Java向有序
- 下一篇: Win10系统鼠标滑轮灵敏度怎么设置