桥接模式

                                          桥接模式

         桥接模式:将抽象部分与实现部分分离,使它们都可以独立的变化.这个模式的主要特点就是解决一个对象的可能变化的因素的多个方向的依赖性。有的时候一个对象,引起这个对象发生变化的因素很多,这个时候我们就可以考虑,把依赖具体实现,提升为依赖抽象,来完成对象和变化因素之间的低耦合,提高系统的可维护性和扩展性。而且客户可能不知道某个因素是否发生变化或者其他的可能情况。当然桥接模式也是结构性模式中一个比较难理解的模式,我们的项目中可能使用的相对来说少一些。

          在创建型模式里面,抽象不应该依赖于具体实现细节,实现细节应该依赖于抽象。看下面这幅图:

在这种情况下,如果抽象B稳定,而实现细节b变化,这时用创建型模式来解决没有问题。但是如果抽象B也不稳定,也是变化的,该如何解决?这就要用到Bridge模式了

        例如:现在有这样一个要求,需要将excel ,txt中从数据库中导出的一个表的数据读取出来。这时我们设计的类图如下:

                                           

代码如下:

 
    ///<summary>
    /// 接口
    /// </summary>
    public interface IFileHandle
    {
        object ReadData(string filePath);
    }

    public class TxtHandle : IFileHandle
    {
        public override object ReadData(string filePath)
        {
            DataTable dtData = null;
            dtData = GetTxtData(filePath);
            return dtData;
        }

        private DataTable GetTxtData(string filePath)
        {
            DataTable dtData = null;
            //读取txt文件中的数据
            return dtData;
        }

    }

    public class ExcelHandle : IFileHandle
    {
        public override object ReadData(string filePath)
        {
            DataTable dtData = null;
            dtData = GetExcelData(filePath);
            return dtData;
        }

        private DataTable GetExcelData(string filePath)
        {
            DataTable dtData = null;
            //读取Excel文件中的数据
            return dtData;
        }
    }

        过了一段时间,需求又有了新的变化,需要将excel ,txt中从数据库中导出的一个表的数据读取出来并转化为xml字符串输出,基于开发封闭原则,我们不会去修改原来的代码,有些人可能会采取继承的方式对类进行扩展,设计的类图就会变成下面的样子:

 

如果以后需求再发生变化,需要将excel ,txt,csv中从数据库中导出的一个表的数据读取出来并转化为xml,json字符串输出,如果还采用继承的方式对类进行扩展的话,类的设计图就会变成下图:

        这种存在很多问题,首先它在遵循开放-封闭原则的同时,违背了类的单一职责原则,即一个类只有一个引起它变化的原因,而这里引起变化的原因却有两个;其次是重复代码会很多;再次是类的结构过于复杂,继承关系太多,难于维护,最后最致命的一点是扩展性太差。上面我们分析的变化只是沿着某一个方向,如果变化沿着转化方式和读取两个方向变化,我们会看到这个类的结构会迅速的变庞大。

      如果我们分析了解好需求,在最开始就知道哪些方面会引起类的变化而采用桥接模式,应对这些需求的变化就会变的简单

先将转化字符串格式的实现抽象出来:代码如下:

public abstract class IConvert
{
    public abstract string ToString(DataTable dtData);
}

 public  class XmlConvert:IConvert
{
    public override  string ToString(DataTable dtData)
    {
        //转换为xml.....
    }
}

 public  class JsonConvert:IConvert
{
    public override  string ToString(DataTable dtData)
    {
        //转换为Json.....
    }
}

读取数据的实现如下:

///<summary>
    /// 抽象基类
    /// </summary>
    public abstract class IFileHandle
    {
        protected IConvert objConvert;
     
        public IConvert ObjConvert
        {
            set { objConvert = value; }    
        }

        public abstract object ReadData(string filePath);

    }

    public class TxtHandle : IFileHandle
    {
        public override object ReadData(string filePath)
        {
            DataTable dtData = null;
            dtData = GetTxtData(filePath);
            return objConvert.ToString(dtData);
        }

        private DataTable GetTxtData(string filePath)
        {
            DataTable dtData = null;
            //读取txt文件中的数据
            return dtData;
        }

    }

    public class ExcelHandle : IFileHandle
    {
        public override object ReadData(string filePath)
        {
            DataTable dtData = null;
            dtData = GetExcelData(filePath);
            return objConvert.ToString(dtData);
        }

        private DataTable GetExcelData(string filePath)
        {
            DataTable dtData = null;
            //读取Excel文件中的数据
            return dtData;
        }
    }


调用的代码如下:

public static void Main(string[] args)
        {
            string filePath = "......";
            //读取txt,输出xml
            TxtHandle tHandle = new TxtHandle();
            tHandle.objConvert = new XmlConvert();
            object  result = tHandle.ReadData(filePath);

            //读取excel,输出Json
            ExcelHandle tHandle2 = new ExcelHandle();
            tHandle2.objConvert = new JsonConvert();
            object result2 = tHandle.ReadData(filePath);
        }


 

效果及实现要点

1.Bridge模式使用“对象间的组合关系”解耦了抽象和实现之间固有的绑定关系,使得抽象和实现可以沿着各自的维度来变化。

2.所谓抽象和实现沿着各自维度的变化,即“子类化”它们,得到各个子类之后,便可以任意它们,从而获得不同平台上的不同型号。

3.Bridge模式有时候类似于多继承方案,但是多继承方案往往违背了类的单一职责原则(即一个类只有一个变化的原因),复用性比较差。Bridge模式是比多继承方案更好的解决方法。

4.Bridge模式的应用一般在“两个非常强的变化维度”,有时候即使有两个变化的维度,但是某个方向的变化维度并不剧烈——换言之两个变化不会导致纵横交错的结果,并不一定要使用Bridge模式。

适用性

在以下的情况下应当使用桥梁模式:

1.如果一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性,避免在两个层次之间建立静态的联系。

2.设计要求实现化角色的任何改变不应当影响客户端,或者说实现化角色的改变对客户端是完全透明的。

3.一个构件有多于一个的抽象化角色和实现化角色,系统需要它们之间进行动态耦合。

4.虽然在系统中使用继承是没有问题的,但是由于抽象化角色和具体化角色需要独立变化,设计要求需要独立管理这两者。




 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值