电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術文章
文章詳情頁

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

瀏覽:45日期:2024-06-30 08:34:00
內容: (來源:http://www.cn.ibm.com/developerWorks) 內容: 基本概念 簡單分析 具體實施 后話: 參考資料 關于作者 劉湛 (jeru@163.net)武漢大學信息與計算科學系學士2001 年 9 月在設計模式中,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 實例的 CircleFactoryclass CircleFactory extends ShapeFactory { // 重載factoryMethod方法,返回Circle對象 protected Shape factoryMethod(String aName) { return new Circle(aName + ' (created by CircleFactory)'); }} // 定義返回 Square 實例的 SquareFactoryclass 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); else if (aType.compareTo('circle')==0) return new Circle(aName); else throw new NoThisShape(aType); } // 在anOperation中定義Shape的一系列行為 static void anOperation(String aName, String aType) throws NoThisShape{ s = factoryMethod(aName, aType); System.out.println('The current shape is: ' + s.name); s.draw(); s.erase(); }} 2.c 測試類:這里客戶端必須指定參數來決定具體創建哪個類.這個例子里的anOperation是靜態函數,可以直接引用. class Main { public static void main(String[] args) throws NoThisShape{ ShapeFactory.anOperation('Shape one','circle'); ShapeFactory.anOperation('Shape two','square'); ShapeFactory.anOperation('Shape three', 'delta'); }} 運行結果如下: The current shape is: Shape oneIt will draw a circle.It will erase a circle.The current shape is: Shape twoIt will draw a square.It will erase a square.Exception in thread 'main' NoThisShape: delta at ShapeFactory.factoryMethod(ShapeFactory.java:10) at ShapeFactory.anOperation(ShapeFactory.java:15) at Main.main(Main.java:5) 動態裝載機制: 有的時候我們會把ConcreteProduct的實例傳給創建器作為參數,這種情況下,如果在創建器里完成創建過程,就必須判斷參數的具體類型(用instanceof),然后才能產生相應的實例,那么比較好的做法是利用Java的動態裝載機制來完成這件事.比如:我們得到一個Shape的子類s,但不知道具體是那個子類,就可以利用Class類自帶的方法newInstance()得到實例return (Shape)s.getClass().newInstance(); 這種方法有興趣得讀者可以自己嘗試,限于篇幅,不寫具體代碼出來了.后話: 看完這篇文章后,相信讀者對Factory Method模式有一個比較清楚的了解了.我想說的是,我們不僅應該關心一個具體的模式有什么作用,如何去實現這個模式,更應該透過現象看本質,不但知其然,還要知其所以然.要通過對模式的學習加深對面向對象思想的理解,讓自己的認識得到升華.Factory Method模式看似簡單,實則深刻.抽象,封裝,繼承,委托,多態,針對接口編程等面向對象中的概念都在這里得到了一一的體現.只有抓住了它的本質,我們才能夠不拘于形式的靈活運用,而不是為了使用模式而使用模式.參考資料 Thinking in Pattern with Java ---- Bruce Eckel The Factory Method Design Pattern by Gopalan Suresh Raj---- http://gsraj.tripod.com/design/creational/factory/factory.html SENG609_40 FACTORY PATTERNS PAPER---- http://sern.ucalgary.ca/~kjfu/courses/SENG60904/paper.html Factory Method Pattern---- http:// www.ugolandini.net/FactoryMethodPattern.html Design Patterns in Java ---- Bob Tarr Design Patterns ---- Gang of Four Dynamic Class Loading in Java---- http:// www.pramodx.20m.com/dynamic_class_loading_in_java.htm 關于作者 劉湛,武漢大學信息與計算科學系學士,熟悉 Java 語言和 J2EE 思想,國內多個 Java 論壇版主,現致力于 J2EE 平臺上的 eCRM 套件開發。你可以通過jeru@163.net與他聯系! Java, java, J2SE, j2se, J2EE, j2ee, J2ME, j2me, ejb, ejb3, JBOSS, jboss, spring, hibernate, jdo, struts, webwork, ajax, AJAX, mysql, MySQL, Oracle, Weblogic, Websphere, scjp, scjd
標簽: Java
相關文章:
主站蜘蛛池模板: 最新电影-好看的电视剧大全-朝夕电影网 | 铝单板_铝窗花_铝单板厂家_氟碳包柱铝单板批发价格-佛山科阳金属 | 节流截止放空阀-不锈钢阀门-气动|电动截止阀-鸿华阀门有限公司 | 小程序开发公司_APP开发多少钱_软件开发定制_微信小程序制作_客户销售管理软件-济南小溪畅流网络科技有限公司 | 一礼通 (www.yilitong.com)-企业礼品解决方案一站式服务平台 | 施工电梯_齿条货梯_烟囱电梯_物料提升机-河南大诚机械制造有限公司 | 澳威全屋定制官网|极简衣柜十大品牌|衣柜加盟代理|全屋定制招商 百度爱采购运营研究社社群-店铺托管-爱采购代运营-良言多米网络公司 | 拖鞋定制厂家-品牌拖鞋代加工厂-振扬实业中国高端拖鞋大型制造商 | 高柔性拖链电缆-聚氨酯卷筒电缆-柔性屏蔽电缆厂家-玖泰电缆 | 湖州织里童装_女童男童中大童装_款式多尺码全_织里儿童网【官网】-嘉兴嘉乐网络科技有限公司 | 西安展台设计搭建_西安活动策划公司_西安会议会场布置_西安展厅设计西安旭阳展览展示 | 硫化罐-胶管硫化罐-山东鑫泰鑫智能装备有限公司 | 高铝砖-高铝耐火球-高铝耐火砖生产厂家-价格【荣盛耐材】 | 诗词大全-古诗名句 - 古诗词赏析 | 产业规划_产业园区规划-产业投资选址及规划招商托管一体化服务商-中机院产业园区规划网 | 锂辉石检测仪器,水泥成分快速分析仪-湘潭宇科分析仪器有限公司 | 二手注塑机回收_旧注塑机回收_二手注塑机买卖 - 大鑫二手注塑机 二手光谱仪维修-德国OBLF光谱仪|进口斯派克光谱仪-热电ARL光谱仪-意大利GNR光谱仪-永晖检测 | 首页|专注深圳注册公司,代理记账报税,注册商标代理,工商变更,企业400电话等企业一站式服务-慧用心 | 宁夏档案密集柜,智能密集柜,电动手摇密集柜-盛隆柜业宁夏档案密集柜厂家 | 郑州外墙清洗_郑州玻璃幕墙清洗_郑州开荒保洁-河南三恒清洗服务有限公司 | 移动厕所租赁|移动卫生间|上海移动厕所租赁-家瑞租赁 | 微动开关厂家-东莞市德沃电子科技有限公司 | 单级/双级旋片式真空泵厂家,2xz旋片真空泵-浙江台州求精真空泵有限公司 | 卡诺亚轻高定官网_卧室系统_整家定制_定制家居_高端定制_全屋定制加盟_定制家具加盟_定制衣柜加盟 | 河北码上网络科技|邯郸小程序开发|邯郸微信开发|邯郸网站建设 | 一体化污水处理设备_生活污水处理设备_全自动加药装置厂家-明基环保 | 生物风-销售载体,基因,质粒,ATCC细胞,ATCC菌株等,欢迎购买-百风生物 | 注浆压力变送器-高温熔体传感器-矿用压力传感器|ZHYQ朝辉 | 加中寰球移民官网-美国移民公司,移民机构,移民中介,移民咨询,投资移民 | 净化工程_无尘车间_无尘车间装修-广州科凌净化工程有限公司 | 包头市鑫枫装饰有限公司| 北京普辉律师事务所官网_北京律师24小时免费咨询|法律咨询 | 定坤静电科技静电消除器厂家-除静电设备 | 【黄页88网】-B2B电子商务平台,b2b平台免费发布信息网 | 湖南档案密集架,智能,物证,移动,价格-湖南档案密集架厂家 | 广东恩亿梯电源有限公司【官网】_UPS不间断电源|EPS应急电源|模块化机房|电动汽车充电桩_UPS电源厂家(恩亿梯UPS电源,UPS不间断电源,不间断电源UPS) | 方源木业官网-四川木门-全国木门专业品牌 | 牛奶检测仪-乳成分分析仪-北京海谊| 棕刚玉_白刚玉_铝酸钙-锐石新材料 | 粘度计,数显粘度计,指针旋转粘度计 | 阿米巴企业经营-阿米巴咨询管理-阿米巴企业培训-广东键锋企业管理咨询有限公司 |