桥接模式(Bridge pattern)【使用频率:★★★☆☆】
1. 概述
将抽象部分与它的实现部分分离开来,使他们都可以独立变化。套用《大话设计模式》里面的就是实现系统可能有多个角度分类,每一种角度都可能变化,那么把这种多角度分类给分离出来让他们独立变化,减少他们之间耦合。
2. 解决的问题
在软件系统中,有些类型由于自身的逻辑,它具有两个或多个维度的变化。为了解决这种多维度变化,又不引入复杂度,这就要使用Bridge模式。
3. 模式中的角色
2.1 抽象类(Abstraction):定义抽象接口,它一般是抽象类而不是接口。该接口中包含实现具体行为、具体特征的Implementor接口。
2.2 扩充的抽象类(RefinedAbstraction):继承自Abstraction的子类,通常情况下它不再是抽象类而是具体类,它实现了在Abstraction中声明的抽象业务方法,在RefinedAbstraction中可以调用在Implementor中定义的业务方法。
2.3 实现类(Implementor):定义具体行为,具体特征的应用接口。
2.4 具体实现类(ConcreteImplementor):实现Implementor。
4. 模式解读
4.1 模式的类图
4.2 桥接模式代码实现
using System;
namespace ConsoleApp2
{
class Class1
{
static void Main(string[] args)
{
//白色
Color white = new White();
//正方形
Shape square = new Square();
//白色的正方形
square.SetColor(white);
square.Draw();
//长方形
Shape rectange = new Rectangle();
rectange.SetColor(white);
rectange.Draw();
Console.ReadLine();
}
}
public abstract class Shape
{
public Color color;
public void SetColor(Color color)
{
this.color = color;
}
public abstract void Draw();
}
public class Circle : Shape
{
public override void Draw()
{
color.Bepaint("正方形");
}
}
public class Rectangle : Shape
{
public override void Draw()
{
color.Bepaint("长方形");
}
}
public class Square : Shape
{
public override void Draw()
{
color.Bepaint("正方形");
}
}
public interface Color
{
void Bepaint(string shape);
}
public class White : Color
{
public void Bepaint(string shape)
{
Console.WriteLine("白色的" + shape);
}
}
public class Gray : Color
{
public void Bepaint(string shape)
{
Console.WriteLine("灰色的" + shape);
}
}
public class Black : Color
{
public void Bepaint(string shape)
{
Console.WriteLine("黑色的" + shape);
}
}
}
5. 模式优缺点
5.1 优点
- 降低了沿着两个或多个维度扩展时的复杂度,防止类的过度膨胀。
- 桥接模式提高了系统的可扩充性,在两个变化维度中任意扩展一个维度,都不需要修改原有系统。
5.2 缺点
- 桥接模式的引入会增加系统的理解与设计难度,由于聚合关联关系建立在抽象层,要求开发者针对抽象进行设计与编程。
- 桥接模式要求正确识别出系统中两个独立变化的维度,因此其使用范围具有一定的局限性。
6. 适用场景
- 当一个对象有多个变化因素时,可以考虑使用桥接模式,通过抽象这些变化因素,将依赖具体实现修改为依赖抽象。
- 当我们期望一个对象的多个变化因素可以动态变化,而且不影响客户端的程序使用时。
- 如果使用继承的实现方案,会导致产生很多子类,任何一个变化因素都需要产生多个类来完成,就要考虑桥接模式。
- 游戏开发中一个武器有多种变化形态,可以考虑使用桥接模式。