Bridge桥接模式(结构型模式)
现有一个需求,一个游戏系统需要构建不同风格的房屋,暂不考虑其他设计模式,需要能实现在PC端、移动端....等等多个平台的构建.最简单的实现方式如下:
/// <summary>
/// 房屋抽象
/// </summary>
public abstract class House
{
/// <summary>
/// 不同平台的初始化方法
/// </summary>
public abstract void PlatformInit(); /// <summary>
/// 绘制窗户
/// </summary>
public abstract void DrowWindow(); /// <summary>
/// 绘制门
/// </summary>
public abstract void DrowDoor();
} /// <summary>
/// PC版的现代化房屋构建过程
/// </summary>
public class PCModernHouse : House
{ public override void DrowDoor()
{ } public override void DrowWindow()
{ } public override void PlatformInit()
{
//这里初始化构建PC版的现代化房屋所需要的PC平台的相关信息
}
} /// <summary>
/// 移动端的现代化房屋构建过程
/// </summary>
public class MobileModernHouse : House
{
public override void DrowDoor()
{ } public override void DrowWindow()
{ } public override void PlatformInit()
{
//这里初始化构建移动端的现代化房屋所需要的移动端平台的相关信息
}
} /// <summary>
/// PC版经典房屋
/// </summary>
public class PCClassicalHouse : House
{
public override void DrowDoor()
{ } public override void DrowWindow()
{ } public override void PlatformInit()
{
//这里初始化构建PC版经典房屋所需要的PC平台的相关信息
}
} /// <summary>
/// 移动版经典房屋
/// </summary>
public class MobileClassicalHouse : House
{
public override void DrowDoor()
{ } public override void DrowWindow()
{ } public override void PlatformInit()
{
//这里初始化构建移动版经典房屋所需要的移动版平台的相关信息
}
}
ok,这种设计虽然能很好的满足需求,但是这里只列举了两种平台,如果之后需要支持更多的平台,这种设计模式显然不行,因为产生的类会原来越多.随之维护的成本也越来越大.
so.分析代码,发现设计中有两个变化点,一个是House,另一个是平台,而上面的代码并没有把平台作为变化点抽离出来,所以需要将平台抽离抽来,接下来,对代码进行重构.
思考:由于House的固有逻辑,使得House具有两个维护的变化一一一个变化维度为"平台的变化",另一个变化维度为"风格的变化".那么如何解决这种维度的变化?如何利用OOP,来轻松地使得House以"平台"和"风格"两个方向变化?这就是桥接模式要解决的问题:
利用Bridge桥接模式重构后的代码如下:
#region 抽象
/// <summary>
/// 房屋抽象
/// </summary>
public abstract class House
{
protected HousePlatform _housePlatform; public House(HousePlatform housePlatform)
{
_housePlatform = housePlatform;
} public HousePlatform HousePlatform => _housePlatform; /// <summary>
/// 绘制窗户
/// </summary>
public abstract void DrowWindow(); /// <summary>
/// 绘制门
/// </summary>
public abstract void DrowDoor();
} /// <summary>
/// 平台抽象
/// </summary>
public abstract class HousePlatform
{
public abstract HousePlatform Init();
}
#endregion #region 实现 /// <summary>
/// 现代化房屋
/// </summary>
public class ModernHouse : House
{
private HousePlatform _platform;
public ModernHouse(HousePlatform housePlatform) : base(housePlatform)
{
_platform = HousePlatform.Init();
} public override void DrowDoor()
{
//执行HousePlatform实例的一些方法,然后做自己的逻辑
} public override void DrowWindow() { }
} /// <summary>
/// 经典房屋
/// </summary>
public class ClassicalHouse : House
{
private HousePlatform _platform;
public ClassicalHouse(HousePlatform housePlatform) : base(housePlatform)
{
_platform = housePlatform.Init();
} public override void DrowDoor() { } public override void DrowWindow() { }
} /// <summary>
/// PC平台
/// </summary>
public class PCPlatform : HousePlatform
{
public override HousePlatform Init()
{
//执行PC平台的初始化方法,返回一个PCPlatform对象实例供对应的房屋使用
return this.MemberwiseClone() as HousePlatform;
}
} /// <summary>
/// 移动端平台
/// </summary>
public class MobilePlatform : HousePlatform
{
public override HousePlatform Init()
{
//执行移动端平台的初始化方法,返回一个MobilePlatform对象实例供对应的房屋使用
return this.MemberwiseClone() as HousePlatform;
}
} #endregion
客户端调用代码如下:
public class GameSystem
{
public void Build()
{
//构建了一个基于PC平台的现代化房屋
var modernHouse = new ModernHouse(new PCPlatform());
modernHouse.DrowDoor();
modernHouse.DrowWindow();
}
}
将变化点平台也分离出来,并抽象出一个接口,并通过构造函数的方式将两个变化点桥接到一起,可以理解为组合到一起,这就是桥接模式.
桥接模式使用的要点:
1、Bridge桥接模式一般是用在两个变化剧烈的维度,如上面的房屋的风格和平台的类型都是变化非常剧烈的,但如果有一个维度变化并不剧烈,则并需要使用桥接模式.
2、抽象和实现沿着各自纬度的变化,比如不同风格的房屋和不同的平台.得到各个子类之后,便可以不同的方式组合它们,便可以得到不同平台下的不同风格的房屋.
3、多继承关系,可以考虑使用Bridge模式来实现.多继承方案往往违背oop的单一职责.Bridge模式是比多继承更好的选择.
4、Bridge模式使用对象组合关系,解耦了抽象和实现之间固有的绑定关系,使得抽象(不同风格的房屋)和实现(不同的平台)可以沿着各自的维度变化.
,
Bridge桥接模式(结构型模式)的更多相关文章
- 代理模式/proxy模式/结构型模式
代理模式proxy 定义 为其他对象提供一种代理,并以控制对这个对象的访问.最简单的理解,买东西都是要去商店的,不会去工厂. java实现三要素 proxy(代理)+subject(接口)+realS ...
- 设计模式(十二): Flyweight享元模式 -- 结构型模式
说明: 相对于其它模式,Flyweight模式在PHP实现似乎没有太大的意义,因为PHP的生命周期就在一个请求,请求执行完了,php占用的资源都被释放.我们只是为了学习而简单做了介绍. 1. 概述 面 ...
- 设计模式(十三): Proxy代理模式 -- 结构型模式
设计模式(十一)代理模式Proxy(结构型) 1.概述 因为某个对象消耗太多资源,而且你的代码并不是每个逻辑路径都需要此对象, 你曾有过延迟创建对象的想法吗 ( if和else就是不同的两条逻辑路 ...
- 设计模式学习之路——Facade 外观模式(结构型模式)
动机: 组件的客户和组件中各种复杂的子系统有了过多的耦合,随着外部客户程序和各子系统的演化,这种过多的耦合面临很多变化的挑战.如何简化外部客户程序和系统间的交互接口?如何将外部客户程序的演化和内部子系 ...
- 设计模式(十一):FACADE外观模式 -- 结构型模式
1. 概述 外观模式,我们通过外观的包装,使应用程序只能看到外观对象,而不会看到具体的细节对象,这样无疑会降低应用程序的复杂度,并且提高了程序的可维护性.例子1:一个电源总开关可以控制四盏灯.一个风扇 ...
- 设计模式(十):Decorator装饰者模式 -- 结构型模式
1. 概述 若你从事过面向对象开发,实现给一个类或对象增加行为,使用继承机制,这是所有面向对象语言的一个基本特性.如果已经存在的一个类缺少某些方法,或者须要给方法添加更多的功能(魅力),你也许会仅仅继 ...
- 设计模式(八):Bridge桥接模式 -- 结构型模式
1. 概述 在软件系统中,某些类型由于自身的逻辑,它具有两个或多个维度的变化,那么如何应对这种“多维度的变化”?如何利用面向对象的技术来使得该类型能够轻松的沿着多个方向进行变化,而又不引入额外的复杂度 ...
- 适配器模式/adapter模式/结构型模式
定义 将类的接口转化为客户端希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的类可以一起工作,别名Wrapper(包装器). 适配器模式,最终改变一个已有对象的接口. 使用场景 当有那么个类, ...
- 外观模式/facade模式/结构型模式
外观模式 为子系统中的一组接口提供一个一致的界面, Facade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用. 外观模式三要素(client-facade-subSystem) 外观角色 ...
随机推荐
- CodeForces 235E Number Challenge (莫比乌斯反演)
题意:求,其中d(x) 表示 x 的约数个数. 析:其实是一个公式题,要知道一个结论 知道这个结论就好办了. 然后就可以解决这个问题了,优化就是记忆化gcd. 代码如下: #pragma commen ...
- laravel 5.1 使用Eloquent ORM 操作实例
Laravel 的 Eloquent ORM 提供了更优雅的ActiveRecord 实现来和数据库的互动. 每个数据库表对应一个模型文件. 数据库配置 .env文件(也可以直接修改config/da ...
- Arria10中的IOPLL与fPLL
最近在用Arria10.从480降到270的过程中,IOPLL出现问题,大概是说几个Bank的IOPLL已经被占用,没有空间再给别的IOPLL去适配. 因为在工程中,所用的PLL多达35个之多,其中明 ...
- WordPaster2产品介绍
更新WordParser组件,集成ImagePaster组件功能.完善粘贴剪帖板图片,粘贴电脑图片文件,粘贴word,粘贴excel逻辑. 大幅度优化和精简js代码,js代码行数从1932行减少到97 ...
- C#重点内容之:接口(interface)(一)网络初级示例
这一篇来源于网络,简单介绍了接口的概念 接口是体现面向对象编程思想优越性的一件利器,为什么这么说呢? 首先我们来看,接口是为继承而存在的,如果没有继承,那就自然不需要接口了,既然有继承,那就需要把可能 ...
- re模块,subprocess模块
""" RE是什么 正则 表达 式子 就是一些带有特殊含义的符号或者符号的组合 它的作用是对字符串进行过滤 在一堆字符串中找到你所关心的内容 你就需要告诉计算机你的过滤规 ...
- Shell编程-12-Shell脚本规范及调试
目录 Shell脚本规范 Shell脚本调试 Shell脚本规范 良好的代码规范不仅方便阅读,也利于维护和提升开发效率.因此建议大家在编写Shell脚本时养成良好的代码习惯.今天就和大家探讨一 ...
- 如何更改linux文件的拥有者及用户组(chown和chgrp)
http://blog.csdn.net/hudashi/article/details/7797393 一.基本知识 在Linux中,创建一个文件时,该文件的拥有者都是创建该文件的用户.该文件用 ...
- redis简单使用
主要参考资料:http://wiki.jikexueyuan.com/project/redis-guide/data-type.html一.redis 安装1.在官网下载安装包2.解压安装包 tar ...
- Codeforces Round #265 (Div. 2) C. No to Palindromes! 构造不含回文子串的串
http://codeforces.com/contest/465/problem/C 给定n和m,以及一个字符串s,s不存在长度大于2的回文子串,现在要求输出一个字典比s大的字符串,且串中字母在一定 ...