桥接模式之我见

背景

      最近一直在研究用户账户体系相关的内容,尤其是安全方面。一些基本的代码逻辑,总是有人遗漏,说是安全问题,倒不如说是代码的逻辑不严谨,说是bug也不为过。规则逻辑大家都很清楚,但是落地实现却是千人前面,千疮百孔。从管理侧,天天苦口婆心的敦敦教诲,结果总是不如人意。于是乎,我们需要反思自己:当一件事,总是做不好的时候,在不怀疑自己的基础上,只能怀疑我们使用的方式方法是否合理。需要从架构层面进行权限约束,我们做了两方面的事情:参数标准化及越权抽象化。首先,了解下什么是桥接模式。

桥接模式的概念

      将抽象部分与它的实现部分分离,使它们都可以独立地变化。桥接模式的结构:桥接模式包含4个主要角色。

抽象(Abstraction)角色:定义抽象类,并包含一个对实现角色的引用。

扩展抽象(Refined Abstraction)角色:抽象角色的实现,实现抽象角色的方法,并通过组合关系调用实现角色中的业务方法进行扩展。

实现(Implementor)角色:定义实现角色的接口,供扩展抽象角色调用。

具体实现(Concrete Implementor)角色:实现角色接口的具体实现。

应用示例

      接口是行为的抽象,一个对象会有多种行为特征的。以画图形上色为例,一般来说我会先将图形画出来,可能是三角形、圆形、长方形等等。图形的形状是一个变化点,所以我们肯定要抽象出来,作为一个接口,我们记为图形接口IShape。另外,画完图形外,我们计划给图形图上夜色,相应的可能是:红色、黑色等等。这也是一个变化点,我们记录为颜色变化,相应的也会新建一个接口。那么我们怎么把这两种行为融合起来呢?

方式一:实现类直接实现这两个接口。

      这个也是我们子工作中常用的,想让类获取更多的行为,实现不同的接口即可。在java中是不允许多继承的,但是可以实现多个接口。在实际工作中,一个类实现多个接口的场景非常多。比如:JDK中的String类,就实现了java.io.Serializable, Comparable, CharSequence三个接口。你可能会问,为何不把这些行为都定义在一个接口中呢,这样直接实现一个统一接口就行了。这样做是违背:接口隔离原则的,接口需要按功能进行隔离,细化一些。如果真的需要做统一的接口,也是基于目前的细化接口取做,这其实就是另一种设计模式了。

方式二:将颜色接口注入到具体的实现类中

      熟悉Spring的同学,一定不会陌生IOC(依赖注入)。其主要遵循了如下两个原则:面向接口编程,而不是面向实现编程和多用组合,少用继承。通过组合的方式,赋予对象额外的行为。一般来说我们基于以上两点去做,基本能满足业务需求了。其实,我们可以试想一下,在有些业务场景上,可能A、B两个行为业务上关系比较密切,给与A赋予B的行为特征。一般来说除了行为的赋予有时候还会赋予属性,使用接口方式就不太合适了,需要再增加抽象层,引入抽象类。然后在抽象类中将另外类注入进来,这就是桥接模式。桥接模式其本质就是一种组合(UML中使用关联更严谨一些),通过组合来对类的功能进行泛化。

项目实战

      以项目中,权限过滤为例,来看一看桥接模式实际项目中的应用,存在二维的变化分别是:操作的资源和操作资源的动作。我们抽象出两个接口:

      我们可以通过接口多实现、组合的方式很容易将两者的行为融合起来。但是,基于高内聚低耦合的原则,对于公共部分抽取出来总是没有错的。所以我们需要增加一层抽象层,以IPermission为基础,增加抽象类:AbstractPermission,在抽象类中,将IAction行为注入进去。做到这步,其实就是桥接模式了。扩展抽象就是整个桥接模式的精髓所在。最终的类图如下:

总结

      无论是在工作中,还是生活上:唯一不变的就是变化。对于变化我们不应该惧怕或者逃避,我们能做的是尽量控制它,限制其影响的范围。如果能做到这些,任他变化,何惧?

你可能感兴趣的:(桥接模式之我见)