zoukankan      html  css  js  c++  java
  • C#设计模式(10)——桥接模式

    出处:https://www.cnblogs.com/wyy1234/

    阅读目录


     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.扩展性好,解决了多角度分类使用继承可能出现的子类爆炸问题。

    桥接模式的缺点:

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

  • 相关阅读:
    PHP实现无限极分类
    html2canvas生成并下载图片
    一次线上问题引发的过程回顾和思考,以更换两台服务器结束
    Intellij IDEA启动项目报Command line is too long. Shorten command line for XXXApplication or also for
    mq 消费消息 与发送消息传参问题
    idea 创建不了 java 文件
    Java switch 中如何使用枚举?
    Collections排序
    在idea 设置 git 的用户名
    mongodb添加字段和创建自增主键
  • 原文地址:https://www.cnblogs.com/frank0812/p/11280213.html
Copyright © 2011-2022 走看看