设计模式(7)桥接模式

模式介绍

桥接模式试图将抽象与它的实现解耦,使得两者可以独立地变化。

示例

现实中,我哥有某种疾病,所以不能吃包含谷类麦类的食物。
我们以此为例,构建一个从不同餐馆购买特供的食物。

interface IOrder { }
class DairyFreeOrder : IOrder { }//无奶的
class GlutenFreeOrder : IOrder { }//无谷蛋白的

如果我们还想知道食物是哪家餐馆的,那就会这么写:

interface IOrder { }
class DairyFreeOrder : IOrder { }
class GlutenFreeOrder : IOrder { }
interface IDinerOrder : IOrder { }
class DinerDairyFreeOrder : DairyFreeOrder, IDinerOrder { }
class DinerGlutenFreeOrder : GlutenFreeOrder, IDinerOrder { }
interface IFancyRestaurantOrder : IOrder { }
class FancyRestaurantDairyFreeOrder : DairyFreeOrder, IFancyRestaurantOrder { }
class FancyRestaurantGlutenFreeOrder : GlutenFreeOrder, IFancyRestaurantOrder { }

我们建模两个正交属性,就需要3个接口和6个类,有些过分了。
这个时候,桥接模式就发挥作用了,它划分接口责任使之可以重用:

interface IOrder { }
class DairyFreeOrder : IOrder { } 
class GlutenFreeOrder : IOrder { } 

interface IRestaurantOrder : IOrder { }
class DinerOrder : IRestaurantOrder { }
class FancyRestaurantOrder : IRestaurantOrder { }

接下来,我们详细使用桥接模式。
首先,我们先写Implementor用于定义发订单的接口IOrderingSystem

/// <summary>
/// Implementor which defines an interface for placing an order
/// </summary>
public interface IOrderingSystem
{
    void Place(string order);
}

其次,我们定义一个抽象的SendOrder类,内部对Implementor进行引用

/// <summary>
/// Abstraction which represents the sent order and maintains a reference to the restaurant where the order is going.
/// </summary>
public abstract class SendOrder
{
    //Reference to the Implementor
    public IOrderingSystem _restaurant;

    public abstract void Send();
}

SendOrder的具体实现

/// <summary>
/// RefinedAbstraction for a dairy-free order
/// </summary>
public class SendDairyFreeOrder : SendOrder
{
    public override void Send()
    {
        _restaurant.Place("Dairy-Free Order");
    }
}

/// <summary>
/// RefinedAbstraction for a gluten free order
/// </summary>
public class SendGlutenFreeOrder : SendOrder
{
    public override void Send()
    {
        _restaurant.Place("Gluten-Free Order");
    }
}

OrderingSystem具体实现

/// <summary>
/// ConcreteImplementor for an ordering system at a diner.
/// </summary>
public class DinerOrders : IOrderingSystem
{
    public void Place(string order)
    {
        Console.WriteLine("Placing order for " + order + " at the Diner.");
    }
}

/// <summary>
/// ConcreteImplementor for an ordering system at a fancy restaurant.
/// </summary>
public class FancyRestaurantOrders : IOrderingSystem
{
    public void Place(string order)
    {
        Console.WriteLine("Placing order for " + order + " at the Fancy Restaurant.");
    }
}

客户端调用

static void Main(string[] args)
{
    SendOrder _sendOrder = new SendDairyFreeOrder();
    _sendOrder._restaurant = new DinerOrders();
    _sendOrder.Send();

    _sendOrder._restaurant = new FancyRestaurantOrders();
    _sendOrder.Send();

    _sendOrder = new SendGlutenFreeOrder();
    _sendOrder._restaurant = new DinerOrders();
    _sendOrder.Send();

    _sendOrder._restaurant = new FancyRestaurantOrders();
    _sendOrder.Send();

    Console.ReadKey();
}

总结

当设计可能存在多种不同类型继承的系统时,该模式非常有用。

源代码

https://github.com/exceptionnotfound/DesignPatterns/tree/master/Bridge

原文

https://www.exceptionnotfound.net/the-daily-design-pattern-bridge/

posted @ 2018-10-23 11:12  talentzemin  阅读(135)  评论(0编辑  收藏  举报