为什么需要桥接模式?
对象的关系是在编译时就定义好了,所以无法再运行时改变从父类继承的实现。子类的实现与它的父类有非常紧密的依赖关系,以至于父类实现中的任何变化必然会导致子类发生变化,当你需要复用子类时,如果继承下来的实现不适合解决新的问题,则父类必须重写或被其他更适合的类替换。这种依赖关系限制了灵活性并最终限制了复用性。-
合成/聚合复用原则
尽量使用合成/聚合,尽量不要使用类继承。- 聚合:聚合表示一种弱的“拥有”关系,体现的是 A 对象可以包含 B 对象,但B 对象不是 A 对象的一部分。
- 合成,强的‘拥有‘关系,体现了严格的部分和整体的关系,部分和整体的声明周期是一样。
-
举例
- 问题:
手机品牌:手机品牌 A,手机品牌 B。
手机软件:游戏 ,通讯录。
现在想要在两个手机上分别安装游戏和通讯录。 -
分析:手机品牌作为抽象类 A,软件做为抽象类 B,手机品牌和手机软件之间属于聚合关系,手机品牌包含手机软件,但是手机软件并不属于手机品牌。
- 问题:
-
桥接模式
桥接模式,将抽象部分与它的实现部分分离,使它们都可以独立的变化。
抽象与实现分离是指抽象类和它的派生类用来实现自己的对象。让手机既可以按照品牌来分类也可以按照功能来分分类。
代码实现
abstract class Implementor
{
public abstract void Operation();
}
class ConcreteImplentorA:Implementor
{
public override void Operation()
{
Console.WriteLine("A 方法执行");
}
}
class ConcreteImplentorB:Implementor
{
public override void Operation()
{
Console.WriteLine("B 方法执行");
}
}
class Abstraction
{
protected Implementor implementor;
public void SetImplementor(Implementor implementor)
{
this.implementor = implementor;
}
public virtual void Operation()
{
implementor.Operation();
}
}
class RefinedAbstraction:Abstraction
{
public override void Operation()
{
implementor.Operation();
}
}
//客户端实现
static void Main(string[] args){
Abstraction ab = new Abstraction();
ab.Operation();
ab.SetImplementor(new ConcreteImplentorA);
ab.Operation();
ab.SetImplementor(new ConcreteImplentorB);
ab.Operation();
}