第十三课 桥接模式

第十三课  桥接模式

 

概述:

有没有碰到过这样的情况。在系统中,有些复杂逻辑,它具有两个以上维度的变化,这样的话,就无法遵循类的单一原则,提高了关系复杂性,难于维护。那么这种情况下,应当怎么来将他的2个变化点剥离呢?就是桥接模式了。

这里使用一个日志记录模块的设计来进行说明。

需求如下:

首先,我要实现一个日志记录功能,要求能够扩展多种记录方式,例如:数据库,文本,xml 等。然后要支持 windows 平台,又要支持linux平台。 那么我们怎么来设计这个模块的结构呢?

1.       定义基类Log

2.       对应数据库模式的 DBLog

3.       对应文本模式的   TextLog

4.       对应XML模式的  XMLLog

 

然后呢,我们好需要他支持多个平台。怎么办?各个模式下面在扩展平台吗?如下图。

 

       显然这样是不好的。为什么这么说呢,首先这Log上面有两个变化点,日志模式,和操作平台。这显然不符合类的单一职责原则,会造成复杂的变化,难于维护和扩展。那么怎么解决呢。一直看我这一设计模式系列的人可能会很快想到适配器模式吧。把平台这里构件化,使用适配器的方式可以解决问题吧。没错,就是这个思路,但是结构怎么设计呢?如何将适配器模式结合进来呢。方法是,提供一个平行逻辑,如下图所示。

 

 

1.       基于操作系统构件的基类 Slog

2.       Windows系统的 WLog

3.       Linux 系统的 LLog

4.       Unix系统的 ULog

 

然后将起作为Log的构件引入。形成如下关系。

 

这样就将模式变化和平台变化分离出来了,那么如何结合起来呢?使用类似适配器模式那样,在Log中定义一个Slog的对象,在不同实现的时候,使用Slog对象来执行操作即可。下面使用代码实现吧。

 

C#:代码

 

using System;

using System.Collections.Generic;

using System.Text;

 

namespace ConsoleApplication2

{

    class Program

    {

        static void Main(string[] args)

        {

            Log logger = new TextLog();

            logger.Implementor = new WLog();

            logger.Write("Log Test");

            Console.Read();

        }

    }

 

   

 

    public abstract class Log

    {

 

        protected SLog implementor;

 

 

 

        public SLog Implementor

        {

 

            set { implementor = value; }

 

        }

 

 

        public virtual void Write(string log)

        {

 

            implementor.Execute(log);

 

        }

 

    }

 

 

    public class DBLog : Log

    {

 

        public override void Write(string log)

        {

 

            implementor.Execute(log);

 

        }

 

    }

 

 

    public class TextLog : Log

    {

 

        public override void Write(string log)

        {

 

            implementor.Execute(log);

 

        }

 

    }

 

    public class XMLLog : Log

    {

 

        public override void Write(string log)

        {

 

            implementor.Execute(log);

 

        }

 

    }

 

    public abstract class SLog

    {

 

        public abstract void Execute(string msg);

 

    }

 

 

    public class WLog : SLog

    {

 

        public override void Execute(string msg)

        {

 

            Console.WriteLine("Windows下记录:"+msg);

 

        }

 

    }

 

 

    public class LLog : SLog

    {

 

        public override void Execute(string msg)

        {

 

            Console.WriteLine("Linux下记录:" + msg);

 

        }

 

    }

 

    public class ULog : SLog

    {

 

        public override void Execute(string msg)

        {

 

            Console.WriteLine("Unix下记录:" + msg);

 

        }

 

    }

 

}

 

     看明白了吗,这里分别用了两个线路封装两种变化点,通过类似适配器方式,进行了结合使用。相当于将两部分桥接起来了,这也就是桥接模式了。

    可能有人会说,这样客户端调用的时候耦合性就高了,需要设置相匹配的平台对象。但是,忘了吗,用工厂里面提到的映射方法可以吗?嘿嘿,自己试着通过配置来初始化Log吧。

 

总结:

1.     当要设计一个类对象,但是这个类对象有多个变化点时,可以考虑通过桥接分离变化。

2.     如果两个变化点变化概率很小,就需要你好好衡量是否需要使用桥梁模式。桥梁模式相对复杂,没有必要的话不推荐使用。

3.     桥梁模式会产生类对象间耦合性,但是可以考虑使用其他设计模式来解决耦合问题,例如通过抽象工厂结合反射来获得对象。

 

以上

 

作者:王文斌

转载请注明出处

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值