版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第2章簡(jiǎn)單工廠(chǎng)模式(SimpleFactory)
(靜態(tài)工廠(chǎng)方法模式(StaticFactoryMethod))創(chuàng)建型模式創(chuàng)建型模式概述創(chuàng)建型模式在創(chuàng)建什么(What),由誰(shuí)創(chuàng)建(Who),何時(shí)創(chuàng)建(When)等方面都為軟件設(shè)計(jì)者提供了盡可能大的靈活性創(chuàng)建型模式隱藏類(lèi)實(shí)例的創(chuàng)建細(xì)節(jié),通過(guò)隱藏對(duì)象如何被創(chuàng)建和組合在一起達(dá)到使整個(gè)系統(tǒng)獨(dú)立的目的
創(chuàng)建型模式簡(jiǎn)單工廠(chǎng)模式(SimpleFactory)
工廠(chǎng)方法模式(FactoryMethod)抽象工廠(chǎng)模式(AbstractFactory)建造者模式(Builder)原型模式(Prototype)單例模式(Singleton)創(chuàng)建型模式類(lèi)別工廠(chǎng)模式工廠(chǎng)模式將大量有共同接口的類(lèi)實(shí)例化,而且不必事先知道每次是要實(shí)例化哪一個(gè)類(lèi)的模式(工廠(chǎng)模式可以動(dòng)態(tài)決定將哪一個(gè)類(lèi)實(shí)例化)工廠(chǎng)模式有以下幾種形態(tài):簡(jiǎn)單工廠(chǎng)(SimpleFactory)模式工廠(chǎng)方法(FactoryMethod)模式抽象工廠(chǎng)(AbstractFactory)模式
如何使用接口?假設(shè)有一個(gè)接口Api,然后有一個(gè)類(lèi)Impl實(shí)現(xiàn)它,在客戶(hù)端怎么用這個(gè)接口呢?通常都是在客戶(hù)端創(chuàng)建一個(gè)Impl的實(shí)例,把它賦值給一個(gè)Api接口類(lèi)型的變量,然后客戶(hù)端就可以通過(guò)這個(gè)變量來(lái)操作接口的功能不用模式的解決方案public
interface
Api
{
public
void
test1(String
s);
}
public
class
Impl
implements
Api{
public
void
test1(String
s)
{
System.out.println("The
input
s=="+s);
}
}
public
class
Client
{
public
static
void
main(String[]
args)
{
Api
api
=
new
Impl();
api.test1("測(cè)試!");
}
}
Api
api
=
new
Impl();
在客戶(hù)端調(diào)用的時(shí)候,客戶(hù)端不但知道接口,同時(shí)還知道具體的實(shí)現(xiàn)就是Impl。而接口的思想是“封裝隔離”,而Impl這個(gè)實(shí)現(xiàn)類(lèi),應(yīng)該是被接口Api封裝并同客戶(hù)端隔離開(kāi)的,也就是說(shuō),客戶(hù)端根本就不應(yīng)該知道具體的實(shí)現(xiàn)類(lèi)是Impl。有何問(wèn)題?問(wèn)題描述:在Java編程中,出現(xiàn)只知接口而不知實(shí)現(xiàn),該怎么辦?有何問(wèn)題?解決方案就是簡(jiǎn)單工廠(chǎng)簡(jiǎn)單工廠(chǎng)模式(SimpleFactory)(靜態(tài)工廠(chǎng)方法(StaticFactoryMethod))提供一個(gè)創(chuàng)建對(duì)象實(shí)例的功能,而無(wú)需關(guān)心其具體實(shí)現(xiàn)。被創(chuàng)建實(shí)例的類(lèi)型可以是接口、抽象類(lèi)、具體類(lèi)簡(jiǎn)單工廠(chǎng)定義分析上面的問(wèn)題,雖然不能讓模塊外部知道模塊內(nèi)的具體實(shí)現(xiàn),但是模塊內(nèi)部是可以知道實(shí)現(xiàn)類(lèi)的,而且創(chuàng)建接口是需要具體實(shí)現(xiàn)類(lèi)的是否可以在模塊內(nèi)部新建一個(gè)類(lèi),在這個(gè)類(lèi)里面來(lái)創(chuàng)建接口,然后把創(chuàng)建好的接口返回給客戶(hù)端,這樣外部應(yīng)用就只需要根據(jù)這個(gè)類(lèi)來(lái)獲取相應(yīng)的接口對(duì)象,然后就可以操作接口定義的方法了應(yīng)用簡(jiǎn)單工廠(chǎng)來(lái)解決的思路通過(guò)SimpleFactory類(lèi)生產(chǎn)產(chǎn)品,而對(duì)客戶(hù)端隱藏產(chǎn)品產(chǎn)生的細(xì)節(jié)實(shí)作時(shí)定義一個(gè)產(chǎn)品接口,并透過(guò)特定靜態(tài)方法來(lái)建立成品SimpleFactory類(lèi)根據(jù)傳入的參數(shù)決定創(chuàng)建出哪一種產(chǎn)品類(lèi)的實(shí)例一個(gè)工廠(chǎng)類(lèi)封裝很多類(lèi)的實(shí)例化(同一接口)簡(jiǎn)單工廠(chǎng)模式簡(jiǎn)單工廠(chǎng)模式簡(jiǎn)單工廠(chǎng)模式的類(lèi)圖結(jié)構(gòu)UML工廠(chǎng)類(lèi)角色Creator:工廠(chǎng)類(lèi)在客戶(hù)端的直接調(diào)用下,創(chuàng)建產(chǎn)品對(duì)象并返回該對(duì)象抽象產(chǎn)品角色Product:是工廠(chǎng)類(lèi)所創(chuàng)建對(duì)象的父類(lèi)或它們共同的接口具體產(chǎn)品角色ConcreteProduct:工廠(chǎng)類(lèi)所創(chuàng)建的任何對(duì)象都是這個(gè)角色的實(shí)例說(shuō)明publicinterfaceProduct{}publicclassConcreteProductimplementsProduct{
publicConcreteProduct(){}}publicclassCreator{
publicProductfactory(){
returnnewConcreteProduct();
}}使用簡(jiǎn)單工廠(chǎng)重寫(xiě)前面的示例
1)接口Api和實(shí)現(xiàn)類(lèi)Impl都和前面的示例一樣2)新創(chuàng)建一個(gè)簡(jiǎn)單工廠(chǎng)的對(duì)象,示例代碼//工廠(chǎng)類(lèi),用來(lái)創(chuàng)造Api對(duì)象
public
class
Factory
{
public
static
Api
createApi(){
return
new
Impl();
}
}
3)使用簡(jiǎn)單工廠(chǎng)public
class
Client
{
public
static
void
main(String[]
args)
{
//重要改變,沒(méi)有new
Impl()了,取而代之Factory.createApi()
Api
api
=
Factory.createApi();
api.test1("測(cè)試!");
}
}
例1
假設(shè)有一個(gè)音樂(lè)盒工廠(chǎng),購(gòu)買(mǎi)音樂(lè)盒的客人無(wú)需知道音樂(lè)盒是如何制作的,他只要知道如何播放音樂(lè)盒就可以了
UML類(lèi)別圖MusicBoxDemo代表客戶(hù)角色,它依賴(lài)于IMusicBox接口,而不關(guān)心特定的實(shí)作如何產(chǎn)生IMusicBox的實(shí)例由MusicBoxFactory完成
publicinterfaceIMusicBox{
publicvoidplay();
}publicclassPianoBoximplementsIMusicBox{
publicvoidplay(){
System.out.println(“播放鋼琴音樂(lè):)");
}
}publicclassViolinBoximplementsIMusicBox{
publicvoidplay(){
System.out.println(“播放小提琴音樂(lè)");
}
}
publicclassMusicBoxFactory{publicstaticIMusicBoxcreateMusicBox(Stringname)throwsInstantiationException,IllegalAccessException,ClassNotFoundException{
return(IMusicBox)Class.forName(name).newInstance();
}
}使用Java的Reflection機(jī)制來(lái)產(chǎn)生實(shí)例,以后即使修改程序,客戶(hù)端程序也不用更改
publicclassMusicBoxDemo{
publicstaticvoidmain(String[]args)throwsException{
playMusicBox(MusicBoxFactory.createMusicBox("PianoBox")); playMusicBox(MusicBoxFactory.createMusicBox("ViolinBox"));
}publicstaticvoidplayMusicBox(IMusicBoxmusicBox){
musicBox.play();
}
}
客戶(hù)端只依賴(lài)于IMusicBox接口,改變createMusicBox()中的實(shí)作方式,對(duì)客戶(hù)端沒(méi)有影響
Reflection是Java被視為動(dòng)態(tài)(或準(zhǔn)動(dòng)態(tài))語(yǔ)言的一個(gè)關(guān)鍵性質(zhì)。Java反射機(jī)制主要提供了以下功能:
1)在運(yùn)行時(shí)判斷任意一個(gè)對(duì)象所屬的類(lèi);
2)在運(yùn)行時(shí)構(gòu)造任意一個(gè)類(lèi)的對(duì)象;
3)在運(yùn)行時(shí)判斷任意一個(gè)類(lèi)所具有的成員變量和方法(含私有屬性);
4)在運(yùn)行時(shí)調(diào)用任意一個(gè)對(duì)象的方法;
5)生成動(dòng)態(tài)代理。
在JDK類(lèi)庫(kù)中,主要由以下類(lèi)來(lái)實(shí)現(xiàn)Java反射機(jī)制,這些類(lèi)都位于java.lang.reflect包中。Class類(lèi):代表一個(gè)類(lèi)。
Field類(lèi):代表類(lèi)的屬性。
Method類(lèi):代表類(lèi)的方法。
Constructor類(lèi):代表類(lèi)的構(gòu)造方法。
Array類(lèi):提供了動(dòng)態(tài)創(chuàng)建數(shù)組,以及訪(fǎng)問(wèn)數(shù)組元素的靜態(tài)方法。
Proxy類(lèi)和InvocationHandler接口:提供了生成動(dòng)態(tài)代理類(lèi)及其實(shí)例的方法。
Q1:在Java運(yùn)行時(shí)環(huán)境中,對(duì)于任意一個(gè)類(lèi),能否知道這個(gè)類(lèi)有哪些屬性和方法?對(duì)于任意一個(gè)對(duì)象,能否調(diào)用它的任意一個(gè)方法?Q2:C++?動(dòng)態(tài)語(yǔ)言?有一個(gè)描述你的后花園的系統(tǒng),在你的后花園里有各種的花,但還沒(méi)有水果。你現(xiàn)在要往你的系統(tǒng)里引進(jìn)一些新的類(lèi),用來(lái)描述下列的水果:葡萄Grapes草莓Strawberry萍果Apple
例2
UML類(lèi)別圖作為小花園的主人兼園丁,也是系統(tǒng)的一部分,自然要由一個(gè)合適的類(lèi)來(lái)代表,這個(gè)類(lèi)就FruitGardener類(lèi)。園丁的工作(簡(jiǎn)單工廠(chǎng))FruitGardener類(lèi)會(huì)根據(jù)要求,創(chuàng)建出不同水果類(lèi)的實(shí)例園丁就如同一個(gè)可以創(chuàng)建水果產(chǎn)品的工廠(chǎng)一樣如果接到不合法的要求,FruitGardener類(lèi)會(huì)給出例外BadFruitException。
豐收的果園(客戶(hù)端)
使用時(shí),只須調(diào)用FruitGardener的factory()try{
FruitGardenergardener=newFruitGardener();
FruitIFgrape=gardener.factory("grape");
FruitIFapple=gardener.factory("apple");
FruitIFstrawberry=gardener.factory("strawberry");
...}catch(BadFruitExceptione){...}
FruitIF接口接口FruitIF確定水果類(lèi)必備的方法:種植plant(),生長(zhǎng)grow(),以及收獲harvest()。
publicinterfaceFruitIF{
voidgrow();
voidharvest();
voidplant();
Stringcolor=null;
Stringname=null;
}Apple類(lèi)
萍果是多年生木本植物,因此具備樹(shù)齡treeAge性質(zhì)publicclassAppleimplementsFruitIF{
publicvoidgrow(){
log("Appleisgrowing...");
}
publicvoidharvest(){
log("Applehasbeenharvested.");
}
publicvoidplant(){
log("Applehasbeenplanted.");
}
publicstaticvoidlog(Stringmsg){
System.out.println(msg);
}
publicintgetTreeAge(){returntreeAge;}
publicvoidsetTreeAge(inttreeAge){this.treeAge=treeAge;}
privateinttreeAge;
}Grape類(lèi)
葡萄分為有籽與無(wú)籽兩種,因此具有seedful性質(zhì)publicclassGrapeimplementsFruitIF{
publicvoidgrow(){
log("Grapeisgrowing...");
}
publicvoidharvest(){
log("Grapehasbeenharvested.");
}
publicvoidplant(){
log("Grapehasbeenplanted.");
}
publicstaticvoidlog(Stringmsg){
System.out.println(msg);
}
publicbooleangetSeedful(){
returnseedful;
}
publicvoidsetSeedful(booleanseedful){
this.seedful=seedful;
}
privatebooleanseedful;
}Strawberry類(lèi)publicclassStrawberryimplementsFruitIF{
publicvoidgrow(){
log("Strawberryisgrowing...");
}
publicvoidharvest(){
log("Strawberryhasbeenharvested.");
}
publicvoidplant(){
log("Strawberryhasbeenplanted.");
}
publicstaticvoidlog(Stringmsg){
System.out.println(msg);
}
}FruitGardener類(lèi)publicclassFruitGardener{
publicFruitIF
factory(Stringwhich)throwsBadFruitException
{
if(which.equalsIgnoreCase("apple")){returnnewApple();}
elseif(which.equalsIgnoreCase("strawberry")){returnnewStrawberry();}
elseif(which.equalsIgnoreCase("grape")){returnnewGrape();}
else{thrownewBadFruitException("Badfruitrequest");}
}
}BadFruitException類(lèi)publicclassBadFruitExceptionextendsException{
publicBadFruitException(Stringmsg{super(msg);})
}問(wèn)題1
例1和例2的代碼哪個(gè)更好?問(wèn)題2例1和例2符合開(kāi)閉原則?(對(duì)擴(kuò)展開(kāi)放,對(duì)改變關(guān)閉)數(shù)據(jù)庫(kù)開(kāi)發(fā)中的數(shù)據(jù)源選擇問(wèn)題:
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 地鐵項(xiàng)目招投標(biāo)代理合同樣本
- 2020山東廣電網(wǎng)絡(luò)有限公司招聘試題及答案解析(公共基礎(chǔ)知識(shí))
- 2024年紙質(zhì)宣傳冊(cè)制作與銷(xiāo)售合同范本3篇
- 家政服務(wù)店租賃合同模板
- 2024標(biāo)準(zhǔn)工程居間合同范本
- 二零二五年度股權(quán)轉(zhuǎn)讓三方合作中的員工安置與權(quán)益保障協(xié)議3篇
- 二零二五年度百貨零售商與供應(yīng)商聯(lián)合促銷(xiāo)合同3篇
- 2024石粉環(huán)保型產(chǎn)品研發(fā)與應(yīng)用采購(gòu)合同3篇
- 2024簡(jiǎn)化版委托代理協(xié)議樣本版B版
- 重慶警察學(xué)院《英語(yǔ)教學(xué)實(shí)踐2》2023-2024學(xué)年第一學(xué)期期末試卷
- FZ/T 81024-2022機(jī)織披風(fēng)
- GB/T 24123-2009電容器用金屬化薄膜
- 艾滋病梅毒乙肝實(shí)驗(yàn)室檢測(cè)
- 國(guó)鐵橋梁人行道支架制作及安裝施工要點(diǎn)課件
- 領(lǐng)導(dǎo)科學(xué)全套精講課件
- 粵教版地理七年級(jí)下冊(cè)全冊(cè)課件
- 小學(xué)科學(xué)蘇教版六年級(jí)上冊(cè)全冊(cè)精華知識(shí)點(diǎn)(2022新版)
- 萎縮性胃炎共識(shí)解讀
- 《中外資產(chǎn)評(píng)估準(zhǔn)則》課件第8章 澳大利亞與新西蘭資產(chǎn)評(píng)估準(zhǔn)則
- 2022版義務(wù)教育語(yǔ)文課程標(biāo)準(zhǔn)(2022版含新增和修訂部分)
- 精品金屬線(xiàn)管布線(xiàn)施工工程施工方法
評(píng)論
0/150
提交評(píng)論