桥模式






4.88/5 (11投票s)
本文展示了一个关于我们如何将桥模式用于 Elizabeth's Day Care Center 的案例研究。
背景
再次来到我最喜欢的地方 - 伊丽莎白的日托中心。
在伊丽莎白的日托中心,所有老师都非常友好,并试图与所有孩子交朋友。
起初,在新孩子和新老师之间建立关系非常困难,因为他们从未见过面。为了让老师和孩子能够相互交流,我们需要某种方式建立一个沟通路径,以允许老师/主管(任何想成为沟通者的人)与孩子沟通。
老师(沟通者对象)可以与任何孩子(可交谈的对象)交谈,孩子也应该允许任何老师(沟通者对象)开始与他/她交谈。就像打印机与电脑一起工作一样。如果我们有一根 USB 电缆(桥梁),那么我们可以将任何打印机连接到任何电脑以开始打印。无论是激光打印机还是彩色打印机,无论是 Windows PC 还是 Mac,都无关紧要。因为我们知道所有打印机都允许电脑打印,明白了吗?
引言
桥接模式可以帮助我们将合同(接口)和实现在两个独立的区域分开。我们可以使用 C# 中的接口来构建我们的合同。合同只会提供/列出功能,但将实现留给实现者来处理。因此,合同可以用作其他类中的桥梁,它允许其他类使用具体的实现者,而无需了解任何细节。
本文介绍了一种使用桥接模式到我们日托中心的实现方法。
桥接设计模式结构

类图

实现代码
抽象类
ICommunicator
ICommunicator
是一个接口,当其他类想要能够与 ITalkable
对象通信时,这些类将继承它。在 ICommunicator
类中,我们定义了 ITalkable
对象,它允许我们使用来自 Italkable
对象的所有功能。 Italkable
对象在这里充当桥梁,让 ICommnucator
对象使用它。
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace www.askbargains.com
{
namespace BridgeDesignPattern
{
public interface ICommunicator
{
//build a bridge between a Communicator and a talkable object (Kid)
ITalkable objToTalk { get; set; }
//Start chatting process
void StartChatting();
}
}
}
老师
Teacher
类是一个 RefinedAbstraction
类,它实际上实现了 StartChatting()
方法的细节。在 teacher 类中,我将 ITalkable
对象转换为 Kid
对象,以防我需要使用 Kid
类的一些属性。但是,我们不必在这里进行转换,因为我们只关心 ITalkable
功能。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace www.askbargains.com
{
namespace BridgeDesignPattern
{
public class Teacher : ICommunicator
{
Kid aKid = new Kid();
//or
//ITalkable _objToTalk
#region ICommunicator Members
public ITalkable objToTalk
{
get
{
return aKid;
}
set
{
aKid = (Kid)value;
}
}
//Implementing the Chatting procedures.
public void StartChatting()
{
Console.WriteLine("What's your name?");
aKid.TellMeAboutName();
Console.WriteLine("How old are you?");
aKid.TellMeAboutAge();
Console.WriteLine("What's your favor food");
aKid.TellMeAboutFavorFood();
//I use objToTalk as Kid object to use Name property here
//for demo purpose
string name = aKid.Name;
//You don't have to cast objToTalk object to Kid.
//objToTalk.TellMeAboutAge();
//objToTalk.TellMeAboutName();
//objToTalk.TellMeAboutFavorFood();
}
#endregion
}
}
}
总监
与 Teacher
相同,是另一个 ConcreteAbstraction
类。它直接使用 ITalkable
对象(aKid
)来实现 StartChatting()
方法。这里没有转换过程,只是为了展示与 Teacher
的 Startchatting()
方法的一些差异。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace www.askbargains.com.BridgeDesignPattern
{
public class Director : ICommunicator
{
ITalkable aKid;
#region ICommunicator Members
public ITalkable objToTalk
{
get
{
return aKid;
}
set
{
aKid = value;
}
}
//Director has different questions than teacher.
public void StartChatting()
{
Console.WriteLine("Hi , can your tell me your name?");
aKid.TellMeAboutName();
Console.WriteLine("Hi , can you tell my your age?");
aKid.TellMeAboutAge();
}
#endregion
}
}
实现者类
ITalkable
ITalkable
接口列出了一个可交谈的类必须拥有的所有合同方法/功能。需要能够被 Communicator
对象交谈的类需要继承 ITalkable
接口。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace www.askbargains.com
{
namespace BridgeDesignPattern
{
//it is going to be consumed by the Communicator as a bridge to talk to any
//ITalkable objects. And also all the ITalkable objects must provide the
//below activities as well.
public interface ITalkable
{
void TellMeAboutName();
void TellMeAboutAge();
void TellMeAboutFavorFood();
}
}
}
Kid
Kid
类继承自 ITalkable
接口,使其自身可交谈。它按照自己的规则实现每个 ITalkable
方法。在本案例研究中,我只定义了一个继承自 ITalkable
接口的 Kid
类。实际上,任何类都可以继承 ITalkable
接口,使其自身能够被任何 Communicator
对象交谈。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace www.askbargains.com
{
namespace BridgeDesignPattern
{
public class Kid : ITalkable
{
public string Name { get; set; }
public int Age { get; set; }
public string FavorFood { get; set; }
#region ITalker Members
public void TellMeAboutName()
{
Console.WriteLine("My name is {0}", Name);
}
public void TellMeAboutAge()
{
Console.WriteLine("I am {0} years old", Age.ToString());
}
public void TellMeAboutFavorFood()
{
Console.WriteLine("My favor food is {0}", FavorFood);
}
#endregion
}
}
}
客户端应用程序
从客户端,我创建了两个孩子(Elizabeth
和 Ammie
)作为我们的 ITalkable
对象,并创建了一个 Teacher
和一个 Director
作为我们的 ICommunicator
对象。
让 Teacher
和 Director
都开始与两个孩子交谈,我们将看到 Elizabeth
和 Ammie
都能够回答来自两个 ICommunicator
对象的问题。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using www.askbargains.com.BridgeDesignPattern;
namespace www.askbargains.com
{
namespace Client
{
class Program
{
static void Main(string[] args)
{
//create a teacher and a director
Teacher Megan = new Teacher();
Director Lisa = new Director();
Kid Elizabeth = new Kid();
Elizabeth.Name = "Elizabeth";
Elizabeth.Age = 3;
Elizabeth.FavorFood = "Chicken Nuggets";
Kid Ammie = new Kid();
Ammie.Name = "Ammie";
Ammie.Age = 4;
Ammie.FavorFood = "French Fries";
//teacher Megan starts talking with Elizabeth
Console.WriteLine("Miss Megan starts talking to Elizabeth");
Megan.objToTalk = Elizabeth;
Megan.StartChatting();
Console.WriteLine();
//Director Lisa starts talking with Ammie
Console.WriteLine("Director Lisa starts talking to Ammie");
Lisa.objToTalk = Ammie;
Lisa.StartChatting();
Console.WriteLine();
//Teacher Megan starts talking with Ammie
Console.WriteLine("Miss Megan starts talking to Ammie");
Megan.objToTalk = Ammie;
Megan.StartChatting();
Console.WriteLine();
//Director Lisa starts talking with Elizabeth
Console.WriteLine("Director Lisa starts talking to Elizabeth");
Lisa.objToTalk = Elizabeth;
Lisa.StartChatting();
Console.Read();
}
}
}
}
一旦我们启动我们的客户端应用程序,您将看到,无论谁想与孩子们交谈,孩子们都会给沟通者正确的答案。太棒了!

结论
在本文中,我演示了如何使用桥接模式来实现伊丽莎白日托中心的通信系统。我在其他文章中也将日托中心用作 原型设计模式。
历史
- 2009 年 9 月 30 日:首次发布