设计模式学习笔记之桥接模式

存在目地:将抽象部分与实现部分分离,使它们都可以独立的变化。也即将抽象和实现进行脱耦,使用组合/聚合关系而不是继承使二者可以相对独立的变化。

应用场合:某些类型由于自身的逻辑,它具有两个或多个维度的变化,那么如何应对这种“多维度的变化”?如何利用面向对象的技术来使得该类型能够轻松的沿着多个方向进行变化,而又不引入额外的复杂度?这就要使用Bridge模式。

实现方式:

using System;

// 抽象化角色,抽象化给出的定义,并保存一个对实现化对象的引用

class Abstraction

{

  // 实现化对象implementor

  protected Implementor implementor;

  // Properties

  public Implementor Implementor

  {

    set{ implementor = value; }

  }

  // Methods

  virtual public void Operation()

  {

    implementor.Operation();

  }

}

 

// 修正抽象化角色,扩展抽象化角色,改变和修正父类对抽象化的定义

class RefinedAbstractionA : Abstraction

{

  // Methods

  override public void Operation()

  {

    implementor.Operation();

  }

}

class RefinedAbstractionB : Abstraction

{

  // Methods

  override public void Operation()

  {

    implementor.Operation();

  }

}

// 实现化角色,给出具体实现化角色的接口

abstract class Implementor

{

  // Methods

  abstract public void Operation();

}

// 具体实现化角色,给出实现化角色接口的具体实现

class ConcreteImplementorA : Implementor

{

  // Methods

  override public void Operation()

  {

    Console.WriteLine("ConcreteImplementorA Operation");

  }

}

class ConcreteImplementorB : Implementor

{

  // Methods

  override public void Operation()

  {

    Console.WriteLine("ConcreteImplementorB Operation");

  }

}

/** <summary>

/// Client test

/// </summary>

public class Client

{

  public static void Main( string[] args )

  {

Abstraction abstraction = new RefinedAbstractionA();

// Set implementation and call

      abstraction.Implementor = new ConcreteImplementorA();

      abstraction.Operation(); 

      // Change implemention and call

      abstraction.Implementor = new ConcreteImplementorB();

      abstraction.Operation();

 

      abstraction = new RefinedAbstractionB();

// Set implementation and call

      abstraction.Implementor = new ConcreteImplementorA();

      abstraction.Operation(); 

      // Change implemention and call

      abstraction.Implementor = new ConcreteImplementorB();

      abstraction.Operation();

  }

}

另一个关于日志记录的代码实例,在两种不同的平台下.NETJava两种记录方式

public abstract class ImpLog

{

    public abstract void Execute(string msg);

}

public class NImpLog : ImpLog

{

    public override void Execute(string msg)

    {

        //...... .NET平台

    }

}

public class JImpLog : ImpLog

{

    public override void Execute(string msg)

    {

        //...... Java平台

    }

}

 

public abstract class Log

{

    protected ImpLog implementor;

    public ImpLog Implementor

    {

        set { implementor = value; }   

    }

    public virtual void Write(string log)

    {

        implementor.Execute(log);

    }

}

public class DatabaseLog : Log

{

    public override void Write(string log)

    {

        implementor.Execute(log);

    }

}

public class TextFileLog : Log

{

    public override void Write(string log)

    {

        implementor.Execute(log);

    }

}

 

class App

{

    public static void Main(string[] args)

    {

        //.NET平台下的Database Log

        Log dblog = new DatabaseLog();

        dblog.Implementor = new NImpLog();

        dblog.Write();       

 

        //Java平台下的Text File Log

        Log txtlog = new TextFileLog();

        txtlog.Implementor = new JImpLog();

        txtlog.Write();

    }

}

 

适用性:

如果一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性,避免在两个层次之间建立静态的联系。

设计要求实现化角色的任何改变不应当影响客户端,或者说实现化角色的改变对客户端是完全透明的。

一个构件有多于一个的抽象化角色和实现化角色,系统需要它们之间进行动态耦合。

虽然在系统中使用继承是没有问题的,但是由于抽象化角色和具体化角色需要独立变化,设计要求需要独立管理这两者。

 

 

 

 

参考资料:

TerryLee's Tech Space

吕震宇博客

Erich Gamma《设计模式可复用面向对象软件的基础》

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值