65.9K
CodeProject 正在变化。 阅读更多。
Home

桥模式

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.88/5 (11投票s)

2009年9月30日

CPOL

3分钟阅读

viewsIcon

61277

downloadIcon

504

本文展示了一个关于我们如何将桥模式用于 Elizabeth's Day Care Center 的案例研究。

背景

再次来到我最喜欢的地方 - 伊丽莎白的日托中心。

在伊丽莎白的日托中心,所有老师都非常友好,并试图与所有孩子交朋友。

起初,在新孩子和新老师之间建立关系非常困难,因为他们从未见过面。为了让老师和孩子能够相互交流,我们需要某种方式建立一个沟通路径,以允许老师/主管(任何想成为沟通者的人)与孩子沟通。

老师(沟通者对象)可以与任何孩子(可交谈的对象)交谈,孩子也应该允许任何老师(沟通者对象)开始与他/她交谈。就像打印机与电脑一起工作一样。如果我们有一根 USB 电缆(桥梁),那么我们可以将任何打印机连接到任何电脑以开始打印。无论是激光打印机还是彩色打印机,无论是 Windows PC 还是 Mac,都无关紧要。因为我们知道所有打印机都允许电脑打印,明白了吗?

引言

桥接模式可以帮助我们将合同(接口)和实现在两个独立的区域分开。我们可以使用 C# 中的接口来构建我们的合同。合同只会提供/列出功能,但将实现留给实现者来处理。因此,合同可以用作其他类中的桥梁,它允许其他类使用具体的实现者,而无需了解任何细节。

本文介绍了一种使用桥接模式到我们日托中心的实现方法。

桥接设计模式结构

Bridge.JPG - Click to enlarge image

类图

BridgeClass.JPG - Click to enlarge image

实现代码

抽象类

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() 方法。这里没有转换过程,只是为了展示与 TeacherStartchatting() 方法的一些差异。

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
        }
    }
}

客户端应用程序

从客户端,我创建了两个孩子(ElizabethAmmie)作为我们的 ITalkable 对象,并创建了一个 Teacher 和一个 Director 作为我们的 ICommunicator 对象。

TeacherDirector 都开始与两个孩子交谈,我们将看到 ElizabethAmmie 都能够回答来自两个 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(); 
            }
        }
    }
}

一旦我们启动我们的客户端应用程序,您将看到,无论谁想与孩子们交谈,孩子们都会给沟通者正确的答案。太棒了!

BridgeOutput.JPG

结论

在本文中,我演示了如何使用桥接模式来实现伊丽莎白日托中心的通信系统。我在其他文章中也将日托中心用作 原型设计模式

历史

  • 2009 年 9 月 30 日:首次发布
© . All rights reserved.