[DP]Bridge设计模式

来源:互联网 发布:java入门到精通pdf 编辑:程序博客网 时间:2024/04/29 15:38

这次我们继续接着我们的KFGStoe连锁餐厅

我们的KFG连锁餐厅在全国各地都有连锁加盟,因为各地的口味风俗差异,所以我们的KFG餐厅都是非常具有地方特色的。

用马克思主义讲,就是我们的KFG餐厅因地制宜,将KFG餐饮风格与地方特色相结合。

什么是地方特色,就是我们的KFG餐厅根据当地饮食习惯制作出符合当地饮食的料理,店面装修也具有当地的特色。

所以这个时候我们就有了北京小清新风格KFG餐厅,北京豪华风格KFG餐厅,南京小清新风格KFG餐厅,南京豪华风格KFG餐厅。

假如我们用程序代码来表示就是

class NanjingXiaoQingXinKFGStore {private KGFFoodLine foodLine = new NanjingFoodLine();// ...小清新风格的装饰}class NanjingHaoHuaKFGStore {private KGFFoodLine foodLine = new NanjingFoodLine();// ...豪华风格的装饰}class BeijingXiaoQingXinKFGStore {private KGFFoodLine foodLine = new BeijingFoodLine();// ...小清新风格的装饰}class BeijingHaoHuaKFGStore {private KGFFoodLine foodLine = new BeijingFoodLine();// ...豪华风格的装饰}

这个时候问题来了,全国至少上千个城市,那么我们的 不同装修风格的 *  地方饮食 将会是一个很庞大的数字,我们是不是真的要写出这么多类来?


这种将风格与特色相互仅仅结合的设计 并不是我们想要的,我们想要的是可以扩展的。

那么怎么扩展呢?

我们只要有一类通用的KFGStore 不管我们是北京小清新风格KFG餐厅,北京豪华风格KFG餐厅,南京小清新风格KFG餐厅,南京豪华风格KFG餐厅。

它们都是KFG餐厅,它们的主要职责都是服务顾客,让顾客在店内有着良好的心情。

至此我们需要抽取店内的共性,然后离散特性。

interface KGFFoodLine {public Food cookChip();public Food cookHamberger();public Food cookChicken();}class BeijingFoodLine implements KGFFoodLine {@Overridepublic Food cookChip() {return new Chip("Beijing Chip");}@Overridepublic Food cookHamberger() {return new Hamburger("Beijing Hamberger");}@Overridepublic Food cookChicken() {return new Chicken("Beijing Chicken");}}class NanjingFoodLine implements KGFFoodLine {@Overridepublic Food cookChip() {return new Chip("Nanjing Chip");}@Overridepublic Food cookHamberger() {return new Hamburger("Nanjing Hamberger");}@Overridepublic Food cookChicken() {return new Chicken("Nanjing Chicken");}}interface Cook {public Food cook(FoodType type);}abstract class KFGStore implements Cook {private KGFFoodLine foodLine;public void setFoodLine(KGFFoodLine foodLine) {this.foodLine = foodLine;}@Overridepublic Food cook(FoodType type) {switch (type) {case CHIP:return foodLine.cookChip();case HAMBURGER:return foodLine.cookHamberger();case CHICKEN:return foodLine.cookChicken();default:break;}return null;}abstract public void decoratePatternDescribe();}class QingXinKFGStore extends KFGStore {// ...小清新风格的装饰@Overridepublic void decoratePatternDescribe() {// TODO Auto-generated method stub}}class HaoHuaKFGStore extends KFGStore {// ...豪华风格的装饰@Overridepublic void decoratePatternDescribe() {// TODO Auto-generated method stub}}



 解决方案:

桥连模式:将抽象部分与实现部分分离,使它们都可以独立的变化。它是一种结构性模式,又称柄体(Handle and body)模式或者接口(Interface)模式。        当一个抽象可能有多个实现时,通常用继承来协调他们。抽象类的定义对该抽象的接口。而具体的子类则用不同的方式加以实现,但是此方法有时不够灵活。继承机制将抽象部分与他的视线部分固定在一起,使得难以对抽象部分和实现部分独立地进行修改、扩充和充用。

理解桥接模式,重点需要理解如何将抽象化(Abstraction)与实现化(Implementation)脱耦,使得二者可以独立地变化。



构建模式的组成
抽象类(Abstraction):定义抽象类的接口,维护一个指向Implementor类型对象的指针
扩充抽象类(RefinedAbstraction):扩充由Abstraction定义的接口
实现类接口(Implementor):定义实现类的接口,该接口不一定要与Abstraction的接口完全一致;事实上这两个接口可以完全不同。一般来讲, Implementor接口仅提供基本操作,而 Abstraction则定义了基于这些基本操作的较高层次的操作。
具体实现类(ConcreteImplementor):实现Implementor接口并定义它的具体实现。



按照上述定义,我们寻找该模式的角色对应关系吧。

抽象类:KFGStore,持有一个KFGFoodLine 接口,该接口的具体实现提供不同风格的地方美食。同时定义了一个描述装饰样式的抽象方法,由子类去实现。

扩充抽象类:QingXinKFGStore,HaoHuaKFGStore。对抽象类的方法进行实现,以产生不同装修风格的餐厅。

实现类接口:KFGFoodLine,制作各种美食,提供烹制各种各样美食的基本操作,具体怎么组合,在抽象类中依据顾客的请求合理的调用foodLine.cookxxx()

具体实现:NanjingFoodLine,BeijingFoodLine。按照接口产生独特的美食。


假设 我们 原来有 4种装修 风格, 4 种 美食风格,按照原先的设计方式,那么我们将会得到 4 x 4个类。

但是改进之后 使用Bridge设计模式后, 我们只要 4 + 4个类即可。


我这里需要强调一个问题,那就是使用桥接模式的主要目的并不是减少类,而是将抽象和实现解耦,分离接口及其实现部分,提高可扩充性。


适用性
1). 你不希望在抽象和他的实现部分之间有一个固定的绑定关系,如在程序的运行时刻实现部分应该可以被选择或者切换。
2). 类的抽象以及他的视像都可以通过生成子类的方法加以扩充。这时bridge模式使你可以对不同的抽象接口和实现部分进行组合,并对他们进行扩充。
3). 对一个抽象的实现部分的修改应该对客户不产生影响,即客户的代码不需要重新编译。
4). 你想对客户完全隐藏抽象的实现部分。
5). 你想在多个实现间 共享实现,但同时要求客户并不知道这一点。




这里举spring中ClassPathApplicationContext类作为例子。

我们都知道ClassPathApplicationContext里面有个getBean方法,而这个getBean是BeanFactory接口的实现。

package org.springframework.beans.factory;import org.springframework.beans.BeansException;import org.springframework.core.ResolvableType;public interface BeanFactory {String FACTORY_BEAN_PREFIX = "&";Object getBean(String name) throws BeansException;<T> T getBean(String name, Class<T> requiredType) throws BeansException;<T> T getBean(Class<T> requiredType) throws BeansException;Object getBean(String name, Object... args) throws BeansException;<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;boolean containsBean(String name);boolean isSingleton(String name) throws NoSuchBeanDefinitionException;boolean isPrototype(String name) throws NoSuchBeanDefinitionException;boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException;Class<?> getType(String name) throws NoSuchBeanDefinitionException;String[] getAliases(String name);}
而该ClassPathApplicationContext中getBean的实现则是从其父类AbstractApplicationContext实现的。

AbstractApplicationContext:

@Overridepublic Object getBean(String name) throws BeansException {assertBeanFactoryActive();return getBeanFactory().getBean(name);}@Overridepublic <T> T getBean(String name, Class<T> requiredType) throws BeansException {assertBeanFactoryActive();return getBeanFactory().getBean(name, requiredType);}@Overridepublic <T> T getBean(Class<T> requiredType) throws BeansException {assertBeanFactoryActive();return getBeanFactory().getBean(requiredType);}@Overridepublic Object getBean(String name, Object... args) throws BeansException {assertBeanFactoryActive();return getBeanFactory().getBean(name, args);}@Overridepublic <T> T getBean(Class<T> requiredType, Object... args) throws BeansException {assertBeanFactoryActive();return getBeanFactory().getBean(requiredType, args);}

该父类中的getBeanFactory()实际上是从其父类中继承下来的,对其不可见,只提供了公共接口getBeanFactory()访问

实际上等同于

beanFactory.getBean()


而这里我们的具体BeanFactory实现类则是DefaultListableBeanFactory

ClassPathApplicationContext 并不是唯一的context,还有WebApplicationContext,AnnotationApplicationContext等。

所以我们这里整理一下思路,按照之前的角色划分整理:

抽象类(Abstraction): AbstractApplicationContext

扩充抽象类(RefinedAbstraction):ClassPathApplicationContext,WebApplicationContext,AnnotationApplicationContext
实现类接口(Implementor):BeanFactory。
具体实现类(ConcreteImplementor):DefaultListableBeanFactory




0 0
原创粉丝点击