亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

在Java中應用設計模式-Factory Method

2019-11-18 13:36:58
字體:
來源:轉載
供稿:網友

  在設計模式中,Factory Method也是比較簡單的一個,但應用非常廣泛,EJB,RMI,COM,CORBA,Swing中都可以看到此模式的影子,它是最重要的模式之一.在很多地方我們都會看到xxxFactory這樣命名的類,那么,什么是Factory Method,為什么要用這個模式,如何用java語言來實現該模式,這就是本文想要帶給大家的內容.

基本概念

Factory Method是一種創建性模式,它定義了一個創建對象的接口,但是卻讓子類來決定具體實例化哪一個類.當一個類無法預料要創建哪種類的對象或是一個類需要由子類來指定創建的對象時我們就需要用到Factory Method 模式了.簡單說來,Factory Method可以根據不同的條件產生不同的實例,當然這些不同的實例通常是屬于相同的類型,具有共同的父類.Factory Method把創建這些實例的具體過程封裝起來了,簡化了客戶端的應用,也改善了程序的擴展性,使得將來可以做最小的改動就可以加入新的待創建的類. 通常我們將Factory Method作為一種標準的創建對象的方法,當發現需要更多的靈活性的時候,就開始考慮向其它創建型模式轉化

簡單分析

圖1是Factory Method 模式的結構圖,這里提供了一些術語,讓我們可以進行更方便的描述:

PRodUCt: 需要創建的產品的抽象類.

ConcreteProduct: Product的子類,一系列具體的產品.

Creator: 抽象創建器接口,聲明返回Product類型對象的Factory Method.

ConcreteCreator: 具體的創建器,重寫Creator中的Factory Method,返回ConcreteProduct類型的實例.

圖1: Factory Method 模式結構

由此可以清楚的看出這樣的平行對應關系: Product <====> Creator ; ConreteProduct <====> ConreteCreator

抽象產品對應抽象創建器,具體產品對應具體創建器.這樣做的好處是什么呢?為什么我們不直接用具體的產品和具體的創建器完成需求呢?實際上我們也可以這樣做.但通過Factory Method模式來完成,客戶(client)只需引用抽象的Product和Creater,對具體的ConcreteProduct和 ConcreteCreator可以毫不關心,這樣做我們可以獲得額外的好處:

首先客戶端可以統一從抽象創建器獲取產生的實例, Creator的作用將client和產品創建過程分離開來,客戶不用操心返回的是那一個具體的產品,也不用關心這些產品是如何創建的.同時, ConcreteProduct也被隱藏在Product后面,ConreteProduct繼續了Product的所有屬性,并實現了Product中定義的抽象方法,按照Java中的對象造型(cast)原則,通過ConcreteCreator產生的ConcreteProduct可以自動的上溯造型成Product.這樣一來,實質內容不同的ConcreteProduct就可以在形式上統一為Product,通過Creator提供給 client來訪問.

其次,當我們添加一個新的ConcreteCreator時,由于Creator所提供的接口不變,客戶端程序不會有絲毫的改動,不會帶來動一發而牽全身的災難, 這就是良好封裝性的體現.但假如直接用ConcreteProduct和ConcreteCreator兩個類是無論如何也做不到這點的. 優良的面向對象設計鼓勵使用封裝(encapsulation)和委托(delegation),而Factory Method模式就是使用了封裝和委托的典型例子,這里封裝是通過抽象創建器Creator來體現的,而委托則是通過抽象創建器把創建對象的責任完全交給具體創建器ConcreteCreator來體現的.

現在,請再回頭看看基本概念中的那段話,開始也許覺得生澀難懂,現在是不是已經明朗化了很多.

下面讓我們看看在 Java 中如何實現Factory Method模式,進一步加深對它的熟悉.

具體實施

先說明一點,用Factory Method模式創建對象并不一定會讓我們的代碼更短,實事上往往更長,我們也使用了更多的類,真正的目的在于這樣可以靈活的,有彈性的創建不確定的對象.而且,代碼的可重用性提高了,客戶端的應用簡化了,客戶程序的代碼會大大減少,變的更具可讀性.

標準實現: 這里我采用Bruce Eckel 用來描述OO思想的經典例子 Shape.這樣大家會比較熟悉一些.我完全按照圖1中所定義的結構寫了下面的一段演示代碼.這段代碼的作用是創建不同的Shape實例,每個實例完成兩個操作:draw和erase.具體的創建過程委托給ShapeFactory來完成.

1.a 首先定義一個抽象類Shape,定義兩個抽象的方法.

abstract class Shape {

// 勾畫shape

public abstract void draw();

// 擦去 shape

public abstract void erase();

public String name;

public Shape(String aName){

   name = aName;

}

}


1.b 定義 Shape的兩個子類: Circle, Square,實現Shape中定義的抽象方法

// 圓形子類

class Circle extends Shape {

public void draw() {

  System.out.println("It will draw a circle.");

}

public void erase() {

  System.out.println("It will erase a circle.");

}

// 構造函數

public Circle(String aName){

   super(aName);

}

}


// 方形子類

class Square extends Shape {

public void draw() {

  System.out.println("It will draw a square.");

}

public void erase() {

  System.out.println("It will erase a square.");

}

// 構造函數

public Square(String aName){

   super(aName);

}

}


1.c 定義抽象的創建器,anOperation調用factoryMethod創建一個對象,并對該對象進行一系列操作.

abstract class ShapeFactory {  

protected abstract Shape factoryMethod(String aName);

// 在anOperation中定義Shape的一系列行為

public void anOperation(String aName){

  Shape s = factoryMethod(aName);

   System.out.println("The current shape is: " + s.name);

  s.draw();

 s.erase();

}

}


1.d 定義與circle和square相對應的兩個具體創建器CircleFactory,SquareFactory,實現父類的methodFactory方法

// 定義返回 circle 實例的 CircleFactory

class CircleFactory extends ShapeFactory {

// 重載factoryMethod方法,返回Circle對象

protected Shape factoryMethod(String aName) {

  return new Circle(aName + " (created by CircleFactory)");

}

}


// 定義返回 Square 實例的 SquareFactory

class SquareFactory extends ShapeFactory {

// 重載factoryMethod方法,返回Square對象

protected Shape factoryMethod(String aName) {

  return new Square(aName + " (created by SquareFactory)");

}

}


1.e 測試類:請注重這個客戶端程序多么簡潔,既沒有羅嗦的條件判定語句,也無需關心ConcreteProduct和ConcreteCreator的細節 (因為這里我用anOperation封裝了Product里的兩個方法,所以連Product的影子也沒看見,當然把Product里方法的具體調用放到客戶程序中也是不錯的).

class Main {

public static void main(String[] args){

ShapeFactory sf1 = new SquareFactory();

ShapeFactory sf2 = new CircleFactory();

sf1.anOperation("Shape one");

sf2.anOperation("Shape two");

}

}

運行結果如下:

The current shape is: Shape one (created by SquareFactory)

It will draw a square.

It will erase a square.

The current shape is: Shape two (created by CircleFactory)

It will draw a circle.

It will erase a circle.

參數化的Factory Method: 這種方式依靠指定的參數作為標志來創建對應的實例,這是很常見的一種辦法.比如JFC中的BorderFactory就是個很不錯的例子. 以下的這個例子是用字符串作為標記來進行判定的,假如參數的類型也不一樣,那就可以用到過載函數來解決這個問題,定義一系列參數和方法體不同的同名函數, 這里java.util.Calendar.getInstance()又是個極好的例子.參數化的創建方式克服了Factory Method模式一個最顯著的缺陷,就是當具體產品比較多時,我們不得不也建立一系列與之對應的具體構造器. 但是在客戶端我們必須指定參數來決定要創建哪一個類.

2.a 我們在第一種方法的基礎上進行修改,首先自定義一個的異常,這樣當傳入不正確的參數時可以得到更明顯的報錯信息.

class NoThisShape extends Exception {

public NoThisShape(String aName) {

  super(aName);

}

}


2.b去掉了ShapeFactory的兩個子類,改為由ShapeFactory直接負責實例的創建. ShapeFactory自己變成一個具體的創建器,直接用參數化的方法實現factoryMethod返回多種對象.

abstract class ShapeFactory {  

private static Shape s;

private ShapeFactory() {}

 

static Shape factoryMethod(String aName, String aType) throws NoThisShape{

  if (aType.compareTo("square")==0)

    return new Square(aName);

  &nbs

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美国产欧美亚洲国产日韩mv天天看完整| 国产精品丝袜白浆摸在线| 日韩av网址在线| 亚洲电影av在线| 久久久视频免费观看| 狠狠躁18三区二区一区| 性欧美激情精品| 国产成人在线亚洲欧美| 国产精品6699| 伊人精品在线观看| 欧美亚洲成人精品| 国产久一一精品| 亚洲18私人小影院| 欧美大胆在线视频| 亚洲欧美中文另类| 欧美激情精品久久久久| 亚洲摸下面视频| 91日韩在线视频| 欧美日韩在线视频一区二区| 国产精品久久91| 日韩视频免费看| 97精品视频在线| 亚洲摸下面视频| 亚洲www永久成人夜色| 国产欧美在线视频| 中文字幕在线看视频国产欧美在线看完整| 亚洲成av人片在线观看香蕉| 成人在线视频网| 亚洲欧美日韩区| 国产精品ⅴa在线观看h| 国产精品久久久久久久7电影| 成人免费网站在线| 欧美电影免费观看大全| 国产在线视频2019最新视频| 日韩精品一区二区三区第95| 欧美在线影院在线视频| 国产成人精品999| 久久99亚洲精品| 深夜福利国产精品| 亚洲精品福利免费在线观看| 国产精品成人aaaaa网站| 欧美电影在线观看| 色系列之999| 亚洲高清色综合| 日韩动漫免费观看电视剧高清| 欧美亚洲另类激情另类| 91精品久久久久久久久中文字幕| 日韩精品有码在线观看| 91视频88av| 欧美www视频在线观看| 欧美日本高清一区| 亚洲人成网站免费播放| 狠狠久久亚洲欧美专区| 一区二区三区视频免费| 国产精品亚发布| 久久久久久久久久久久久久久久久久av| 北条麻妃在线一区二区| 亚洲人成电影网站色xx| 97av在线视频免费播放| 成人福利网站在线观看| 神马久久久久久| 一本色道久久综合狠狠躁篇的优点| 最近2019年中文视频免费在线观看| 亚洲精品福利视频| 97国产suv精品一区二区62| 北条麻妃久久精品| 青青草原一区二区| 国产欧美亚洲精品| 欧美日韩国产成人在线| 永久免费毛片在线播放不卡| 日韩电影在线观看永久视频免费网站| 久久久亚洲天堂| 欧美一级免费视频| 欧美亚洲视频在线看网址| 国产91色在线免费| 成人免费福利视频| 91精品在线观| 国产精品精品视频一区二区三区| 在线精品视频视频中文字幕| 久久久亚洲天堂| 57pao精品| 亚洲国产成人久久综合一区| 欧美高清在线观看| 91精品国产99久久久久久| 久久久国产精彩视频美女艺术照福利| 国内精品久久久久影院优| 国产免费一区视频观看免费| 日韩亚洲成人av在线| 欧美福利在线观看| 欧美国产日韩二区| 日本亚洲欧美成人| 精品毛片网大全| 欧美夫妻性生活视频| 亚洲欧洲美洲在线综合| 欧美极品少妇xxxxⅹ喷水| 97色在线视频| 欧美中文在线观看| 最新的欧美黄色| 91九色国产社区在线观看| 欧美电影免费播放| 91国在线精品国内播放| 4438全国亚洲精品在线观看视频| 国产精品视频公开费视频| 亚洲一区二区三区视频播放| 亚洲精品v天堂中文字幕| 亚洲欧美中文日韩在线v日本| 98精品国产自产在线观看| 欧美激情视频在线观看| 成人黄色免费在线观看| 欧美性生活大片免费观看网址| 国产精品高清在线观看| 日韩视频免费观看| 伊人伊成久久人综合网小说| 欧美第一淫aaasss性| 欧美成人免费全部观看天天性色| 亚洲影院高清在线| 精品人伦一区二区三区蜜桃免费| 久久久久久国产精品三级玉女聊斋| 亚洲国产精品va在线看黑人动漫| 亚洲天堂av综合网| 亚洲国产欧美在线成人app| 在线日韩欧美视频| 日韩国产精品亚洲а∨天堂免| 日韩人体视频一二区| 国产精品爽黄69天堂a| 一个人www欧美| 久久av红桃一区二区小说| 久久精品成人一区二区三区| 亚洲摸下面视频| 亚洲a区在线视频| 欧美电影在线播放| 庆余年2免费日韩剧观看大牛| 国产色综合天天综合网| 成人做爰www免费看视频网站| 久久精品亚洲一区| 亚洲精品少妇网址| 欧美电影免费观看高清| 啊v视频在线一区二区三区| 热99精品只有里视频精品| 国产日韩精品入口| 国产一区视频在线播放| 久久成人这里只有精品| 久久亚洲国产精品| 欧美电影在线播放| 欧美富婆性猛交| 亚洲精品久久久久久久久| 亚洲第一偷拍网| 国产精品视频久久久| 在线丨暗呦小u女国产精品| 欧洲成人在线观看| 在线中文字幕日韩| 日韩精品极品在线观看| 欧美一区二区三区四区在线| 久久久久中文字幕| 亚洲成人av片| 欧美孕妇与黑人孕交| 亚洲一区二区久久久久久| 亚洲а∨天堂久久精品喷水| 88国产精品欧美一区二区三区| 中文字幕不卡av| 欧美超级免费视 在线| 日韩中文字幕亚洲| 亚洲va久久久噜噜噜久久天堂| 秋霞av国产精品一区|