الگوی Bridge

الگوی Bridge در دسته الگوهای ساختاری قرار دارد. تغریف Gof : رابط کاربری شیء را از پیاده سازی آن جدا می کند - به عبارت دیگر جدا کردن انتزاع و پیاده‌سازی از یکدیگر به منظور این که بتوان هر کدام را به طور مستقل از دیگری توسعه داد. UML class diagram شركت كنندگان کلاس ها و اشیاء شرکت کننده در این الگو عبارتند از: انتزاع Abstraction (شی کسب و کار BusinessObject) : رابط انتزاع ( abstraction's interface ) را تعریف می کند.یک ارجاع به یک شی از نوع پیاده سازی را نگه می دارد.به عبارت دیگر واسطی است که کلاینت میبیند. این واسط حاوی ارجاعی به Abstraction و Implementor/Bridge است و درخواست‌های کلاینت را به آن حواله می دهد. انتزاع تصفیه RefinedAbstraction (شی کسب و کار مشتری CustomersBusinessObject) :رابط کاربری تعریف شده توسط Abstraction را توسعه می دهد( نمونه ای از پیاده سازی Abstraction است ).پیاده سازی Implementor (شی داده DataObject) :رابط کاربری کلاس های پیاده سازی را تعریف می کند.این Interface لازم نیست به طور دقیق به رابط انتزاع ( Abstraction's interface ) دقیقا مطابقت داشته باشد؛ در واقع دو رابط (Interface) می تواند کاملا متفاوت باشد.به طور معمول، رابط پیاده سازی تنها عملیات ابتدایی(اصلی) را فراهم می کند و Abstraction ( انتزاع ) عملیات سطح بالایی را بر اساس عملیات اولیه تعریف می کند.پیاده سازی سفت ConcreteImplementor (شی داده مشتری CustomersDataObject) : پیاده سازی Implementor interface (رابط پیاده سازی) و تعریف پیاده سازی سفت آن را مشخص می کند.ساختار کلی الگوی Bridgeاین کد ساختاری الگوی پل را نشان می دهد که رابط( interface ) را از پیاده سازی( implementation ) آن جدا می کند.پیاده سازی می تواند بدون تغییر کلاینت ها توسعه یابد که از انتزاع شیء استفاده می کنند. using System; namespace DoFactory.GangOfFour.Bridge.Structural { /// <summary> /// MainApp startup class for Structural /// Bridge Design Pattern. /// </summary> class MainApp { /// <summary> /// Entry point into console application. /// </summary> static void Main () { Abstraction ab = new RefinedAbstraction (); // Set implementation and call ab.Implementor = new ConcreteImplementorA (); ab.Operation (); // Change implemention and call ab.Implementor = new ConcreteImplementorB (); ab.Operation (); // Wait for user Console.ReadKey (); } } /// <summary> /// The 'Abstraction' class /// </summary> class Abstraction { protected Implementor implementor; // Property public Implementor Implementor { set { implementor = value; } } public virtual void Operation () { implementor.Operation (); } } /// <summary> /// The 'Implementor' abstract class /// </summary> abstract class Implementor { public abstract void Operation (); } /// <summary> /// The 'RefinedAbstraction' class /// </summary> class RefinedAbstraction : Abstraction { public override void Operation () { implementor.Operation (); } } /// <summary> /// The 'ConcreteImplementorA' class /// </summary> class ConcreteImplementorA : Implementor { public override void Operation () { Console.WriteLine ("ConcreteImplementorA Operation"); } } /// <summary> /// The 'ConcreteImplementorB' class /// </summary> class ConcreteImplementorB : Implementor { public override void Operation () { Console.WriteLine ("ConcreteImplementorB Operation"); } } } OutputConcreteImplementorA OperationConcreteImplementorB Operationیا// Don't forget to add System.Configuration to the list of references in this program // Also add an "Implementor" entry in the <appSettings> section in app.config file. public abstract class Implementor { public abstract void OperationImp(); } public class ConcreteImplementorA: Implementor { public override void OperationImp() { Console.WriteLine("ConcreteImplementorA.OperationImp()"); } } public class ConcreteImplementorB: Implementor { public override void OperationImp() { Console.WriteLine("ConcreteImplementorB.OperationImp()"); } } public class DefaultImplementation: Implementor { public override void OperationImp() { Console.WriteLine("DefaultImplementation.OperationImp()"); } } public static class Implementation { public static Implementor GetImplementation() { var config = ConfigurationManager.AppSettings; if (config["Implementor"] == "ConcreteImplementorA") return new ConcreteImplementorA(); else if (config["Implementor"] == "ConcreteImplementorB") return new ConcreteImplementorB(); else return new DefaultImplementation(); } } public abstract class Abstraction { private Implementor implementor; public Abstraction() { this.implementor = Implementation.GetImplementation(); } public virtual void Operation() { Console.WriteLine("Abstraction.Operation()"); Console.WriteLine("Calling implementation using implementor ..."); implementor.OperationImp(); } } public class RefinedAbstraction: Abstraction { } public class Client { public static void Main() { Abstraction ra = new RefinedAbstraction(); ra.Operation(); Console.ReadKey(); } } /* OUTPUT:Abstraction.Operation()Calling implementation using implementor ...ConcreteImplementorA.OperationImp()*/ کد در دنیای واقعی الگوی پل را نشان می دهد که در آن یک انتزاع BusinessObject از پیاده سازی در DataObject جدا شده است. پیاده سازی DataObject می تواند بدون تغییر هیچ مشتری به طور پویا تکامل یابد.using System; using System.Collections.Generic; namespace DoFactory.GangOfFour.Bridge.RealWorld { /// <summary> /// MainApp startup class for Real-World /// Bridge Design Pattern. /// </summary> class MainApp { /// <summary> /// Entry point into console application. /// </summary> static void Main () { // Create RefinedAbstraction Customers customers = new Customers ("Chicago"); // Set ConcreteImplementor customers.Data = new CustomersData (); // Exercise the bridge customers.Show (); customers.Next (); customers.Show (); customers.Next (); customers.Show (); customers.Add ("Henry Velasquez"); customers.ShowAll (); // Wait for user Console.ReadKey (); } } /// <summary> /// The 'Abstraction' class /// </summary> class CustomersBase { private DataObject _dataObject; protected string group; public CustomersBase (string group) { this.group = group; } // Property public DataObject Data { set { _dataObject = value; } get { return _dataObject; } } public virtual void Next () { _dataObject.NextRecord (); } public virtual void Prior () { _dataObject.PriorRecord (); } public virtual void Add (string customer) { _dataObject.AddRecord (customer); } public virtual void Delete (string customer) { _dataObject.DeleteRecord (customer); } public virtual void Show () { _dataObject.ShowRecord (); } public virtual void ShowAll () { Console.WriteLine ("Customer Group: " + group); _dataObject.ShowAllRecords (); } } /// <summary> /// The 'RefinedAbstraction' class /// </summary> class Customers : CustomersBase { // Constructor public Customers (string group) : base (group) { } public override void ShowAll () { // Add separator lines Console.WriteLine (); Console.WriteLine ("------------------------"); base.ShowAll (); Console.WriteLine ("------------------------"); } } /// <summary> /// The 'Implementor' abstract class /// </summary> abstract class DataObject { public abstract void NextRecord (); public abstract void PriorRecord (); public abstract void AddRecord (string name); public abstract void DeleteRecord (string name); public abstract void ShowRecord (); public abstract void ShowAllRecords (); } /// <summary> /// The 'ConcreteImplementor' class /// </summary> class CustomersData : DataObject { private List<string> _customers = new List<string> (); private int _current = 0; public CustomersData () { // Loaded from a database _customers.Add ("Jim Jones"); _customers.Add ("Samual Jackson"); _customers.Add ("Allen Good"); _customers.Add ("Ann Stills"); _customers.Add ("Lisa Giolani"); } public override void NextRecord () { if (_current <= _customers.Count - 1) { _current++; } } public override void PriorRecord () { if (_current > 0) { _current--; } } public override void AddRecord (string customer) { _customers.Add (customer); } public override void DeleteRecord (string customer) { _customers.Remove (customer); } public override void ShowRecord () { Console.WriteLine (_customers[_current]); } public override void ShowAllRecords () { foreach (string customer in _customers) { Console.WriteLine (" " + customer); } } } } OutputJim JonesSamual JacksonAllen Good-- -- -- -- -- -- -- -- -- -- -- --Customer Group : ChicagoJim JonesSamual JacksonAllen GoodAnn StillsLisa GiolaniHenry Velasquez-- -- -- -- -- -- -- -- -- -- -- --منبع