设计模式(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/