桥接模式



类图:

image.png


桥梁模式所涉及的角色有:
  • 抽象化(Abstraction)角色:抽象化给出的定义,并保存一个对实现化对象的引用。

  • 修正抽象化(RefinedAbstraction)角色:扩展抽象化角色,改变和修正父类对抽象化的定义。

  • 实现化(Implementor)角色:这个角色给出实现化角色的接口,但不给出具体的实现。必须指出的是,这个接口不一定和抽象化角色的接口定义相同,实际上,这两个接口可以非常不一样。实现化角色应当只给出底层操作,而抽象化角色应当只给出基于底层操作的更高一层的操作。

  • 具体实现化(ConcreteImplementor)角色:这个角色给出实现化角色接口的具体实现。


咖啡的例子

原文见:https://zhuanlan.zhihu.com/p/58903776


类图:

image.png



这里勇哥给出C#的演示代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 桥接模式_点咖啡2
{
    /*
    项目经理突然过来了:蛋大啊,客户那边说了,
    他们准备加两个容量规格的咖啡,大杯和小杯,你改一下。


   加着加着蛋大慌了,共需要3x2=6个类啊,大杯原味和加糖,中杯原味和加糖,小杯原味和加糖。
   过段时间万一那二笔客户又要出加奶,加蜂蜜等等口味,
   说不定还有迷你杯,女神杯等等规格的咖啡,
   那我这边的类不就爆炸了吗?看来的去找个设计模式了。。。
   
   此场景桥接模式正合适,这里有两个变化维度,咖啡的容量和口味,
   而且都需要独立变化。如果使用继承的方式,随着变化类就会急剧的增加。
   你可以将容量理解为抽象部分,而口味理解为实现部分,这两个部分需要桥接。
   */
   
    class Program
    {
        static void Main(string[] args)
        {
            RefinedAbstraction db = new 大杯牛奶(new 加奶());
            db.orderCoffee(2);
            db.checkQuality();

            Console.ReadKey();
        }
    }


    /// <summary>
    /// 抽象化(Abstraction)角色
    /// </summary>
    public abstract class Abstraction
    {
        protected abstract Implementor 口味 { get; set; }
        public Abstraction(Implementor _口味)
        {
            this.口味 = _口味;
        }

        public abstract void orderCoffee(int count);
    }

    /// <summary>
    /// 修正抽象化(RefinedAbstraction)角色
    /// </summary>
    public abstract class RefinedAbstraction : Abstraction
    {
        protected override Implementor 口味 { get; set; }
        public RefinedAbstraction(Implementor _口味) : base(_口味)
        {
            口味 = _口味;
        }

        public void checkQuality()
        {
            Console.WriteLine($"{口味.GetType().Name},正常");
        }

    }


    public class 大杯牛奶 : RefinedAbstraction
    {
        protected override Implementor 口味 { get; set; }
        public 大杯牛奶(Implementor add) : base(add)
        {
            口味 = add;
        }

        public override void orderCoffee(int count)
        {
            口味.addSomething();
            Console.WriteLine($"大杯咖啡{count}杯");
        }
    }


    /// <summary>
    /// 实现化(Implementor)角色
    /// </summary>
    public interface Implementor
    {
        void addSomething();
    }

    /// <summary>
    /// 具体实现化(ConcreteImplementor)角色1
    /// </summary>
    public class 加奶 : Implementor
    {
        public void addSomething()
        {
            Console.WriteLine($"加奶");
        }
    }

    /// <summary>
    /// 具体实现化(ConcreteImplementor)角色2
    /// </summary>
    public class 加糖 : Implementor
    {
        public void addSomething()
        {
            Console.WriteLine($"加糖");
        }
    }



}



这篇文章有位读者的点评很能说明桥接模式的特点:将m*n个实现类转换为m+n个实现类



图片在不同系统下显示


原文链接:

https://www.jianshu.com/p/516a6beb42c3



代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            WindowsSystem win = new WindowsSystem();
            LinuxSystem lin = new LinuxSystem();

            Image jpgSys = new JPGImage(system: win, format: "jpg");
            jpgSys.ParseFile();

            Image jpgLin = new JPGImage(system: lin, format: "jpg");
            jpgLin.ParseFile();

            Image pngSys = new PNGImage(system: win, format: "png");
            pngSys.ParseFile();

            Image pngLin = new PNGImage(system: lin, format: "png");
            pngLin.ParseFile();

            Console.ReadKey();
        }
    }



    public abstract class Image
    {
        public System System { get; protected set; }
        public string Format { get; protected set; }

        public Image(System system, string format)
        {
            System = system;
            Format = format;
        }

        public void ParseFile()
        {
            System.Show(Format);
        }
    }

    public class JPGImage : Image
    {
        public JPGImage(System system, string format) : base(system, format) { }
    }

    public class PNGImage : Image
    {
        public PNGImage(System system, string format) : base(system, format) { }
    }

    public abstract class System
    {
        public virtual void Show(string format)
        {
            // 基础实现,可以在子类中被覆盖  
        }
    }

    public class WindowsSystem : System
    {
        public override void Show(string format)
        {
            Console.WriteLine($"{format}格式在Windows系统下显示");
        }
    }

    public class LinuxSystem : System
    {
        public override void Show(string format)
        {
            Console.WriteLine($"{format}格式在Linux系统下显示");
        }
    }
}


结果:

image.png


需求V2:增加新的图像文件格式TIF

只需要创建TIFImage继承自Image即可

public class TIFImage : Image  
{  
    //public TIFImage(System system, string format) : base(system, format) { }  
}

TIFImage tifSys = new TIFImage(system: win, format: "tif");  
tifSys.ParseFile();  
  
TIFImage tifLin = new TIFImage(system: lin, format: "tif");  
tifLin.ParseFile();


需求V3:增加一个新的操作系统Mac OS

只需要创建MacOSSystem继承自System即可

public class MacOSSystem : System  
{  
    public override void Show(string format)  
    {  
        Console.WriteLine($"{format}格式在Mac OS系统下显示");  
    }  
}  
  
//客户端:  
MacOSSystem mac = new MacOSSystem();  
  
Image jpgMac = new JPGImage(system: mac, format: "jpg");  
jpgMac.ParseFile();  
  
Image pngMac = new PNGImage(system: mac, format: "png");  
pngMac.ParseFile();  
  
Image tifMac = new TIFImage(system: mac, format: "tif"); 
// 注意这里应该是TIFImage而不是JPGImage  
tifMac.ParseFile();




另一篇:

https://zhuanlan.zhihu.com/p/666037755


https://baijiahao.baidu.com/s?id=1736389582955994797&wfr=spider&for=pc



本文出自勇哥的网站《少有人走的路》wwww.skcircle.com,转载请注明出处!讨论可扫码加群:
本帖最后由 勇哥,很想停止 于 2023-11-30 16:31:45 编辑

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

会员中心
搜索
«    2024年4月    »
1234567
891011121314
15161718192021
22232425262728
2930
网站分类
标签列表
最新留言
    热门文章 | 热评文章 | 随机文章
文章归档
友情链接
  • 订阅本站的 RSS 2.0 新闻聚合
  • 扫描加本站机器视觉QQ群,验证答案为:halcon勇哥的机器视觉
  • 点击查阅微信群二维码
  • 扫描加勇哥的非标自动化群,验证答案:C#/C++/VB勇哥的非标自动化群
  • 扫描加站长微信:站长微信:abc496103864
  • 扫描加站长QQ:
  • 扫描赞赏本站:
  • 留言板:

Powered By Z-BlogPHP 1.7.2

Copyright Your skcircle.com Rights Reserved.

鄂ICP备18008319号


站长QQ:496103864 微信:abc496103864