@Author:云都小生
引子
衣服有长袖,有短袖,还有背心。并且,衣服有黄色、蓝色、黑色各种不同的颜色。一般人来设计,会怎么去设计呢?
首先它可能会创建长袖、短袖、背心三个抽象类/接口,然后黄色长袖、蓝色长袖、黑色长袖从长袖继承··· 黄色短袖、蓝色短袖和黑色短袖从短袖继承···
数一数,这样设计的话,我们至少得用十三个类(还有一个衣服的抽象类)。这样会有什么坏处呢?
第一,这样去设计,我们要分的类就太多了,而且存在多重继承,加大了程序的复杂度。第二点,扩展性不强,你说我要是增加一个更新的款式——吊带衣,那又得增加多少个类。
在前面的面向对象设计原则里,有这么一个原则——合成复用。尽量多使用组合,而不是继承。
概述
如若一个系统中存在两个变化的维度,我们就要考虑将两个维度分离,使两者可以独立扩展。就像上面的例如,我们可以把款式、颜色两个维度分离,让它们都独立出来,通过组装去实现。
桥接模式(Bridge Pattern):将抽象部分与它的实现部分分离,使它们都可以独立地变化。
在桥接模式下,一般有这些角色:
抽象类(衣服):这个抽象类会维护另一个组合的对象(颜色);
扩充抽象类(各种款式):这些都实现了抽象类/接口,是具体的类,它需要实现抽象类里面的抽象业务方法;
实现类接口(颜色):这是另一个维度,被分离出来,独立的存在;
具体实现类(各种颜色):实现了实现类接口,也是具体的类。
其实我觉得,桥接模式的精髓——“分离”,一定要渐渐的成为我们编程的习惯,让代码看起来不会太“蠢”。
接下来我们来看看代码的实现。
代码实现
//衣服类
abstract class Clothes {
Color Clothescolor;
abstract void wear();
}
//长袖
public class Longsleeves extends Clothes{
Longsleeves(Color color) {
this.Clothescolor = color;
}
void wear() {
System.out.println("穿上了一件长袖,颜色是:" + this.Clothescolor.color);
}
}
//短袖
public class Shortsleeves extends Clothes{
Shortsleeves(Color color) {
this.Clothescolor = color;
}
void wear() {
System.out.println("穿上了一件短袖,颜色是:" + this.Clothescolor.color);
}
}
//背心
public class Vest extends Clothes{
Vest(Color color) {
this.Clothescolor = color;
}
void wear() {
System.out.println("穿上了一件背心,颜色是:" + this.Clothescolor.color);
}
}
//颜色
abstract class Color {
String color = "白色";
//各种抽象方法
}
//黑色
public class Black extends Color{
Black()
{
this.color = "黑色";
}
}
//蓝色
public class Blue extends Color{
Blue()
{
this.color = "蓝色";
}
}
//红色
public class Red extends Color{
Red()
{
this.color = "红色";
}
}
public class Client {
public static void main(String[] args) {
Longsleeves ss = new Longsleeves(new Blue());
ss.wear();
}
}
心得
我觉得桥接模式其实就是面向对象设计原则中的合成复用原则,是一种编程的基本思想,每个程序员都应该有这种编程思想和编程规范。
桥接模式的应用较为广泛,某种情况下极大减少了子类的个数,对耦合度高的继承结构进行解耦,提高了系统的可扩展性。但是反过来,有时候桥接模式的使用会增加系统的理解与设计难度。
2017/11/6 11:47:15 @Author:云都小生(Clouking)