<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12
      happyhippy

      這個世界的問題在于聰明人充滿疑惑,而傻子們堅信不疑。--羅素

          FactoryMethod是一個相對比較簡單的創建型模式,但是能領悟或者用對的并不多見;很多示例都沒有反應出Factory Method的核心思想,只是實現了一個簡化版的Abstract Factory,然后給出的解釋是Factory Method模式解決“單個對象”的需求變化,Abstract Factory 模式解決“系列對象”的需求變化。

          試想一下,如果把1視為N的一種特殊情況,則一個產品系列可能只包含一個對象;那么我們是不是可以認為Factory Method是一個簡化版的Abstract Factory呢?實際上,Factory Method模式與Abstract Factory模式雖然同屬于對象創建型模式,并且AbstractFactory通常用Factory Method模式實現,并且效果上都可用于連接平行的類層次,但是這兩個模式在思想上有著本質的區別。網上的文章抄來抄去,結果錯誤也被到處傳。上一篇介紹了被普遍誤用的Builder模式,這篇繼續為Factory Method正名。

       

      1. Factory Method (Form《設計模式》 GOF)

      1.1 意圖

      定義一個用于創建對象的接口,讓子類來決定實例化哪一個類。Factory Method使一個類的實例化延遲到其子類

      1.2 別名

      虛構造器(Virtual Constructor

      1.3 實用性

      同時滿足下列情況下可以使用Factory Method模式:

      1. 當一個類不知道他所必須創建的類的對象的時候;
      2. 當一個類希望由它的子類來指定他所創建的對象的時候;
      3. 當類將創建對象的職責委托給多個幫助子類中的某一個,并且你希望將哪一個幫助子類是代理者這一信息局部化的時候。(這個翻譯很汗,英文原文是:classes delegate responsibility to one of several helper subclasses, and you want to localize the knowledge of which helper subclass is the delegate.)
      1.4 結構:(直接從書中截的圖)

      image

       

      1.5 補充說明
      1. 上面是GOF對FactoryMethod的闡述,字里行間,都流露出繼承思想:父類(Creator)不知道他所必須創建的類的對象(Product),于是就留了個接口,委托給子類(ConcreteCreator)來實現(重寫)。
      2. Creator類中還有個AnOperation方法,GOF還專門為這個方法做了注釋,該方法是一個Template Method(模板方法),其調用FactoryMethod()。并且在相關模式中,GOF也重復提到:“工廠方法通常在Template Method中被調用”,很多介紹Factory Method的例子,都直接無視這個Method和注釋,導致誤用Factory Method模式。
      3. 這個類圖中,沒有畫“Client”類,而Abstract Factory中,有畫Client類。這里應該不是高興的時候就畫,不高興的時候就不畫,畫與不畫自有其中的道理。

          繼續沿用上一篇的思路,從幾個被曲解的例子開始。

       

      2.  兩個簡化版的Abstract Factory模式

      2.1 Abstract Factory模式結構圖

      (直接從書中截的圖)

      image

      2.2 當產品系列中只包含一個對象

      Abstract Factory 用于創建產品系列,一個系列的產品可能包含多個(N,N>=1)個對象;但如果我們把1視為N的一種特殊情況,則一個產品系列可能只包含一個對象,則有如下結構:

      1. 《大話設計模式》中Factory Method的例子:(從書中截的圖)

      clip_image001

      2. <.Net設計模式(5):工廠方法模式(Factory Method)>

      http://www.rzrgm.cn/Terrylee/archive/2006/01/04/310716.html, 直接引用的原文中的兩個圖片:

          由于是兩個圖,我也沒有做處理,直接搬過來了;畫上聚合線的話,與前面的例子差不多。

      2.3 對這兩個例子的說明

          GOF在介紹Abstract Factory模式的時候,有說到“AbstractFactory通常用Factory Method模式實現,但它們也可以用Prototype實現”。雖然上面兩個例子中,只看其中的局部部分的話,用到了Factory Method模式,但結合原作者們的闡述、及擴展點,全局地看,并沒有反映出Factory Method的思想

       

      3. Factory Method與Abstract Factory的區別

      Factory Method模式與Abstract Factory模式雖然同屬于對象創建型模式,并且AbstractFactory通常用Factory Method模式實現,并且效果上都可用于連接平行的類層次(Factory Method不限于此),但是這兩個模式在思想上有著本質的區別。我理解的Factory Method與Abstract Factory,有如下幾點區別:

      3.1 對象職責上:Abstract Factory中的Factory,只具有創建對象(一個產品系列)的唯一職責;而Factory Method中的Creator,往往具有實際的邏輯和意義

          回過頭來看Factory Method的結構圖,可以看到Creator類中還有個AnOperation方法,GOF還專門為這個方法做了注釋,該方法是一個Template Method(模板方法),其調用FactoryMethod()。并且在相關模式中,GOF也重復提到:“工廠方法通常在Template Method中被調用”。也就是說,通常是在Creator類自己的其他方法里面,調用Factory Method方法。為啥會這樣子呢?

          GOF用下面這個例子來引出Factory Method模式:

           image

          這個例子中,Application扮演Creator的角色,MyApplication扮演ConcreteCreator的角色。Application是一個鮮活的類,它是對具體事物(應用)的抽象,具有自己的職責,而不僅僅只是new一個Document對象;它的NewDocument方法(Template Method)調用CreateDocument,Application對象其實就是Document對象的使用者(Client);Factory Method突出的是對Procuct(本例中的Document)創建,所以在結構圖中,沒有出現額外的Client類,也不需要出現。

        (2010-09-29補充 [特別感謝一樓的soudog] :) Factory Method的creator同時包含了不變的代碼邏輯和變化部分,但里面的變化部分可以委托子類來重寫(override);而abstract facotry把變化部分提取到factory類中,將不變的代碼邏輯(Client)與變化部分分離得更徹底,然后通過聚合來連接Client和factory。

      3.2 擴展上:Abstract Factory側重水平擴展,而Factory Method側重垂直擴展

          “水平擴展”、“垂直擴展”的概念是我自己胡口亂說的,呵呵。可以用下面兩個圖來說明:

          先看Abstact Factory(留意圖中的紅色箭頭及方向):

      image

          Abstract Factory:不同的ConcreteFactory,創建不同的產品系列,Factory之間可以相互替換,從而替換產品系列。Client面向接口(AbstractFactory和AbstractProductA)編程,Factory類封裝了對象系列的創建工作,具體的產品也從Client中分離開來,使得我們很容易交換產品系列。圖中我們可以看到,新增加的ProductA3/B3和ConcreteFactory3,與原有ConcreteProduct和ConcreteFactory,處于平行的類層次。這就是我所謂的“水平擴展”-_-

          補充:雖然可以增加其他的ConcreteFactory,譬如ConcreteFactory4,讓其繼承現有的ConcreteFactory,看起來ConcreteFactory4與其他的ConcreteFacotry不再屬于同一個類層次,看起來不再“水平”了。但是,這里強調的是Client的視角,從Client看來,ConcreteFactory4與ConcreteFactory1~3,從意義上是等價的,即創建一個系列的產品,且他們之間可以相互替換,以實現替換產品系列。即:從邏輯意義上看,還是可以看作“水平擴展”。

          再看Factory Method(留意圖中的深綠色箭頭及方向)::

          image

          Factory Method:子類(ConcreteCreator)重寫父類(Creator)的創建產品接口(FactoryMethod())。結合Factory Method的實用性及Application/Document的例子,ConcreteCreator該創建什么類型的Product,是依賴于ConcreteCreator自身封裝的邏輯來決定的(上一節介紹了,Creator/ConcreteCreator是具有現實意義的類),這里強調的是ConcreteCreator與Creator之間的繼承關系,它們處于不同的類層次,這就是我所謂的“垂直擴展”。

          補充:雖然可以增加ConcreteCreator3/ConcreteProduct3,如上圖所示,讓ConcreteCreator之間看起來不再垂直。但是,這里強調的是Creator與ConcreteCeator、以及Product與ConcreteProduct之間的關系。從Creator的Client(圖中沒有畫出)來看,不同的ConcreteCreator之間是不能替換的。譬如Application/Document的例子,當Client操作的是一個繪圖應用,則使用的必然是DrawingApplication和DrawingDocument,而不可能是TextApplication和TextDocument。雖然在“效果”一節中,GOF闡述到:Factory Method可以連接平行的類層次,并以Figure和Manipulator為例,如下圖所示:

      image

          從圖形結構上看,Creator(LineFigure和TextFigure等),與Product(LineManipulator和TextManipulator)之間是處于平行的類層次。但是值得注意的是:Product之間、TextManipulator之間,是不可替換的。Client面向接口(Figure和Manipulator)編程,當Client操作一條線段(Line)時,它必然要使用LineFigure和LineManipulator;而當Client操作一段文本(Text)時,也必然使用的是TextFigure和TextManipulator;ConcreteDocument依賴于Client的上下文才能確定,ConcreteFigure之間是不能相互替換的。抽象的Creator接口,不知道Client的上下文是什么,無從知曉該創建什么Product,于是就委托給子類來重寫。Factory Method強調的是Procuct與ConcreteProduct、Creator與ConcreteCreator之間的繼承關系,子類(ConcreteCreator)重寫父類(Creator)的創建產品接口(FactoryMethod()),從邏輯意義上講,可以看作“垂直擴展”。

          而在實現一節中,GOF給出的MazeGame的例子:

      image

          圖中省略了創建的產品。雖然這里可以認為EnchantedMazeGame與BomedMazeGame可以互換,但是留意MazeGame的職責(它是對具體事物[迷宮游戲]的抽象,而不僅僅是一個創建各個Product的接口),以及他的CreateMaze方法(該方法是一個模板方法)。這里反復強調的是繼承父類、重寫創建Product的接口。

      3.3 使用上:Abstract Factory的思想是聚合(Composition),而Factory Method的思想是繼承(Inheritance)

          GOF在介紹完5個創建型模式后,有一個討論小結:“用一個系統創建的那些對象的類對系統進行參數化有兩種常用方式:一種是生成創建對象的類的子類,這對應于Factory Method模式”;“另一種對系統進行參數化的方法更多的依賴于對象復合:定義一個對象負責明確產品對象的類,并將它作為該系統的參數,這就是Abstract Factory、Builder和Prototype模式的關鍵特征。”

          對于Factory Method,以Application/Document為例,Application(Creator)要使用Document(Product),把Document視為Application操作的一個“參數”,則特定的Document(ConcreteProduct)是由具體應用的Application(ConcreteCreator,Creator的子類)來創建的。

          對于Abstract Factory,來看看GOF介紹的實現:

      image

          畫得比較亂,湊合著看,呵呵。重點是左上方的紅色注釋部分,其演繹的就是Abstract Factory的Composition思想:MazeGame聚合了一個MazeFactory。

          另外兩個需要留意的地方:(1). 注意MazeFactory的職責:只是一組創建對象的接口;(2). MazeFactory包含了一組Factory Method。

       

      4. 總結

          Factory Method模式不是簡化版的Abstract Factory;相反,Abstract Factory模式中的Factory類,可以視為一個簡化版的Factory Method模式(例如本文開頭的兩個例子),其將Creator的職責單一化了,使之只具有創建的對象的職責。

          Factory Method與Abstract Factory,在效果上都可用于連接平行的類層次(Factory Method不限于此),但是這兩個模式在思想上有著本質的區別:

      1. 對象職責上:Abstract Factory中的Factory,只具有創建對象(一個產品系列)的唯一職責;而Factory Method中的Creator,具有實際的邏輯和意義。
      2. 擴展上:Abstract Factory側重水平擴展,而Factory Method側重垂直擴展。
      3. 使用上:Abstract Factory的思想是聚合,而Factory Method的思想是繼承。

         相關模式:Abstract Factory經常用工廠方法來實現。工廠方法通常在Template Method中被調用

      posted on 2010-09-26 19:50  Silent Void  閱讀(5989)  評論(10)    收藏  舉報

      主站蜘蛛池模板: 美乳丰满人妻无码视频| 亚洲熟女一区二区av| 动漫AV纯肉无码AV电影网| 国产日韩一区二区四季| 国产自产av一区二区三区性色| 国产精品成人中文字幕| 国产在线线精品宅男网址| 亚洲综合色成在线观看| 美女把尿囗扒开让男人添| 军人粗大的内捧猛烈进出视频| 艳妇乳肉豪妇荡乳在线观看| 国内精品自国内精品自久久| 国外av片免费看一区二区三区| 国产精品久久无码不卡黑寡妇| 日韩久久久久久中文人妻| 久久人妻少妇嫩草av无码专区| 无码伊人66久久大杳蕉网站谷歌| 亚洲av第三区国产精品| 亚洲高清WWW色好看美女| 巴里| 天天燥日日燥| 欧美综合婷婷欧美综合五月| 宝贝腿开大点我添添公口述视频| 久久久精品94久久精品| 亚洲国产成人无码网站大全| 天堂在线中文| 日韩av在线不卡一区二区三区| 水蜜桃精品综合视频在线| 乱人伦人妻中文字幕| 最新的国产成人精品2022| 1000部拍拍拍18勿入免费视频下载| 国产真实精品久久二三区| 永德县| 国产精品亚洲片夜色在线| 久久国产成人午夜av影院| 国产麻豆一区二区精彩视频| 亚洲av永久无码精品水牛影视 | 精品国产美女av久久久久| 香蕉在线精品一区二区 | 国产中文字幕精品免费| 久久精品熟女亚洲av麻|