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