zoukankan      html  css  js  c++  java
  • 设计模式学习总结桥接模式(Bridge Pattern)

    问题:
    在面向对象的设计中,抽象是一个很重要的概念,所谓抽象就是忽略一类对象的特殊特性,提出一些共有的特性,暂时忽略一些细节,而对与此类对象的变化可以使用继承的手段在子类中完成,换言之,用继承来应对抽象的变化。在软件系统中,当抽象由于某种原因也容易变动,使得对象从两个维度或更多方向上发生改变。使用继承方案往往违背了类的单一职责原则(即一个类只有一个变化的原因),复用性比较差。Bridge模式是比继承方案更好的解决方法。

    定义:
    桥接模式(Bridge Pattern),将抽象部分与它的实现部分分离,使的抽象和实现都可以独立地变化。

    意图:
    Bridge模式,系统被分为抽象(Abstraction)和实现(Implemetor)两个相对独立的部分抽象部(这里所谓的“抽象”与“实现”的含义不是指子类继承抽象基类实现具体的方法,抽象是指需求的抽象,而实现是指通过对象组合实现用户的需求),这两个部分可以互相独立地进行修改。Implemetor(还可以扩展到更多变化方向)部分的抽象,以抽象类的形式组合到抽象(Abstraction)部分的抽象类中,在抽象部分的主实现对象RefinedAbstraction中隔离了对实现部分(Implemetor)变化对象的具体实现(ConcreteImplemetor)的依赖。
    参与者:
    •抽象化(Abstraction)角色:抽象化给出的定义,并保存一个对实现化对象的引用。   
    •修正抽象化(Refined Abstraction)角色:扩展抽象化角色,改变和修正父类对抽象化的定义。   
    •实现化(Implementor)角色:这个角色给出实现化角色的接口,但不给出具体的实现。实现化角色给出的底层操作,抽象化角色给出基于底层操作的更高一层的操作。

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

    UML:

     
    实例说明:

    诺基亚手机工厂
    抽象的手机工厂要应对不同型号的手机(N8,N9的生产方式可能不一样)生产差异的变化,又要应对不同网络类型(GSM,CDMA生产方式可能不一样)的差异变化

    uml: 

    •使用继承模式:

    •使用桥接模式:

    代码:

    /// <summary>
    /// 手机生产抽象角色 抽象接口
    /// </summary>
    public abstract class PhoneFactory
    {
        protected PhoneNetType phoneNetType;
        public void SetNetType(PhoneNetType _phoneNetType)
        {
            phoneNetType = _phoneNetType;
        }
        public abstract void Create();
    }
    /// <summary>
    /// 手机生产 抽象角色 RefinedAbstraction
    /// </summary>
    public class  Factory_N8 : PhoneFactory
    {
        public override void Create()
        {
            phoneNetType.CreatePhone();
            System.Console.WriteLine("我是N8");
        }
    }
    /// <summary>
    /// 手机生产 抽象角色 RefinedAbstraction
    /// </summary>
    public class Factory_N9 : PhoneFactory
    {
        public override void Create()
        {
            phoneNetType.CreatePhone();
            System.Console.WriteLine("我是N9");
        }
    }
    /// <summary>
    /// 手机生产 Implementor
    /// </summary>
    public abstract class PhoneNetType
    {
        public abstract void CreatePhone();
    }
    /// <summary>
    /// 手机生产 ConcreteImplementor
    /// </summary>
    public class Factory_Csm : PhoneNetType
    {
        public override void CreatePhone()
        {
            System.Console.WriteLine("我是一款GSM网络手机。");
        }
    }
    /// <summary>
    /// 手机生产 ConcreteImplementor
    /// </summary>
    public class Factory_Cdma : PhoneNetType
    {
        public override void CreatePhone()
        {
            System.Console.WriteLine("我是一款CDMA网络手机。");
        }
    }
    /// <summary>
    /// 客户端测试代码
    /// </summary>
    public void BridgeTest()
    {
        PhoneFactory pf = new Factory_N8();
        pf.SetNetType(new Factory_Csm());
        pf.Create();
    }

    优点:
    •Bridge模式使用“合成/聚合复用原则”解耦了抽象和实现之间的高耦合关系,使得抽象和实现可以沿着各自的维度来变化(通过各自继承)。
    •抽象化角色和具体化角色之间增加更多的灵活性,当有新的抽象或实现方式时,只需要继承一个抽象和继承一个实现即可。
    •实现化角色的任何改变不影响客户端。

    缺点:
    •Bridge模式不能应对维度数量的变化,如果要重新抽象出另外一个维度类型,则需要修改抽象角色,将新的实现(Implemetor)组合进抽象(Abstraction)中,违反开闭原则
    应用情景:
    当系统有多维角度分类时,而每一种分类又有非常强的变化,时使用桥接模式比较合适
      

  • 相关阅读:
    ios6.0,程序为横屏,出现闪退
    [ios]objective-c中Category类别(扩展类)专题总结
    iOS Dev (26) 初步了解下UIColor的最常用知识
    CGGeometry.h详解
    ipa验证错误问题总结
    UITableView和UITableViewCell的几种样式
    willRotateToInterfaceOrientation 屏幕旋转
    ios 使用第三方框架注意
    automaticallyAdjustsScrollViewInsets 使用
    contentSize、contentInset和contentOffset区别
  • 原文地址:https://www.cnblogs.com/ejiyuan/p/2578272.html
Copyright © 2011-2022 走看看