类图:

抽象化(Abstraction)角色:抽象化给出的定义,并保存一个对实现化对象的引用。
修正抽象化(RefinedAbstraction)角色:扩展抽象化角色,改变和修正父类对抽象化的定义。
实现化(Implementor)角色:这个角色给出实现化角色的接口,但不给出具体的实现。必须指出的是,这个接口不一定和抽象化角色的接口定义相同,实际上,这两个接口可以非常不一样。实现化角色应当只给出底层操作,而抽象化角色应当只给出基于底层操作的更高一层的操作。
具体实现化(ConcreteImplementor)角色:这个角色给出实现化角色接口的具体实现。
咖啡的例子
原文见:https://zhuanlan.zhihu.com/p/58903776
类图:

这里勇哥给出C#的演示代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 桥接模式_点咖啡2
{
/*
项目经理突然过来了:蛋大啊,客户那边说了,
他们准备加两个容量规格的咖啡,大杯和小杯,你改一下。
加着加着蛋大慌了,共需要3x2=6个类啊,大杯原味和加糖,中杯原味和加糖,小杯原味和加糖。
过段时间万一那二笔客户又要出加奶,加蜂蜜等等口味,
说不定还有迷你杯,女神杯等等规格的咖啡,
那我这边的类不就爆炸了吗?看来的去找个设计模式了。。。
此场景桥接模式正合适,这里有两个变化维度,咖啡的容量和口味,
而且都需要独立变化。如果使用继承的方式,随着变化类就会急剧的增加。
你可以将容量理解为抽象部分,而口味理解为实现部分,这两个部分需要桥接。
*/
class Program
{
static void Main(string[] args)
{
RefinedAbstraction db = new 大杯牛奶(new 加奶());
db.orderCoffee(2);
db.checkQuality();
Console.ReadKey();
}
}
/// <summary>
/// 抽象化(Abstraction)角色
/// </summary>
public abstract class Abstraction
{
protected abstract Implementor 口味 { get; set; }
public Abstraction(Implementor _口味)
{
this.口味 = _口味;
}
public abstract void orderCoffee(int count);
}
/// <summary>
/// 修正抽象化(RefinedAbstraction)角色
/// </summary>
public abstract class RefinedAbstraction : Abstraction
{
protected override Implementor 口味 { get; set; }
public RefinedAbstraction(Implementor _口味) : base(_口味)
{
口味 = _口味;
}
public void checkQuality()
{
Console.WriteLine($"{口味.GetType().Name},正常");
}
}
public class 大杯牛奶 : RefinedAbstraction
{
protected override Implementor 口味 { get; set; }
public 大杯牛奶(Implementor add) : base(add)
{
口味 = add;
}
public override void orderCoffee(int count)
{
口味.addSomething();
Console.WriteLine($"大杯咖啡{count}杯");
}
}
/// <summary>
/// 实现化(Implementor)角色
/// </summary>
public interface Implementor
{
void addSomething();
}
/// <summary>
/// 具体实现化(ConcreteImplementor)角色1
/// </summary>
public class 加奶 : Implementor
{
public void addSomething()
{
Console.WriteLine($"加奶");
}
}
/// <summary>
/// 具体实现化(ConcreteImplementor)角色2
/// </summary>
public class 加糖 : Implementor
{
public void addSomething()
{
Console.WriteLine($"加糖");
}
}
}这篇文章有位读者的点评很能说明桥接模式的特点:将m*n个实现类转换为m+n个实现类
图片在不同系统下显示
原文链接:
https://www.jianshu.com/p/516a6beb42c3
代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
WindowsSystem win = new WindowsSystem();
LinuxSystem lin = new LinuxSystem();
Image jpgSys = new JPGImage(system: win, format: "jpg");
jpgSys.ParseFile();
Image jpgLin = new JPGImage(system: lin, format: "jpg");
jpgLin.ParseFile();
Image pngSys = new PNGImage(system: win, format: "png");
pngSys.ParseFile();
Image pngLin = new PNGImage(system: lin, format: "png");
pngLin.ParseFile();
Console.ReadKey();
}
}
public abstract class Image
{
public System System { get; protected set; }
public string Format { get; protected set; }
public Image(System system, string format)
{
System = system;
Format = format;
}
public void ParseFile()
{
System.Show(Format);
}
}
public class JPGImage : Image
{
public JPGImage(System system, string format) : base(system, format) { }
}
public class PNGImage : Image
{
public PNGImage(System system, string format) : base(system, format) { }
}
public abstract class System
{
public virtual void Show(string format)
{
// 基础实现,可以在子类中被覆盖
}
}
public class WindowsSystem : System
{
public override void Show(string format)
{
Console.WriteLine($"{format}格式在Windows系统下显示");
}
}
public class LinuxSystem : System
{
public override void Show(string format)
{
Console.WriteLine($"{format}格式在Linux系统下显示");
}
}
}结果:

需求V2:增加新的图像文件格式TIF
只需要创建TIFImage继承自Image即可
public class TIFImage : Image
{
//public TIFImage(System system, string format) : base(system, format) { }
}
TIFImage tifSys = new TIFImage(system: win, format: "tif");
tifSys.ParseFile();
TIFImage tifLin = new TIFImage(system: lin, format: "tif");
tifLin.ParseFile();需求V3:增加一个新的操作系统Mac OS
只需要创建MacOSSystem继承自System即可
public class MacOSSystem : System
{
public override void Show(string format)
{
Console.WriteLine($"{format}格式在Mac OS系统下显示");
}
}
//客户端:
MacOSSystem mac = new MacOSSystem();
Image jpgMac = new JPGImage(system: mac, format: "jpg");
jpgMac.ParseFile();
Image pngMac = new PNGImage(system: mac, format: "png");
pngMac.ParseFile();
Image tifMac = new TIFImage(system: mac, format: "tif");
// 注意这里应该是TIFImage而不是JPGImage
tifMac.ParseFile();另一篇:
https://zhuanlan.zhihu.com/p/666037755
https://baijiahao.baidu.com/s?id=1736389582955994797&wfr=spider&for=pc


少有人走的路



















