当前位置:文档之家› 2015-OO-设计模式(1)(2)

2015-OO-设计模式(1)(2)

北京邮电大学计算机学院通信软件工程中心

设计模式(1)
4 用GoF设计模式设计用例实现
1. 2. 3. 4. 5. 6. 7.
适配器模式(GoF) 工厂模式(GoF) 单子模式(GoF) 策略模式(GoF) 组合模式(GoF) 外观模式(GoF) 观察者/发布-订阅/委托事件模式 (GoF)
《create》 Some App 《create》
<<Interface>> Shape
Square
Circle
15
4 用GoF设计模式设计用例实现2-工厂模式
改进:工厂模式允许我们只依赖于抽象接口就能创建出 具体类的实例。
public interface ShapeFactory { public Shape make(String shapeName) throws Exception; }
20
4 用GoF设计模式设计用例实现3-单子模式 Register对工厂类的调用:
public class Register { IAccountingAdapter accountingAdapter; public void initialize() { do some work ... accountingAdapter = ServicesFactory.getlnstance().getAccountingAdapter(); do some work ... } // other methods... }
4 用GoF设计模式设计用例实现2-工厂模式 –问题:当考虑某些特殊情况时,如复杂的创 建逻辑、希望分离创建职责以产生更好的内 聚度等,谁应该负责创建对象? –解决方案:创建一个名为工厂的纯虚构对象 来处理创建。
{ if ( taxCalculatorAdapter == null )
类型? 返回值类型?
6。工厂中如何与具体适配器类解耦 1)具体用哪个适配器?用属性来记录 System.setProperty("name","zhouchunyan") System.setProperty("", "TaxAAdaptor"); 2)工厂中的getTaxCalculatorAdaptor与具体适配器解耦 ITaxCalculatorAdaptor getTaxCalculatorAdaptor() { if(taxCalculatorAdaptor==null) { String className=System.getProperty(""); taxCalculatorAdaptor=Class.forname(className).newinstance() } return taxCalculatorAdaptor; }
ServicesFactory具有全局可见性
21
4 用GoF设计模式设计用例实现3-单子模式
通过单子模式 得到该实例的 可见性
ServicesFactory.getlnstance().getAccountingAdapter();
22
4 用GoF设计模式设计用例实现-外部接口变化的解决方案
register向外部SAP财务系统发送PostSale
17
4 用GoF设计模式设计用例实现3-单子模式
3.单子模式
–谁创建工厂类?如何访问此类? –事实:整个程序只需要一个工厂类的实例; 由于代码在不同的地方需要访问适配器以调 用外部系统的服务,所以工厂类的方法也需 要在代码的多个地方被调用。 –问题:一个类X只能有一个实例(这就是“单 子”的含义)。对象需要全局的可见性和单一 的访问点。 –解决方案:为类X定义静态方法getInstance, 该方法返回X的唯一实例。因为是静态方法, 所以可以全局访问,且该类的构造方法可见 性设为私有(private)。
代码中有两个容易变化的 地方:计算器的类名、计 算器提供的方法名
2。使用适配器来屏蔽接口的差异 class TaxAdaptor { TaxA tax=new TaxA(); float getTaxes() 3。代码变为 { TaxAdaptor adaptor ; return tax.tax(); adaptor =new TaxAAdaptor(); } adaptor.getTaxes(...);
现在,就剩红色字体处 要出来啦~ 继续想办法!
4 用GoF设计模式设计用例实现
1.适配器模式
–问题:如何解决接口不兼容的问题或为不同 接口但相似的组件提供一个稳定的接口? –解决方案:通过一个中间的适配器对象将组 件的原来接口转换为另一个接口。
6
4 用GoF设计模式设计用例实现-适配器模式 适配器模式类图
taxCalculatorAdaptor= (ITaxCalculatorAdaptor)Class.forName(className).newInstance(); } return taxCalculatorAdaptor; }
14
4 用GoF设计模式设计用例实现2-工厂模式
补充 依赖倒置原则(DIP)告诉我们应该优先依赖于抽象类, 而避免依赖于具体类。当这些具体类不稳定时,更应该 如此。 因此,下面的代码违反了这个原则 Circle c = new Circle();
13
4 用GoF设计模式设计用例实现2-工厂模式
注意:工厂方法返回对 象的类型是接口,而不 是类,这样工厂方法就 可以返回接口的任何实 现。
{
注意:在serviceFactory中,决定哪个类的实例 被初始化是从外部数据源读入类名(如在java 中可使用系统属性),然后动态装载此类来实
if(taxCalculatorAdaptor==null) 现的。 { String className=System.getProperty("");
10
5。应用工厂模式来屏蔽具体适配器 ITaxCalculatorAdaptor adaptor; ServiceFactory factory=new ServiceFactory(); 现在,代码彻底和具体 adaptor =factory.getTaxCalculatorAdaptor(); 的适配器类无关啦~~ adaptor.getTaxes(...);
18
4 用GoF设计模式设计用例实现3-单子模式
//单子方法getlnstance返回工厂类的唯一实例
public static synchronized ServicesFactory getlnstance() { if ( instance == null ) instance = new ServicesFactory(); return instance;
9
4 用GoF设计模式设计用例实现2-工厂模式
2.工厂模式
–考虑:在前面外部服务适配器解决方案中, 谁去负责创建这些适配器?谁去确定要创建 的是哪个适配器,是TaxMasterAdapter 还是
GoodAsGoldTaxProAdapter?
–让领域类(如Sale)来创建适配器对象是否 合适?--如此则领域类不只是包含应用逻辑 了! –一个设计原则:设计要保证分离不相关的事 物。分离不同的事物到不同的领域,从而使 得分离的各部分能达到高内聚的设计目标。
}
接口统一了,但是代码 还是和具体的类耦合! 继续想办法!
TaxBdaptor adaptor ; adaptor =new TaxBAdaptor(); adaptor.getTaxes(...);
4。创建适配器的抽象来屏蔽不同的适配器 ITaxCalculatorAdaptor adaptor ; adaptor =new TaxAAdaptor(); adaptor.getTaxes(...); ITaxCalculatorAdaptor adaptor ; adaptor =new TaxBAdaptor(); adaptor.getTaxes(...);
–register从工厂类中获取针对SAP财务系统的适配器 SAPAccountingAdaptor; –Register向SAPAccountingAdaptor发送PostSale消 息,由适配器将消息适配后转发给外部SAP财务系统。
请画出以上交互的顺序图
23
4 用GoF设计模式设计用例实现-外部接口变化的解决方案
19
4 用GoF设计模式设计用例实现3-单子模式
Synchronized解释:单子类的 getInstance方法经常被调用,在多线程 (MultiThread)的应用程序里,在某一 客户端线程调用getInstance方法前,必 须先把该方法锁住,以防止其他客户端调 用该方法;当方法调用完毕后,再把锁打 开,让其他客户端线程可以调用该方法。 从而实现线程的并发控制。
适配器模式、多态模式、工厂模式、单子模式的综合运用
24
4 用GoF设计模式设计用例实现4-策略模式
目的:实现复杂的定价规则。
–商店的定价策略可能变化。对变化的定价算 法我们应如何设计?
策略模式
–语境/问题:如何对变化或与变化相关的算法 或策略进行设计?如何设计系统使得其具有 改变算法或策略的能力? 解决方案:在单独的类中分别定义每种算法、 策略和政策,并且使其具有公共接口。
16
4 用GoF设计模式设计用例实现2-工厂模式
public class ShapeFactoryImplementation implements ShapeFactory { public Shape make(String shapeName) throws Exception { if (shapeName.equals("Circle")) return new Circle(); else if (shapeName.equals("Square")) return new Square(); else throw new Exception("ShapeFactory cannot create " + shapeName); } }
相关主题