• 二十三种设计模式[7]


    前言

           桥接模式,类结构型模式的一种。在《设计模式 -  可复用的面向对象软件》一书中将之描述为“ 将抽象部分与它的实现部分分离,使它们都可以独立的变化 ”。

          桥接模式可以帮助我们解决那些因为多层次的继承导致的类的个数急剧增加的问题。将抽象与实现的分离提高了类的复用性,同时也保证了各部分的独立性,方便后期的扩展。

    结构

    Bridge_1

    在桥接模式中,需要如下角色:

    • Abstraction(抽象类):一个功能或产品的抽象部分,在该类中聚合实现类接口;
    • RefinedAbstraction(扩充类):Abstraction角色的子类,一般作为抽象类的扩充类;
    • Implementor(实现类接口):定义功能的基本操作;
    • ConcreteImplementor(功能实现类):实现Implementor接口定义的操作;

    场景

           就拿我们每天接触的键盘、鼠标来说。键盘、鼠标有很多品牌,所以在创建鼠标以及键盘对象时,会先抽象出鼠标和键盘的接口,再去创建实现该接口的各个品牌的键盘、鼠标。

    Bridge_2

           之后,在给这个结构增加新的品牌时就需要为每一个产品接口增加一个它的实现类,同理增加新的产品时就需要为每个品牌增加一个实现这个产品接口的类。

    Bridge_3

           这还只是两个维度的变动,如果我们加上产品的型号、材质和颜色呢?那样,类的数量是不可预计的,并且每个维度的更改都会造成很大的连锁反应。现在我们使用桥接模式重新设计一下产品的结构。如下。

    Bridge_4

           从上面结构可以看出,我们只需要将不同的产品与不同的品牌组合就可以得到一个新的产品。当我们增加品牌或产品时,只需要增加接口的实现以及抽象的子类即可。大大的减少了类的数量,提高了类的复用性。其中,我们将产品抽象与品牌接口的关系称之为桥接。

    示例

    Bridge_5

    public interface IBrand
    {
        string GetBrandName();
    }
    
    public class Logitech : IBrand
    {
        public string GetBrandName()
        {
            return "罗技-Logitech";
        }
    }
    
    public class Raze : IBrand
    {
        public string GetBrandName()
        {
            return "雷蛇-Raze";
        }
    }
    
    public abstract class Product
    {
        public Product(IBrand brand)
        {
            this._brand = brand;
        }
    
        public IBrand _brand = null;
    
        public virtual string ShowMyself()
        {
            return $"{this._brand.GetBrandName()}的产品";
        }
    }
    
    public class Mouse : Product
    {
        public Mouse(IBrand brand) : base(brand) { }
    
        public override string ShowMyself()
        {
            return $"{base._brand.GetBrandName()}的鼠标";
        }
    }
    
    public class KeyBoard : Product
    {
        public KeyBoard(IBrand brand) : base(brand) { }
    
        public override string ShowMyself()
        {
            return $"{base._brand.GetBrandName()}的键盘";
        }
    }
    
    static void Main(string[] args)
    {
        IBrand Logitech = new Logitech();       //创建品牌
        Product mouse = new Mouse(Logitech);    //创建产品
        Console.WriteLine(mouse.ShowMyself());
    
        IBrand raze = new Raze();               //创建品牌
        Product keyboard = new KeyBoard(raze);  //创建产品
        Console.WriteLine(keyboard.ShowMyself());
    
        Console.ReadKey();
    }

    image

    总结

           桥接模式的中心思想就是利用聚合来代替接口的实现,将抽象与实现分离。它的的好处在于:

      1. 使得在实现部分发生改动时只需要重新编译实现部分而不需要重新编译抽象部分;
      2. 可以独立的对抽象、实现层次(每个维度的)结构进行扩展,符合开闭原则;
      3. 有助于系统的分层,实现更好的结构化体系;
      4. 可以对调用者隐藏具体的实现细节;

           但桥接模式需要我们准确的识别和预测出各个维度并将其分离,而且过度的使用会增加我们对程序的理解及设计的难度。

           以上,就是我对桥接模式的理解,希望对你有所帮助。

           示例源码:https://gitee.com/wxingChen/DesignPatternsPractice

           系列汇总:https://www.cnblogs.com/wxingchen/p/10031592.html

           本文著作权归本人所有,如需转载请标明本文链接(https://www.cnblogs.com/wxingchen/p/10078589.html)

  • 相关阅读:
    软工-第一次团队展示
    软工-第一次结对编程作业
    软工-第一次个人编程作业
    软工-第一次博客作业
    Apache下安装配置mod_pagespeed模块,轻松完成网站提速
    PHP网站在Linux服务器上安全设置方案
    MariaDB-5.5.32源码编译安装
    LNMP最新源码安装脚本(定期更新)
    Java容器解析系列(7) ArrayDeque 详解
    Java容器解析系列(8) Comparable Comparator
  • 原文地址:https://www.cnblogs.com/wxingchen/p/10078589.html
Copyright © 2020-2023  润新知