




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
第2章簡單工廠模式(SimpleFactory)
(靜態(tài)工廠方法模式(StaticFactoryMethod))創(chuàng)建型模式創(chuàng)建型模式概述創(chuàng)建型模式在創(chuàng)建什么(What),由誰創(chuàng)建(Who),何時創(chuàng)建(When)等方面都為軟件設計者提供了盡可能大的靈活性創(chuàng)建型模式隱藏類實例的創(chuàng)建細節(jié),通過隱藏對象如何被創(chuàng)建和組合在一起達到使整個系統(tǒng)獨立的目的
創(chuàng)建型模式簡單工廠模式(SimpleFactory)
工廠方法模式(FactoryMethod)抽象工廠模式(AbstractFactory)建造者模式(Builder)原型模式(Prototype)單例模式(Singleton)創(chuàng)建型模式類別工廠模式工廠模式將大量有共同接口的類實例化,而且不必事先知道每次是要實例化哪一個類的模式(工廠模式可以動態(tài)決定將哪一個類實例化)工廠模式有以下幾種形態(tài):簡單工廠(SimpleFactory)模式工廠方法(FactoryMethod)模式抽象工廠(AbstractFactory)模式
如何使用接口?假設有一個接口Api,然后有一個類Impl實現(xiàn)它,在客戶端怎么用這個接口呢?通常都是在客戶端創(chuàng)建一個Impl的實例,把它賦值給一個Api接口類型的變量,然后客戶端就可以通過這個變量來操作接口的功能不用模式的解決方案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("測試!");
}
}
Api
api
=
new
Impl();
在客戶端調用的時候,客戶端不但知道接口,同時還知道具體的實現(xiàn)就是Impl。而接口的思想是“封裝隔離”,而Impl這個實現(xiàn)類,應該是被接口Api封裝并同客戶端隔離開的,也就是說,客戶端根本就不應該知道具體的實現(xiàn)類是Impl。有何問題?問題描述:在Java編程中,出現(xiàn)只知接口而不知實現(xiàn),該怎么辦?有何問題?解決方案就是簡單工廠簡單工廠模式(SimpleFactory)(靜態(tài)工廠方法(StaticFactoryMethod))提供一個創(chuàng)建對象實例的功能,而無需關心其具體實現(xiàn)。被創(chuàng)建實例的類型可以是接口、抽象類、具體類簡單工廠定義分析上面的問題,雖然不能讓模塊外部知道模塊內的具體實現(xiàn),但是模塊內部是可以知道實現(xiàn)類的,而且創(chuàng)建接口是需要具體實現(xiàn)類的是否可以在模塊內部新建一個類,在這個類里面來創(chuàng)建接口,然后把創(chuàng)建好的接口返回給客戶端,這樣外部應用就只需要根據(jù)這個類來獲取相應的接口對象,然后就可以操作接口定義的方法了應用簡單工廠來解決的思路通過SimpleFactory類生產產品,而對客戶端隱藏產品產生的細節(jié)實作時定義一個產品接口,并透過特定靜態(tài)方法來建立成品SimpleFactory類根據(jù)傳入的參數(shù)決定創(chuàng)建出哪一種產品類的實例一個工廠類封裝很多類的實例化(同一接口)簡單工廠模式簡單工廠模式簡單工廠模式的類圖結構UML工廠類角色Creator:工廠類在客戶端的直接調用下,創(chuàng)建產品對象并返回該對象抽象產品角色Product:是工廠類所創(chuàng)建對象的父類或它們共同的接口具體產品角色ConcreteProduct:工廠類所創(chuàng)建的任何對象都是這個角色的實例說明publicinterfaceProduct{}publicclassConcreteProductimplementsProduct{
publicConcreteProduct(){}}publicclassCreator{
publicProductfactory(){
returnnewConcreteProduct();
}}使用簡單工廠重寫前面的示例
1)接口Api和實現(xiàn)類Impl都和前面的示例一樣2)新創(chuàng)建一個簡單工廠的對象,示例代碼//工廠類,用來創(chuàng)造Api對象
public
class
Factory
{
public
static
Api
createApi(){
return
new
Impl();
}
}
3)使用簡單工廠public
class
Client
{
public
static
void
main(String[]
args)
{
//重要改變,沒有new
Impl()了,取而代之Factory.createApi()
Api
api
=
Factory.createApi();
api.test1("測試!");
}
}
例1
假設有一個音樂盒工廠,購買音樂盒的客人無需知道音樂盒是如何制作的,他只要知道如何播放音樂盒就可以了
UML類別圖MusicBoxDemo代表客戶角色,它依賴于IMusicBox接口,而不關心特定的實作如何產生IMusicBox的實例由MusicBoxFactory完成
publicinterfaceIMusicBox{
publicvoidplay();
}publicclassPianoBoximplementsIMusicBox{
publicvoidplay(){
System.out.println(“播放鋼琴音樂:)");
}
}publicclassViolinBoximplementsIMusicBox{
publicvoidplay(){
System.out.println(“播放小提琴音樂");
}
}
publicclassMusicBoxFactory{publicstaticIMusicBoxcreateMusicBox(Stringname)throwsInstantiationException,IllegalAccessException,ClassNotFoundException{
return(IMusicBox)Class.forName(name).newInstance();
}
}使用Java的Reflection機制來產生實例,以后即使修改程序,客戶端程序也不用更改
publicclassMusicBoxDemo{
publicstaticvoidmain(String[]args)throwsException{
playMusicBox(MusicBoxFactory.createMusicBox("PianoBox")); playMusicBox(MusicBoxFactory.createMusicBox("ViolinBox"));
}publicstaticvoidplayMusicBox(IMusicBoxmusicBox){
musicBox.play();
}
}
客戶端只依賴于IMusicBox接口,改變createMusicBox()中的實作方式,對客戶端沒有影響
Reflection是Java被視為動態(tài)(或準動態(tài))語言的一個關鍵性質。Java反射機制主要提供了以下功能:
1)在運行時判斷任意一個對象所屬的類;
2)在運行時構造任意一個類的對象;
3)在運行時判斷任意一個類所具有的成員變量和方法(含私有屬性);
4)在運行時調用任意一個對象的方法;
5)生成動態(tài)代理。
在JDK類庫中,主要由以下類來實現(xiàn)Java反射機制,這些類都位于java.lang.reflect包中。Class類:代表一個類。
Field類:代表類的屬性。
Method類:代表類的方法。
Constructor類:代表類的構造方法。
Array類:提供了動態(tài)創(chuàng)建數(shù)組,以及訪問數(shù)組元素的靜態(tài)方法。
Proxy類和InvocationHandler接口:提供了生成動態(tài)代理類及其實例的方法。
Q1:在Java運行時環(huán)境中,對于任意一個類,能否知道這個類有哪些屬性和方法?對于任意一個對象,能否調用它的任意一個方法?Q2:C++?動態(tài)語言?有一個描述你的后花園的系統(tǒng),在你的后花園里有各種的花,但還沒有水果。你現(xiàn)在要往你的系統(tǒng)里引進一些新的類,用來描述下列的水果:葡萄Grapes草莓Strawberry萍果Apple
例2
UML類別圖作為小花園的主人兼園丁,也是系統(tǒng)的一部分,自然要由一個合適的類來代表,這個類就FruitGardener類。園丁的工作(簡單工廠)FruitGardener類會根據(jù)要求,創(chuàng)建出不同水果類的實例園丁就如同一個可以創(chuàng)建水果產品的工廠一樣如果接到不合法的要求,FruitGardener類會給出例外BadFruitException。
豐收的果園(客戶端)
使用時,只須調用FruitGardener的factory()try{
FruitGardenergardener=newFruitGardener();
FruitIFgrape=gardener.factory("grape");
FruitIFapple=gardener.factory("apple");
FruitIFstrawberry=gardener.factory("strawberry");
...}catch(BadFruitExceptione){...}
FruitIF接口接口FruitIF確定水果類必備的方法:種植plant(),生長grow(),以及收獲harvest()。
publicinterfaceFruitIF{
voidgrow();
voidharvest();
voidplant();
Stringcolor=null;
Stringname=null;
}Apple類
萍果是多年生木本植物,因此具備樹齡treeAge性質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類
葡萄分為有籽與無籽兩種,因此具有seedful性質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類publicclassStrawberryimplementsFruitIF{
publicvoidgrow(){
log("Strawberryisgrowing...");
}
publicvoidharvest(){
log("Strawberryhasbeenharvested.");
}
publicvoidplant(){
log("Strawberryhasbeenplanted.");
}
publicstaticvoidlog(Stringmsg){
System.out.println(msg);
}
}FruitGardener類publicclassFruitGardener{
publicFruitIF
factory(Stringwhich)throwsBadFruitException
{
if(which.equalsIgnoreCase("apple")){returnnewApple();}
elseif(which.equalsIgnoreCase("strawberry")){returnnewStrawberry();}
elseif(which.equalsIgnoreCase("grape")){returnnewGrape();}
else{thrownewBadFruitException("Badfruitrequest");}
}
}BadFruitException類publicclassBadFruitExceptionextendsException{
publicBadFruitException(Stringmsg{super(msg);})
}問題1
例1和例2的代碼哪個更好?問題2例1和例2符合開閉原則?(對擴展開放,對改變關閉)數(shù)據(jù)庫開發(fā)中的數(shù)據(jù)源選擇問題:
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 青島幼兒師范高等??茖W校《現(xiàn)代漢語I》2023-2024學年第二學期期末試卷
- 慶陽職業(yè)技術學院《商務統(tǒng)計》2023-2024學年第二學期期末試卷
- 沈陽醫(yī)學院《應用多元統(tǒng)計分析實訓》2023-2024學年第二學期期末試卷
- 嘉興南湖學院《歷史文獻檢索與論文寫作》2023-2024學年第二學期期末試卷
- 江西理工大學《材料科學基礎應用研究》2023-2024學年第二學期期末試卷
- 沈陽師范大學《兒歌表演唱(二)》2023-2024學年第二學期期末試卷
- 麗江文化旅游學院《中外戲劇比較研究》2023-2024學年第二學期期末試卷
- 廣東農工商職業(yè)技術學院《電工與電子技術A》2023-2024學年第二學期期末試卷
- 新疆工程學院《核醫(yī)學E》2023-2024學年第二學期期末試卷
- 池州學院《跨文化研究》2023-2024學年第二學期期末試卷
- 2025年益陽醫(yī)學高等??茖W校高職單招數(shù)學歷年(2016-2024)頻考點試題含答案解析
- 餐飲業(yè)的供應鏈管理與優(yōu)化
- 2025年紹興市上虞大眾勞動事務代理(所)有限公司招聘筆試參考題庫附帶答案詳解
- 心律失常介入并發(fā)癥及預防
- 《分娩機轉》課件
- 口腔醫(yī)院市場營銷新入職員工培訓
- 軍隊文職備考(面試)近年考試真題(參考300題)
- 金融業(yè)稅收優(yōu)惠政策指引
- 葉圣陶杯作文
- 腦梗死臨床表現(xiàn)護理
- 新高考英語|語法專項之括號法突破長難句 講解課件-2025屆高三英語上學期一輪復習專項
評論
0/150
提交評論