当前位置:
文档之家› GOF几种设计模式举例及其应用
GOF几种设计模式举例及其应用
此,我们对 Sale 对象附加的策略既可以是组合的 CompositeBestForCoustomerstrategy 对象,又可以是原子的 PercentDiscountPricingStrategy 对象。Sale 不关心其定价策略 是组合的还是原子的。
策略(strategy) 销售的定价策略有多样性,一段时期内对于所有的销售可能会有 10%的折扣,后
单实例类(Singleton) 工厂设计模式也称为简单工厂,经常描述为抽象工厂的变种。工厂设计模式引发
出另一个新的问题,即谁来创建工厂自身和如何访问工厂。 代码在不同的位置都需要访问适配器以调用外部服务,所以就需要代码在不同的
位置调用工厂中的方法。在这里就存在可见性的问题,即如何获得单个工厂实例的 可见性以及单点访问。
add(ISalePricingStrategy) getTotal(sale) : Money
getTotal(sale) : Money
CompositeBestForCous tomerstrategy
getTotal(sale) : Money
CompositeBestForSt oreStrategy
PercentDiscountPrici ngStrategy
percentage : float
getTotal(sale) : Money
AbsluteDiscountOverThresho
ldPricingStrategy
CompositePricingStrategy
discount : Money threshold : Money
GoF 几种设计模式举例及其应用
1090379131 易余
GOF 即 Gang of Four,就 Java 语言体系来说,GOF 的设计模式是 Java 基础知识 和 J2EE 框架知识之间一座隐性的"桥"。实际上,GoF 的设计模式并不是一种具体" 技术",它讲述的是思想,它不仅仅展示了接口或抽象类在实际案例中的灵活应用和 智慧,让你能够真正掌握接口或抽象类的应用,从而在原来的 Java 语言基础上跃进 一步,更重要的是,GoF 的设计模式反复向你强调一个宗旨:要让你的程序尽可能的 可重用。本文介绍几种常用的设计模式的举例和应用。
//static method public static synchronized ServicesFactory getInstance() { if(instance==null) instance=new ServicesFactory() return instance }
观察者模式(Observer) 观察者模式支持低耦合,它允许现有视图或者表示层使用新的窗口来代替特定的
解决方案为:定义观察者接口,观察者实现此接口。对象可以动态关注某事件的 观察者,并在事件发生时通知他们。下图描述了此类解决方案。
{ for each PropertyListener pl in Propert (this,name,value) }
GreatNorthernAccountingAdapter
postReceivable(CreditPayment) postSale(Sale)
如上图所示,对于选定的外部服务,将选用一个特定的适配器实例来表示。例如 针对账务系统的 SAP,当向外部接口发出 postSale 请求时,首先通过适配器进行转 换,使其能够通过 HTTP 上的 SOAP XML 接口来访问在 SAP 在局域网上提供的 Web Service。
AbsoluteDiscountOverThresh oldPricingStrategy
discount : Money threshold : Money
getTotal(sale) : Money
策略对象依附于语境对象,本例中,语境对象是 Sale。当 getTotal 消息发送给 Sale 时,它会把工作委派给它的策略对象。类型为 Sale 的 S 被传递给了策略,因此 策略对象在将来的协作中对其具有参数可见性。
*
<<Interface>>
propertyListener
{ total=newTotal publishPropertyEvent ("sale.total",total) }
setTitle() setVisible()
onPropertyEvent(source,name,value)
SaleFrame1
事件的通知。也就是说总额变化时,该窗口会得到通知。 Sale 并不知道 SaleFrame1 对象,它只知道实现了 PropertyListener 对象。这
样就降低了 Sale 和窗口的耦合。 Sale 实例就成为了特性事件的发布者,当总额发生变化时,它会遍历所有订阅
了的 PropertyListener,并且通知每一个订阅者。 SaleFrame1 就是观察者
由于公共类的可见性是全局的,因此代码的任何一点,在类的任何方法中,都可 以写为:
SingletonClass.getInstance() 例如 SingletonClass.getInstance().doFoo(),这种写法就是为了获得对于单 实例类的实例可见性,并且对其发送消息。 单实例类还存在另一个问题,为什么不将所有服务的方法都定义成类自己的静态 方法,而是使用有实例方法的实例对象?原因如下: 实例方法允许定义单实例类的子类以对其进行精化。静态的方法不是多态的,而 且大多数语言中不允许在子类中对其覆写。 大多数面向对象的远程通信机制只支持实例方法的远程使用而不支持静态方法。 类并非在所有的场景中都是单实例类。在一个应用中是单实例的,而在另一个实 例中却可能是多实例的,并且在开始设计的时候考虑使用单实例的不多见。因此使 用实例方法的解决方案有更大的灵活性。
TaxMasterAdapter
getTaxes(Sale) : List of TaxLineItem
<<Interface>>
IAccountingAdapter
postReceivable(CreditPayment) postSale(Sale)
SAPAccountingAdapter
postReceivable(CreditPayment) postSale(Sale)
sale
data
getTotal()
pri ci ngStrategy
<<Interface>>
IsalePricingStrategy
1 getTotal(sale) : Money
PercentDiscountPrici ngStrategy
percentage : float
getTotal(sale) : Money
组合(Composite) 商场有不同的定价策略,一般商店在解决冲突策略时会应用“对顾客最有利”的
策略来解决冲突。但有时在财政困难时期,商店也会采用最高价格的策略来解决冲 突。
因此商场存在多个策略,同样定价策略可以与所购买的产品类型相关,那么如何 能够像处理非组合对象一样,多态地处理一组对象或者具有组合结构的对象?
getInstance() : ServicesFactory getAccountingAdapter() : IAccountingAdapter getInventoryAdapter() : IInventoryAdapter getCalculatorAdapter() : ICalculatorAdapter
解决方案:对类定义静态方法返回单实例。其中的关键思想是,对类定义静态方 法 getInstance,该方法提供了类的唯一实例。例如:
public class Register {
public void Initialize { … do some work … AccountingAdapter=ServicesFactory.getInstance().getAccountingAdapter(); … do somework … } }
窗口,同时不会对非 UI 对象产生影响。例如,如果模型对象不知道 Java Swing 对 象,那么久可以拔掉 Swing 接口或者特定的窗口,然后插入其他的东西。
不同类型的观察者关注观察对象的状态变化或事件,并且在观察对象产生事件时 以自己独特的方式的做出反应。观察对象与观察者保持低耦合,就使用观察者设计 模式。
ServicesFactory
instance : ServicesFactory accountingAdapter : IAccountingAdapter inventoryAdapter : IInventoryAdapter calculatorAdapter : ICalculatorAdapter
这里提出的解决方案是:采用组合模式,定义组合和原子对象的类,使他们实现 相同的接口。如下图所示。
sale
data
getTotal()
pri ci ngStrategy
<<Interface>>
IsalePricingStrategy
1 getTotal(sale) : Money
1..*
strategies
{ PropertyListener.add(lis) }
Sale
addPropertyListener(PropertyListener lis) publishPropertyEvent(name,value) setTotal(Money newTotal)
javax.swing.JFrame
onPropertyEvent(source,name,value) initialize(Sale sale)