分享
 
 
 

爪哇语言工厂方法创立性模式介绍(下)

王朝other·作者佚名  2008-05-19
窄屏简体版  字體: |||超大  

package com.javapatterns.factorymethod;

public class BadPlantException extends Exception

{

public BadPlantException(String msg)

{

super(msg);

}

}

代码清单6. 例外类 BadPlantException。

工厂方法模式应该在什么情况下使用

既然工厂方法模式与简单工厂模式的区别很是微妙,那么应该在什么情况下使用工厂方法模式,又应该在什么情况下使用简单工厂模式呢?

一般来说,假如你的系统不能事先确定那一个产品类在哪一个时刻被实例化,从而需要将实例化的细节局域化,并封装起来以分割实例化及使用实例的责任时,你就需要考虑使用某一种形式的工厂模式。

在我们的小花果园系统里,我们必须假设水果的种类随时都有可能变化。我们必须能够在引入新的水果品种时,能够很少改动程序,就可以适应变化以后的情况。因此,我们显然需要某一种形式的工厂模式。

假如在发现系统只用一个产品类等级(hierarchy)就可以描述所有已有的产品类,以及可预见的未来可能引进的产品类时,简单工厂模式是很好的解决方案。因为一个单一产品类等级只需要一个单一的实的工厂类。

然而,当发现系统只用一个产品类等级不足以描述所有的产品类,包括以后可能要添加的新的产品类时,就应当考虑采用工厂方法模式。由于工厂方法模式可以容许多个实的工厂类,以每一个工厂类负责每一个产品类等级,因此这种模式可以容纳所有的产品等级。

在我们的小花果园系统里,不只有水果种类的植物,而且有蔬菜种类的植物。换言之,存在不止一个产品类等级。而且产品类等级的数目也随时都有可能变化。因此,简单工厂模式不能满足需要,为解决向题,我们显然需要工厂方法模式。

关于模式的实现

在实现工厂方法模式时,有下面一些值得讨论的地方。

第一丶在图四的类图定义中,可以对抽象工厂(Creator) 做一些变通。变通的种类有

抽象工厂(Creator) 不是接口而是抽象类。一般而言,抽象类不提供一个缺省的工厂方法。 这样可以有效地解决怎样实例化事先不能预知的类的问题。

抽象工厂(Creator) 本身是一个实类,并提供一个缺省的工厂方法。 这样当最初的设计者所预见的实例化不能满足需要时,后来的设计人员就可以用实工厂类的factory() 方法来置换(Override))父类中factory()方法。

第二丶在经典的工厂方法模式中,factory()方法是没有参量的。在本文举例时加入了参量,这实际上也是一种变通。

第三丶在给相关的类和方法取名字时,应当注重让别人一看即知你是在使用工厂模式。

COM技术架构中的工厂方法模式

在微软(Microsoft)所提倡的COM(Component Object Model)技术架构中, 工厂方法模式起着要害的作用。

在COM架框里,Creator接口的角色是由一个叫作IClassFactory的COM接口来担任的。而实类ConcreteCreator的角色是由实现IClassFactory接口的类CFactory(见下图)来担任的。一般而言,对象的创立可能要求分配系统资源,要求在不同的对象之间进行协调等等。因为IClassFactory的引进,所有这些在对象的创立过程中出现的细节问题, 都可以封装在一个实现IClassFactory接口的实的工厂类里面。这样一来, 一个COM架构的支持系统只需要创立这个工厂类CFactory的实例就可以了。

图6. 微软(Microsoft)的COM(Component Object Model)技术架构是怎样工作的。

在上面的序列活动(Sequence Activity)图中,用户端调用COM的库函数CoCreateInstance。 CoCreateInstance在COM架框中以CoGetClassObject实现。 CoCreateInstance会在视窗系统的Registry里搜寻所要的部件(在我们的例子中即CEmployee)。假如找到了这个部件,就会加载支持此部件的DLL。当此DLL加载成功后, CoGetClassObject就会调用DllGetClassObject。后者使用new操作符将工厂类CFactory实例化。

下面,DllGetClassObject会向工厂类CFactory搜询IClassFactory接口,返还给CoCreateInstance。 CoCreateInstance接下来利用IClassFactory接口调用CreateInstance函数。此时,IClassFactory::CreateInstance调用new操作符来创立所要的部件(CEmployee)。此外,它搜询IEmployee接口。在拿到接口的指针后, CoCreateInstance释放掉工厂类并把接口的指针返还给客户端。

客户端现在就可以利用这个接口调用此部件中的方法了。

EJB技术架构中的工厂方法模式

升阳(Sun Microsystem)倡导的EJB(EnterPRise Java Beans)技术架构是一套为爪哇语言设计的, 用来开发企业规模应用程序的组件模型。我们来举例看一看EJB架构是怎样利用工厂方法模式的。请考察下面的序列活动图。

图7. 在升阳所提倡的EJB技术架构中, 工厂方法模式也起着要害的作用

在上面的图中,用户端创立一个新的 Context 对象,以便利用 JNDI 伺服器寻找 EJBObject。在得到这个 Context 对象后,就可以使用 JNDI 名, 比如"Employee", 来拿到 EJB 类 Employee 的 Home 接口。使用 Employee 的 Home 接口,客户端可以创立 EJB 对象,比如 EJB 类 Employee 的实例 emp, 然后调用 Employee 的各个方法。

// 取到 JNDI naming context

Context ctx = new InitialContext ();

// 利用ctx 索取 EJB Home 接口

EmployeeHome home = (EmployeeHome)ctx.lookup("Employee");

// 利用Home 接口创立一个 session Bean 对象

// 这里使用的是标准的工厂方法模式

Employee emp = home.create (1001, "John", "Smith");

// 调用方法

emp.setTel ("212-657-7879");

代码清单7. EJB架构中,Home接口提供工厂方法以便用户端可以动态地创立EJB类Employee的实例。

JMS技术架构中的工厂方法模式

JMS定义了一套标准的API,让爪哇语言程序能通过支持JMS标准的MOM(Message Oriented Middleware 面向消息的中间伺服器)来创立和交换消息(message)。我们来举例看一看JMS(Java Messaging Service)技术架构是怎样使用工厂方法模式的。

图8. 在JMS技术架构中, 工厂方法模式无处不在

在上面的序列图中,用户端创立一个新的 Context 对象,以便利用 JNDI 伺服器寻找 Topic 和 ConnectionFactory 对象。在得到这个 ConnectionFactory 对象后, 就可以利用 Connection 创立 Session 的实例。有了 Session 的实例后,就可以利用 Session 创立 TopicPublisher的实例,并利用Session创立消息实例。

Properties prop = new Properties();

prop.put(Context.INITIAL_CONTEXT_FACTORY,

"com.sun.jndi.fscontext.RefFSContextFactory");

prop.put(Context.PROVIDER_URL, "file:C:\temp");

// 取到 JNDI context

Context ctx = new InitialContext(prop);

// 利用ctx 索取工厂类的实例

Topic topic = (Topic) ctx.lookup("myTopic");

TopicConnectionFactory tcf = (TopicConnectionFactory) ctx.lookup("myTCF");

// 利用工厂类创立Connection,这是典型的工厂模式

TopicConnection tCon = tcf.createTopicConnectoin();

// 利用Connection创立Session的实例,又是工厂模式

TopicSession tSess = tCon.createTopicSession(false,

Session.AUTO_ACKNOWLEDGE);

// 利用Session创立ProdUCer的实例,又是工厂模式

TopicPublisher publisher = tSess.createPublisher(topic);

// 利用Session创立消息实例,又是工厂模式

TextMesage msg = tSess.createTextMessage("Hello from Jeff");

//发送消息

publisher.publish(msg);

代码清单8.

JMS架构中,工厂模式被用于创立 Connection, Session, Producer 的实例。

问答题

第1题、在这一节和上一节的类图中,我注重到Apple类的类图与Strawberry类的类图有一点点不同。在Apple类的类图左上角有一个夹子样的标识。请问这个标识代表什么意思。

第2题、在这一节的类图4中,我注重到 ConcreteProduct 类只出现一次,但实现 Product 接口的类实际上可以有很多。这是否可以用在联接 Product 和 ConcreteProduct 之间的线旁注上 1,2,... 表示呢? 记得我在UML图中曾见过这种记号。

第3题、请问在本节的小花果园系统的源代码清单4里,Broccoli 类实现两个接口,VeggieIF 和 PlantIF。只有 PlantIF 才与工厂模式有关。为什么不把 VeggieIF 接口合并到 PlantIF 接口中去?

第4题、请问在工厂方法模式中,产品(Product) 何时应是抽象类,何时应是接口?

第5题、请问在工厂方法 (factory())中,为什么要使用 if 语句作过程性判定来决定创立哪一个产品类,而不使用多形性原则 (Polymorphsm) 来创立产品类?

问答题答案

第1题、Apple类有性质(property),而Strawberry类没有性质。

一个类的成员变量叫做属性(attribute)。性质与属性的区别在于性质是带着一套取值丶赋值方法的属性。一个类有了属性,其类图左上角就会有一只夹子。有些人认为,一个爪哇类有了属性才能被称做爪哇豆(Java Bean)。这只夹子就表示这个类是一只豆。

一个企业爪哇豆,或 EJB (Enterprise JavaBean) 的类图左上角也会有一只夹子,夹子上面有一个E字以示与普通的爪哇豆的不同(请见下图)。

第2题、不能。在图4中联接 Product 和 ConcreteProduct 之间的线有两条,一条表示两者之间的推广关系 (即有向上箭头的),另一条表示两者之间

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有