Bridge Pattern(桥接模式)

模式简介

       桥接模式是一种结构型设计模式,用于对抽象部分与实现部分的解耦,使得二者的变化可以相互独立,同时在抽象部分中存储一个对实现部分的引用,建立调用关联。当抽象部分的某个属性或者方法复杂多变时,就可以把它的具体实现部分与该抽象分离,仅保留对实现的引用,从而避免类膨胀的问题,也降低了代码的维护成本。

       常见的应用场景:跨平台界面系统、数据库驱动程序、多层存储系统、多媒体应用和电子设备控制等。

模式结构

  1. 抽象部分(Abstraction): 定义了抽象类的接口,维护了一个指向实现部分的引用。它的结构可以包括抽象方法、成员变量等。

  2. 扩充抽象部分(Refined Abstraction): 继承自抽象部分,对抽象部分的接口进行扩展,可以实现一些额外的功能。

  3. 实现部分(Implementor): 定义了实现部分的接口,通常包含了一些基本的操作。这个接口不一定要与抽象部分的接口完全一致,但必须能够被抽象部分调用。

  4. 具体实现部分(Concrete Implementor): 实现实现部分的接口,提供具体的实现。

工作原理

  1. 定义抽象部分(Abstraction)和实现部分(Implementor): 首先,你需要定义两个独立的层次结构,一个是抽象部分(Abstraction),一个是实现部分(Implementor)。抽象部分定义了高层次的接口,而实现部分定义了低层次的接口。

  2. 建立桥梁连接: 在抽象部分中维护一个指向实现部分的引用。这个引用可以是实现部分的接口,使得抽象部分可以调用实现部分的方法。

  3. 创建具体实现部分: 实现具体的实现部分,即创建实现部分接口的具体实现类。

  4. 创建抽象部分的具体子类: 创建扩充抽象部分的具体子类,这些子类可以实现抽象部分中定义的抽象方法,并可以扩展一些额外的功能。

  5. 客户端使用: 在客户端中,可以使用抽象部分的接口来调用相关操作。客户端可以通过抽象部分的具体子类来实例化对象,这些对象可以在运行时选择与特定的实现部分连接。

代码示例(C#)

提示:可在本栏目的资源篇“设计模式代码示例合集”下载所有完整代码资源。

衣服:Clothes.cs


namespace BridgePattern;

// 衣服
abstract class Clothes
{
    public string name; // 衣服名称
    public string material; // 衣服材质
    public Season applicableSeason; // 适用季节
    protected ColorDyer colorDyer; // 染色器

    public Clothes(string name, string material, Season applicableSeason, ColorDyer colorDyer)
    {
        this.name = name;
        this.material = material;
        this.applicableSeason = applicableSeason;
        this.colorDyer = colorDyer;
    }

    // 给模特穿上
    public abstract void Dressed(Man man);
}

// 衬衫
class Shirt : Clothes
{
    public Shirt(string name, string material, Season applicableSeason, ColorDyer colorDyer) :
    base(name, material, applicableSeason, colorDyer)
    { }

    public override void Dressed(Man man)
    {
        Console.WriteLine("------------------------------------");
        colorDyer.Dye();
        Console.WriteLine(man.name + " is wearing a " + colorDyer.color + " " + name + " made of " + material + " which is suitable for " + applicableSeason + " wear.");
    }
}

// 毛衣
class Sweater : Clothes
{
    public Sweater(string name, string material, Season applicableSeason, ColorDyer colorDyer) :
    base(name, material, applicableSeason, colorDyer)
    { }

    public override void Dressed(Man man)
    {
        Console.WriteLine("------------------------------------");
        colorDyer.Dye();
        Console.WriteLine(man.name + " is wearing a " + colorDyer.color + " " + name + " made of " + material + " which is suitable for " + applicableSeason + " wear.");
    }
}

// 短袖
class ShortSleeve : Clothes
{
    public ShortSleeve(string name, string material, Season applicableSeason, ColorDyer colorDyer) :
    base(name, material, applicableSeason, colorDyer)
    { }

    public override void Dressed(Man man)
    {
        Console.WriteLine("------------------------------------");
        colorDyer.Dye();
        Console.WriteLine(man.name + " is wearing a " + colorDyer.color + " " + name + " made of " + material + " which is suitable for " + applicableSeason + " wear.");
    }
}

// 夹克
class Jacket : Clothes
{
    public Jacket(string name, string material, Season applicableSeason, ColorDyer colorDyer) :
    base(name, material, applicableSeason, colorDyer)
    { }

    public override void Dressed(Man man)
    {
        Console.WriteLine("------------------------------------");
        colorDyer.Dye();
        Console.WriteLine(man.name + " is wearing a " + colorDyer.color + " " + name + " made of " + material + " which is suitable for " + applicableSeason + " wear.");
    }
}

染色器:Dyers.cs


namespace BridgePattern;

// 染色器
abstract class ColorDyer
{
    public Color color; // 颜色

    public ColorDyer(Color color)
    {
        this.color = color;
    }

    // 染色
    public abstract void Dye();
}

// 红色染色器
class RedDyer : ColorDyer
{
    public RedDyer(Color color) : base(color) { }

    public override void Dye()
    {
        Console.WriteLine("The dress is dyed red.");
    }
}

// 橙色染色器
class OrangeDyer : ColorDyer
{
    public OrangeDyer(Color color) : base(color) { }

    public override void Dye()
    {
        Console.WriteLine("The dress is dyed orange.");
    }
}

// 紫色染色器
class PurpleDyer : ColorDyer
{
    public PurpleDyer(Color color) : base(color) { }

    public override void Dye()
    {
        Console.WriteLine("The dress is dyed purple.");
    }
}

// 白色染色器
class WhiteDyer : ColorDyer
{
    public WhiteDyer(Color color) : base(color) { }

    public override void Dye()
    {
        Console.WriteLine("The dress is dyed white.");
    }
}

枚举:Enum.cs


namespace BridgePattern;

//季节
enum Season
{
    Spring, Summer, Autumn, Winter
}

//颜色
enum Color
{
    Red, Blue, Orange, White, Black, Yellow, Green, Purple
}

模特:Man.cs


namespace BridgePattern;

// 男士模特
public class Man
{
    public string name; // 名字

    public Man(string name)
    {
        this.name = name;
    }

    // 行走
    public void Walk()
    {
        Console.WriteLine("The man named " + name + " is walking.");
        Thread.Sleep(new Random().Next(3000));
    }
}

测试代码:Program.cs

// ************* 18.桥接模式测试 **************
using BridgePattern;

// 找两个模特
Man jojo = new Man("JoJo");
Man kaka = new Man("KaKa");

// 做四种染色器
RedDyer redDyer = new RedDyer(Color.Red);
OrangeDyer orangeDyer = new OrangeDyer(Color.Orange);
PurpleDyer purpleDyer = new PurpleDyer(Color.Purple);
WhiteDyer whiteDyer = new WhiteDyer(Color.White);

// 给四种衣服分别配置一种染色器
Shirt whiteShirt = new Shirt("Shirt", "cotton", Season.Spring, whiteDyer);
Sweater orangeSweater = new Sweater("Sweater", "polyester-fiber", Season.Autumn, orangeDyer);
ShortSleeve purpleShortSleeve = new ShortSleeve("ShortSleeve", "cotton", Season.Summer, purpleDyer);
Jacket redJacket = new Jacket("Jacket", "polyester-fiber and cotton", Season.Winter, redDyer);

// 模特试穿衣服
whiteShirt.Dressed(jojo);
redJacket.Dressed(jojo);
purpleShortSleeve.Dressed(kaka);
orangeSweater.Dressed(kaka);

代码解说

       上述代码简单模拟了衣服的染色过程。有ShirtSweaterShortSleeveJacket四种类型的衣服,并且每种衣服都可以染RedOrangePurpleWhite四种不同的颜色,这样就会有16种组合,如果每种组合我们都去定义一个类就会出现类爆炸问题。

      所以我们就可以采用桥接模式,将衣服与染色器分开,二者分别创建一个基类ClothesColorDyer,四种衣服分别继承Clothes基类,四种染色器分别继承ColorDyer。然后我们在Clothes基类中存储一个对ColorDyer的引用,这里就实现了ClothesColorDyer的桥接模式,当我们制作一件衣服时需要通过一个染色器进行染色,当我们下次有一种新的衣服或新的染色器时只需要添加一个类即可,就不需要再定义四个类,这就是桥接模式的好处。

如果这篇文章对你有帮助,请给作者点个赞吧!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值