C#设计模式(10)——桥接模式

 1.桥接模式介绍

  桥接模式用于将抽象化和实现化解耦,使得两者可以独立变化。在面向对象中用通俗的话说明:一个类可以通过多角度来分类,每一种分类都可能变化,那么就把多角度分离出来让各个角度都能独立变化,降低各个角度间的耦合。这样说可能不太好理解,举一个画几何图形的例子:我们画的几何图形可以按照形状和颜色两个角度的进行分类,按形状分类,分为圆形、长方形、三角形,按照颜色分类分为蓝色图形、黄色图形和红色图形,而形状和颜色都是可以添加的,比如我们也可以添加五角星形状,颜色可以添加一个绿色。如果按继承来实现的话,如图1所示,我们需要的具体的子类就有9种(形状种类*颜色种类),如果我们添加一个五角星形状,则必须再添加蓝色五角星,黄色五角星和红色五角星三个具体子类,添加一种颜色也一样需要添加这个颜色的各种形状。当我们的形状和颜色的种类都很多时,就需要很多的具体子类,造成子类爆炸。
  画图的例子只有两个角度的分类,当一个类有更多角度分类时,具体子类种类(分类1种类*分类2种类*分类3种类...)就更多了。这时我们可以用桥接模式优化,将形状和颜色通过继承生产的强耦合关系改成弱耦合的关联关系,这里采用了组合大于继承的思想。如下图,采用桥接模式时,如果我们想添加一个五角星,只需要添加一个形状类的子类五角星接即可,不需要再去添加各种颜色的具体五角星了,如果我们想要一个蓝色五角星就将五角星和蓝色进行组合来获取。这样设计降低了形状和颜色的耦合,减少了具体子类的种类。

桥接模式的角色

Abstraction:抽象化生成的类,如形状类
Implementor:行为实现接口抽象化后关注的其他的特性,如例子中颜色接口。注意:我们可以把颜色抽象化生成抽象类,把形状作为行为实现接口;
RefinedAbstraction:抽象类子类,如圆形,长方形等;
ConcreteImplementor:行为实现接口的实现类,如黄色,红色等;
 
画几何图形例子的代码实现
 
形状抽象类和三种子类的形状:
   public abstract class Shape
    {
        //形状内部包含了另一个维度:color
        protected IColor color;
        public void SetColor(IColor color)
        {
            this.color = color;
        }
        //设置形状
        public abstract void Draw();
    }

    /// <summary>
    /// 圆形
    /// </summary>
    public class Circle : Shape
    {
        public override void Draw()
        {
            color.Paint("圆形");
        }
    }
    /// <summary>
    /// 长方形
    /// </summary>
    public class Rectangle : Shape
    {
        public override void Draw()
        {
            color.Paint("长方形");
        }
    }
    /// <summary>
    /// 三角形
    /// </summary>
    public class Triangle : Shape
    {
        public override void Draw()
        {
            color.Paint("三角形");
        }
    }

颜色接口和三种实现类:

   /// <summary>
    /// 颜色接口
    /// </summary>
    public interface IColor
    {
        void Paint(string shape);
    }
    /// <summary>
    /// 蓝色
    /// </summary>
    public class Blue : IColor
    {
        public void Paint(string shape)
        {
            Console.WriteLine($"蓝色的{shape}");
        }
    }
    /// <summary>
    /// 黄色
    /// </summary>
    public class Yellow : IColor
    {
        public void Paint(string shape)
        {
            Console.WriteLine($"黄色的{shape}");
        }
    }
    /// <summary>
    /// 红色
    /// </summary>
    public class Red : IColor
    {
        public void Paint(string shape)
        {
            Console.WriteLine($"红色的{shape}");
        }
    }

客户端调用代码:

    class Program
    {
        static void Main(string[] args)
        {
            Shape circle = new Circle();
            IColor blue = new Blue();
            circle.SetColor(blue);//设置颜色
            circle.Draw();//画图

            Shape triangle = new Triangle();
            triangle.SetColor(blue);
            triangle.Draw();

            Console.ReadKey();
        }
    }

程序运行结果

2.小结

上边例子的类图:

桥接模式的使用场景:

  当系统实现有多个角度分类,每种分类都可能变化时使用。近几年提出的微服务概念采用了桥接模式的思想,通过各种服务的组合来实现一个大的系统。

桥接模式的优点:

  1.实现抽象和具体的分离,降低了各个分类角度间的耦合;

  2.扩展性好,解决了多角度分类使用继承可能出现的子类爆炸问题。

桥接模式的缺点:

  桥接模式的引进需要通过聚合关联关系建立抽象层,增加了理解和设计系统的难度。

原文地址:https://www.cnblogs.com/wyy1234/p/10016051.html