『设计模式』大话西游的移魂大法竟移出来了桥接模式
23种设计模式+额外常用设计模式汇总 (持续更新)
大话西游里有那么一幕,牛魔王的妹妹使用移魂大法,使几个人的灵魂交换。我们考虑一个问题,一个哲学问题,到底他们时灵魂发生了转移,还是肉体发生了转移。到底肉体是灵魂的载体,还是灵魂是肉体的产物。这部唯心主义了,不行不行,我可是社会唯物主义好青年,看我用桥接模式给你给他们连起来。(PS:为了骗流量,博主起了这个名字,内容很有用)
桥接模式
桥接(Bridge)是用于把抽象化与实现化解耦,使得二者可以独立变化。这种类型的设计模式属于结构型模式,它通过提供抽象化和实现化之间的桥接结构,来实现二者的解耦。
这种模式涉及到一个作为桥接的接口,使得实体类的功能独立于接口实现类。这两种类型的类可被结构化改变而互不影响。
桥接模式是一个非常有用的模式,也是比较复杂的一个模式。熟悉这个模式对于理解面向对象的设计原则,包括"开-闭"原则(OCP)以及组合/聚合复用原则(CARP)都很有帮助。理解好这两个原则,有助于
形成正确的设计思想和培养良好的设计风格。
核心思想:以聚合代替原本的继承关系,重构代码结构实现松耦合(Coupling),二是高内聚(Cohesion)。
面向对象系统追求的目标就是尽可能地提高系统模块内部的内聚(Cohesion)尽可能降低模块间的耦合(Coupling)。然而这也是面向对象设计过程中最难把握的部分
优点:
- 抽象和实现的分离。
- 优秀的扩展能力。
- 实现细节对客户透明。
缺点:
桥接模式的引入会增加系统的理解与设计难度,由于聚合关联关系建立在抽象层,要求开发者针对抽象进行设计与编程。
适用场景:
- 如果一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性,避免在两个层次之间建立静态的继承联系,通过桥接模式可以使它们在抽象层建立一个关联关系。
- 对于那些不希望使用继承或因为多层次继承导致系统类的个数急剧增加的系统,桥接模式尤为适用
- 一个类存在两个独立变化的维度,且这两个维度都需要进行扩展。
实现:
我们用一个示例来形象的说明什么事桥接 模式,但是这个例子不具有开发意义,只是为了讲清楚实现。
如果我们想实现PC系统和软件的关系的软件架构该如何实现。
(再次说明,只是为了举例,评论区总有抬杠的😂)
第一种方式:
感觉很良好,采用继承方式。但是如果再增加一个Mac操作系统该怎么办?
看完可能会说,没啥啊,不就多了几个类,复制粘贴一下不就好了。
真的是这样吗?
- 开发时,复制粘贴绝不是一件好事,这个我们之前就说过。
- 如果说Kubuntu或者说CentOS和Unix等系统都要放到这里呢,粘贴真的够用吗?
所以当二级分类一多,这里软件架构就不是那么合理了!
第二种方式:
我这么聪明我肯定有办法啊!看我怎么做!
你看,我这么一重构,这不就完事了,我加个MAC,再来十个系统我也不怕!
结果老板说,软件不应该还有通讯软件,音乐软件,视频软件…
我晕!
又变得跟第一种一样,每一种都是拖家带口的生成!
第三种方式
所以我们要是用桥接模式,请看:
顺势我们给出桥接UML图
具体代码:
Implementor :
package 桥接模式;
public abstract class Implementor {
public abstract void Operaction();
}
ConcreteImplementorA
package 桥接模式;
public class ConcreteImplementorA extends Implementor {
@Override
public void Operaction() {
System.out.println("我是A的具体方法");
}
}
ConcreteImplementorB
package 桥接模式;
public class ConcreteImplementorB extends Implementor {
@Override
public void Operaction() {
System.out.println("我是B的具体方法");
}
}
Abstraction
package 桥接模式;
public class Abstraction {
protected Implementor im;
public void setIm(Implementor im) {
this.im = im;
}
void operaction() {
im.Operaction();
}
}
RefindAbstraction
package 桥接模式;
public class RefindAbstraction extends Abstraction {
public void Operaction() {
im.Operaction();
}
}
Client
package 桥接模式;
public class Client {
public static void main(String[] args) {
// TODO Auto-generated method stub
Abstraction ab=new RefindAbstraction();
ab.setIm(new ConcreteImplementorA());
ab.operaction();
ab.setIm(new ConcreteImplementorB());
ab.operaction();
}
}