




版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領
文檔簡介
第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();
在客戶端調(diào)用的時候,客戶端不但知道接口,同時還知道具體的實現(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)建實例的類型可以是接口、抽象類、具體類簡單工廠定義分析上面的問題,雖然不能讓模塊外部知道模塊內(nèi)的具體實現(xiàn),但是模塊內(nèi)部是可以知道實現(xiàn)類的,而且創(chuàng)建接口是需要具體實現(xiàn)類的是否可以在模塊內(nèi)部新建一個類,在這個類里面來創(chuàng)建接口,然后把創(chuàng)建好的接口返回給客戶端,這樣外部應用就只需要根據(jù)這個類來獲取相應的接口對象,然后就可以操作接口定義的方法了應用簡單工廠來解決的思路通過SimpleFactory類生產(chǎn)產(chǎn)品,而對客戶端隱藏產(chǎn)品產(chǎn)生的細節(jié)實作時定義一個產(chǎn)品接口,并透過特定靜態(tài)方法來建立成品SimpleFactory類根據(jù)傳入的參數(shù)決定創(chuàng)建出哪一種產(chǎn)品類的實例一個工廠類封裝很多類的實例化(同一接口)簡單工廠模式簡單工廠模式簡單工廠模式的類圖結構UML工廠類角色Creator:工廠類在客戶端的直接調(diào)用下,創(chuàng)建產(chǎn)品對象并返回該對象抽象產(chǎn)品角色Product:是工廠類所創(chuàng)建對象的父類或它們共同的接口具體產(chǎn)品角色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接口,而不關心特定的實作如何產(chǎn)生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機制來產(chǎn)生實例,以后即使修改程序,客戶端程序也不用更改
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))語言的一個關鍵性質(zhì)。Java反射機制主要提供了以下功能:
1)在運行時判斷任意一個對象所屬的類;
2)在運行時構造任意一個類的對象;
3)在運行時判斷任意一個類所具有的成員變量和方法(含私有屬性);
4)在運行時調(diào)用任意一個對象的方法;
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)境中,對于任意一個類,能否知道這個類有哪些屬性和方法?對于任意一個對象,能否調(diào)用它的任意一個方法?Q2:C++?動態(tài)語言?有一個描述你的后花園的系統(tǒng),在你的后花園里有各種的花,但還沒有水果。你現(xiàn)在要往你的系統(tǒng)里引進一些新的類,用來描述下列的水果:葡萄Grapes草莓Strawberry萍果Apple
例2
UML類別圖作為小花園的主人兼園丁,也是系統(tǒng)的一部分,自然要由一個合適的類來代表,這個類就FruitGardener類。園丁的工作(簡單工廠)FruitGardener類會根據(jù)要求,創(chuàng)建出不同水果類的實例園丁就如同一個可以創(chuàng)建水果產(chǎn)品的工廠一樣如果接到不合法的要求,FruitGardener類會給出例外BadFruitException。
豐收的果園(客戶端)
使用時,只須調(diào)用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性質(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類
葡萄分為有籽與無籽兩種,因此具有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類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)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 考前心理調(diào)適2025年信息系統(tǒng)項目管理師試題及答案
- 知識提升信息系統(tǒng)項目管理師試題及答案
- 長線備考西方政治考試的方案試題及答案
- 機電工程2025年外部環(huán)境試題及答案
- 西方政治制度與文化遺產(chǎn)保護的結合探討試題及答案
- 政治變革中的青年參與關系試題及答案
- 網(wǎng)絡工程中的團隊協(xié)作與試題及答案
- 解析軟件設計師考試問答試題及答案
- 機電工程國際技術標準試題及答案
- 2023人教版數(shù)學一年下冊《認識人民幣》說課稿及教學反思共三
- 納米陶瓷噴涂施工方案范本
- 銀行訴訟案件管理辦法
- 危險性較大的分部分項工程專項施工方案編制指南
- 云南省昆明市成考專升本2023年醫(yī)學綜合真題及答案
- 生物質(zhì)材料及應用淀粉
- GB/T 4223-2004廢鋼鐵
- GB/T 36148.1-2018船舶與海上技術海上環(huán)境保護圍油欄第1部分:設計要求
- GB 2811-1989安全帽
- 端子壓接規(guī)范標準
- 新版《藥品管理法》解讀課件
- 東南大學附屬中大醫(yī)院ECMO操作記錄單
評論
0/150
提交評論