zoukankan      html  css  js  c++  java
  • 设计模式之桥接模式(八)

    设计模式之桥接模式

    一、引言

      每个人都有吃饭睡觉的行为,这时我们可以抽象出来一个人类型,然后让每个人去继承人类型,这时,每增加一个人,我们只需扩展一个子类就可以了,但是,人类型需要增加行为时,比如增加一个玩手机的行为,我们只许在人类型中扩展玩手机这一个方法,但是对于子类来说,如果这时子类数量相当庞大时,子类需要进行大量的修改。

      我们可以使用桥接模式,将抽象和实现分离。

    二、介绍

      桥接(Bridge)是用于把抽象化与实现化解耦,使得二者可以独立变化。这种类型的设计模式属于结构型模式,它通过提供抽象化和实现化之间的桥接结构,来实现二者的解耦。

    意图:将抽象部分与实现部分分离,使它们都可以独立的变化。

    主要解决:在有多种可能会变化的情况下,用继承会造成类爆炸问题,扩展起来不灵活。

    何时使用:实现系统可能有多个角度分类,每一种角度都可能变化。

    如何解决:把这种多角度分类分离出来,让它们独立变化,减少它们之间耦合。

    关键代码:抽象类依赖实现类。

    应用实例: 1、猪八戒从天蓬元帅转世投胎到猪,转世投胎的机制将尘世划分为两个等级,即:灵魂和肉体,前者相当于抽象化,后者相当于实现化。生灵通过功能的委派,调用肉体对象的功能,使得生灵可以动态地选择。 2、墙上的开关,可以看到的开关是抽象的,不用管里面具体怎么实现的。

    优点: 1、抽象和实现的分离。 2、优秀的扩展能力。 3、实现细节对客户透明。

    缺点:桥接模式的引入会增加系统的理解与设计难度,由于聚合关联关系建立在抽象层,要求开发者针对抽象进行设计与编程。

    使用场景: 1、如果一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性,避免在两个层次之间建立静态的继承联系,通过桥接模式可以使它们在抽象层建立一个关联关系。 2、对于那些不希望使用继承或因为多层次继承导致系统类的个数急剧增加的系统,桥接模式尤为适用。 3、一个类存在两个独立变化的维度,且这两个维度都需要进行扩展。

    注意事项:对于两个独立变化的维度,使用桥接模式再适合不过了。

    三、UML图

    55555

          桥接模式主要包含如下几个角色:

          Abstraction:抽象类。 
          RefinedAbstraction:扩充抽象类。 
          Implementor:实现类接口。 
          ConcreteImplementor:具体实现类
     。

      这是我找的一张图,下面就根据这张图来书写代码。

    三、代码展示

    namespace Bridge
    {
        /// <summary>
        /// UML中的 Implementor
        /// </summary>
        public interface IOldPelple
        {
            void Eat();
    
            void Sleep();
    
        }
    }
    Implementor
    namespace Bridge
    {
        /// <summary>
        /// UML 中的ConcreteImplementorA
        /// </summary>
        public class XiaoMing : IOldPelple
        {
            public void Eat()
            {
                Console.WriteLine("小明在吃饭。。。");
            }
    
            public void Sleep()
            {
                Console.WriteLine("小明在睡觉。。。");
            }
        }
    }
    ConcreteImplementorA
    namespace Bridge
    {
        /// <summary>
        /// UML 中的ConcreteImplementorB
        /// </summary>
        public class XiaoHong : IOldPelple
        {
            public void Eat()
            {
                Console.WriteLine("小红在吃饭。。。");
            }
    
            public void Sleep()
            {
                Console.WriteLine("小红在睡觉。。。");
            }
        }
    }
    ConcreteImplementorB
    namespace Bridge
    {
        /// <summary>
        /// UML中的Abstraction
        /// </summary>
        public abstract class People
        {
            public IOldPelple oldPelple;
            public People(IOldPelple o) {
                this.oldPelple = o;
            }
    
            public void Eat() {
                oldPelple.Eat();
            }
    
            public void Sleep()
            {
                oldPelple.Sleep();
            }
            public abstract void PlayPhone();
    
        }
    }
    Abstraction
    namespace Bridge
    {
    
        /// <summary>
        /// UML中的RefinedAbstraction
        /// </summary>
        public class ConcretePeople:People
        {
            public ConcretePeople(IOldPelple o) : base(o)
            {
    
            }
    
            public override void PlayPhone()
            {
                Console.WriteLine("我在玩手机哦。。。");
            }
        }
    }
    RefinedAbstraction

    四、运行结果

  • 相关阅读:
    连续子数组的最大和
    孩子们的游戏(圆圈中最后剩下的数)
    左旋转字符串
    业界难题-“跨库分页”的四种方案
    InnoDB意向锁的作用
    Linux下Fork与Exec使用
    minixml的安装教程
    main()函数的形参
    结构体数组初始化
    fork函数详解
  • 原文地址:https://www.cnblogs.com/zkhbalance/p/9424985.html
Copyright © 2011-2022 走看看