软件体系结构- 桥接模式
Python中的桥接模式

Python中的桥接模式Python中的桥接模式桥接模式是一种软件设计模式,通过将抽象部分与实现部分分离来实现解耦,使得两者可以独立地变化。
在Python中,桥接模式可以帮助我们优雅地解决面向对象编程中的一些常见问题,例如类的扩展性、代码的可读性和可维护性等。
1.桥接模式的基本概念桥接模式的核心思想是:将实现部分与抽象部分分离,使它们可以独立地变化。
在桥接模式中,抽象部分通常是一个抽象类或者接口,它定义了一些基本的功能和方法,但是没有具体的实现。
而实现部分则是一个或多个实现类,它们实现了抽象部分中定义的方法和功能。
通过抽象部分和实现部分之间的桥梁,我们可以将它们连接起来,达到解耦的目的。
桥梁通常是一个包含抽象部分对象和实现部分对象的组合对象。
通过桥梁对象,我们可以将抽象部分和实现部分有效地分离,从而实现更好的可扩展性和可维护性。
2.桥接模式的应用场景桥接模式通常适用于以下几种场景:(1)有多个相互独立的变化维度,且需要在运行时动态组合。
(2)需要隔离抽象部分和实现部分,使得它们可以独立地变化。
(3)需要跨越多个平台或者多个系统。
(4)需要实现松耦合的设计。
(5)需要支持扩展性和可维护性。
在Python中,桥接模式可以应用于很多地方,例如图形用户界面编程、网络编程、数据库编程等。
例如,在图形用户界面编程中,我们可以使用桥接模式来解耦控件和控件容器的关系。
控件容器可以是一个窗口、一个面板或者一个对话框,而控件可以是一个按钮、一个文本框或者一个列表框。
通过使用桥梁对象,我们可以将控件和控件容器有效地解耦,从而实现松耦合的设计。
3.一个桥接模式的示例——文本框和窗口的组合下面,我们通过一个简单的示例来介绍Python中桥接模式的应用。
这个示例演示了如何通过桥接模式将文本框和窗口的关系进行解耦。
首先,我们定义一个抽象类Component,它包含了一个抽象方法draw。
然后,我们定义两个具体的实现类:TextField和Window,它们分别实现了Component中的draw方法。
Bridge模式在游戏中的应用

Bridge模式在游戏中的应用Bridge模式(桥接模式)是一种设计模式,它将抽象和实现分离开来,从而使它们能够独立地变化。
Bridge模式适用于需要运行时动态变换的场景,能够增强系统的灵活性和可扩展性。
在游戏开发中,使用Bridge模式可以有效地管理游戏中的对象和场景,提高游戏的交互性和可玩性。
游戏是一个非常复杂的系统,它包含了很多不同的对象和场景。
在游戏中有很多不同的角色和场景要求进行交互,例如武器和角色、角色和场景等等。
如果在游戏中没有使用Bridge模式,那么开发者就需要写大量的代码来进行这些交互操作,这会造成代码的冗余和可维护性的降低。
使用Bridge模式的好处就是将这些交互操作抽象出来,使得它们能够独立地变换。
这种抽象可以使得游戏代码更加灵活,能够适应不同的场景和角色。
以下是几个例子,说明Bridge模式在游戏中的应用。
1. 游戏中的武器游戏中有很多不同类型的武器,这些武器具有不同的使用方法和攻击效果。
如果没有使用Bridge模式,那么开发者需要为每种武器都写一段代码来进行攻击和使用操作。
这显然会使得代码变得冗余和难以维护。
使用Bridge模式的好处就是将武器的使用方法和攻击效果抽象出来,使得它们能够独立地变换。
例如可以定义一个抽象类Weapon,它包含了一些抽象方法,例如attack()和use(),这些方法可以被不同的武器实现为具体的攻击和使用方法。
然后,针对不同的武器,可以分别实现一个具体的子类,例如Knife,Sword 等等。
这样,当需要增加一种新的武器时,只需要实现一个新的子类,而不需要修改原有的代码。
2. 游戏中的角色游戏中的角色具有不同的属性和特点,例如不同的攻击力、防御力、速度等等。
如果没有使用Bridge模式,那么开发者需要为每个角色都写一段代码来描述它的属性和特点。
这显然会使得代码变得冗余和难以维护。
使用Bridge模式的好处就是将角色的属性和特点抽象出来,使得它们能够独立地变换。
桥接模式(Bridge)

桥接模式(Bridge)1 场景问题1.1 发送提示消息考虑这样一个实际的业务功能:发送提示消息。
基本上所有带业务流程处理的系统都会有这样的功能,比如某人有新的工作了,需要发送一条消息提示他。
从业务上看,消息又分成普通消息、加急消息和特急消息多种,不同的消息类型,业务功能处理是不一样的,比如加急消息是在消息上添加加急,而特急消息除了添加特急外,还会做一条催促的记录,多久不完成会继续催促。
从发送消息的手段上看,又有系统内短消息、手机短消息、邮件等等。
现在要实现这样的发送提示消息的功能,该如何实现呢?1.2 不用模式的解决方案1:实现简化版本先考虑实现一个简单点的版本,比如:消息先只是实现发送普通消息,发送的方式呢,先实现系统内短消息和邮件。
其它的功能,等这个版本完成过后,再继续添加,这样先把问题简单化,实现起来会容易一点。
(1)由于发送普通消息会有两种不同的实现方式,为了让外部能统一操作,因此,把消息设计成接口,然后由两个不同的实现类,分别实现系统内短消息方式和邮件发送消息的方式。
此时系统结构如图1所示:图1 简化版本的系统结构示意图下面看看大致的实现示意。
(2)先来看看消息的统一接口,示例代码如下:Java代码1./**2. * 消息的统一接口3. */4.public interface Message {5. /**6. * 发送消息7. * @param message 要发送的消息内容8. * @param toUser 消息发送的目的人员9. */10. public void send(String message,String toUser);11.}(3)再来分别看看两种实现方式,这里只是为了示意,并不会真的去发送Email 和站内短消息,先看站内短消息的方式,示例代码如下:Java代码1./**2. * 以站内短消息的方式发送普通消息3. */4.public class CommonMessageSMS implements Message{5. public void send(String message, String toUser) {6. System.out.println("使用站内短消息的方式,发送消息'"7.+message+"'给"+toUser);8. }9.}同样的,实现以Email的方式发送普通消息,示例代码如下:Java代码1./**2. * 以Email的方式发送普通消息3. */4.public class CommonMessageEmail implements Message{5. public void send(String message, String toUser) {6. System.out.println("使用Email的方式,发送消息'"7.+message+"'给"+toUser);8. }9.}2:实现发送加急消息上面的实现,看起来很简单,对不对。
09计算机软件开发教材之第九章 桥接模式

– 所谓耦合,就是两个实体的行为的某种强关联。而将它们的强关联去 掉,就是耦合的解脱,或称脱耦/解耦。在这里,脱耦是指将抽象和实
现之间的耦合解脱开,或者说是将它们之间的强关联改换成弱关联。
– 将两个角色之间的继承关系改为组合关系,就是将它们之间的强关联 改换成为弱关联。因此,桥接模式中的所谓脱耦,就是指在一个软件 系统的抽象和实现之间使用组合关系而不是继承关系,从而使两者可 以相对独立地变化。这就是桥接模式的用意。
– 桥接模式不能只是认为是抽象和实现的分离,它其实并不 仅限于此,更确切的理解: 应该是将一个事物中多个维度 的变化分离。
9.2 桥接模式的结构
9.2 桥接模式的结构(续)
• 抽象(Abstraction)角色:抽象给出的定义,并保存一 个对实现对象的引用。
• 精化的抽象(Refined Abstraction)角色:扩展抽象角色 ,改变和修正父类对抽象的定义。
两个方向变化,而不引入额外的复杂度?
• 示例:TankGameBridge
• Tank的型号,和Tank的平台都继承自各自的抽象类,因此它们 的变化都不会影响到对方。而它们之间的关联,我们使用组合
的方式,把平台类放到Tank类中作为属性。这再次体现了组合
优先于继承的思想。
• 桥接模式把平台的变化引出了基类Tank,使得Tank仅负责封装 型号的变化,而TankPlatformImplementation则负责封装平台的 变化。应用程序在环境交互中使用的都是抽象类,并且把平台 实现隐藏。
• Bridge模式有时候类似于多继承方案,但是多继承方 案往往违背单一职责原则(即一个类只有一个变化的
原因),复用性比较差。Bridge模式是比多继承方案 更好的解决方法。
软件设计模式之桥接模式

软件设计模式之桥接模式桥接模式是一种结构性设计模式,用于将抽象与实现分离,使它们可以独立地变化。
该模式将抽象与实现通过一个桥接接口进行连接,实现了抽象和实现的解耦。
桥接模式主要解决了类之间的耦合性,将抽象与其实现分离开来,从而使得它们可以独立地进行变化。
具体而言,桥接模式将一个类的抽象部分与它的实现部分分离,使它们可以独立地进行变化,从而达到一个过程中改变抽象类和实现类的目的。
桥接模式包含以下几个关键角色:- 抽象类(Abstraction):定义了抽象类的接口,维护了一个指向实现类接口的引用。
- 扩展抽象类(Refined Abstraction):通过扩展抽象类来更加精细地定义抽象类的接口。
- 实现类接口(Implementor):定义了实现类的接口。
- 具体实现类(Concrete Implementor):实现了实现类接口并具体实现它。
下面以一个图形绘制的例子来说明桥接模式的使用。
假设有一个需要绘制图形的应用程序,该程序需要支持绘制不同形状的图形(如圆形、矩形等),且需要支持不同颜色的填充(如红色、蓝色等)。
使用桥接模式可以将图形的形状和颜色的填充进行解耦,使得它们可以独立地进行变化。
首先,定义一个抽象类Shape来表示图形,其中包含一个实现类接口Color作为成员变量来表示颜色的填充。
抽象类Shape定义了一个绘制方法draw,并在其中调用了Color接口的fillColor方法。
具体代码如下:```javapublic abstract class Shapeprotected Color color;public Shape(Color color)this.color = color;}public abstract void draw(;```然后,定义两个扩展抽象类Circle和Rectangle,分别代表圆形和矩形。
它们都继承自抽象类Shape,并实现了抽象方法draw,具体代码如下:```javapublic class Circle extends Shapepublic Circle(Color color)super(color);}public void draSystem.out.print("Circle ");color.fillColor(;}public class Rectangle extends Shapepublic Rectangle(Color color)super(color);}public void draSystem.out.print("Rectangle ");color.fillColor(;}```Color接口定义了一个fillColor方法,具体代码如下:```javapublic interface Colorvoid fillColor(;```最后,定义两个具体实现类RedColor和BlueColor,它们分别代表红色和蓝色的填充。
软件体系结构- 桥接模式

// "RefinedAbstraction" class RefinedAbstraction : Abstraction { // Methods override public void Operation() { implementor.Operation(); } } // "Implementor" abstract class Implementor { // Methods abstract public voiindow抽 象类和它的两个子类XWindow与 PMWindow,由它们分别实现不同系统 平台上的Window界面。 但是继承机制有两个不足之处:
1) 扩展Window抽象使之适用于不同种类的 窗口或新的系统平台很不方便。 2) 继承机制使得客户代码与平台相关。
客户在创建窗口时应该不涉及到其具体实现部分。 仅仅是窗口的实现部分依赖于应用运行的平台。 这样客户代码在创建窗口时就不应涉及到特定的 平台。 Bridge模式解决以上问题的方法是,将Window 抽象和它的实现部分分别放在独立的类层次结构 中。其中
— 定义实现类的接口,该接口不一定要与A b s t r a c t i o n的接口完 全一致;事实上这两个接口可以完全不同。一般来讲, I m p l e m e n t o r接口仅提供基本操作,而Abstraction则定义了基于这些基本操作 的较高层次的操作。
ConcreteImplementor (XwindowImp, PMWindowImp )
// "Abstraction" class Abstraction { // Fields protected Implementor implementor; // Properties public Implementor Implementor { set{ implementor = value; } } // Methods virtual public void Operation() { implementor.Operation(); } }
软件设计模式中的桥接模式与装饰器模式比较

软件设计模式中的桥接模式与装饰器模式比较桥接模式和装饰器模式是软件设计中常用的两种设计模式,它们都属于结构型模式,但在使用和实现上有一些不同之处。
本文将对这两种模式进行比较。
首先,桥接模式和装饰器模式的目的不同。
桥接模式的目的是将抽象部分与它的具体实现部分分离,使它们可以独立变化,而装饰器模式则是在不改变原对象的基础上,动态地给该对象添加一些额外的职责。
其次,在桥接模式中,抽象部分与实现部分可以独立地变化。
通过桥接模式,我们可以在不修改原有代码的情况下,对抽象部分和实现部分进行扩展。
而在装饰器模式中,装饰器可以动态地对对象进行功能的扩展和修改,但是它们的调用顺序是固定的,且装饰器与被装饰者之间存在一种固定的关系。
此外,在桥接模式中,抽象部分和实现部分是通过一个桥接接口来进行关联的。
这个桥接接口定义了抽象部分和实现部分的关联方法。
而在装饰器模式中,装饰器与被装饰者之间的关联是通过继承和组合来实现的。
在实现上,桥接模式通常使用接口和抽象类来定义抽象部分和实现部分,并通过组合来将两者关联起来。
而装饰器模式则是通过继承来实现对被装饰者的功能扩展。
在使用上,桥接模式适用于系统中存在多个变化维度的场景,通过桥接模式可以在每个变化维度上进行扩展和变化,提高系统的灵活性。
而装饰器模式适用于需要给对象动态地添加或修改功能的场景,通过装饰器可以避免使用继承带来的静态特性,使得系统更加灵活和可扩展。
综上所述,桥接模式和装饰器模式在使用和实现上有一些不同之处。
桥接模式主要用于抽象部分和实现部分的分离,而装饰器模式主要用于对对象功能的扩展和修改。
在实际开发中,我们可以根据具体的需求选择合适的模式来解决问题。
桥接模式(Bridge、Implementor)(具体不同平台日志记录,抽象与实现分离)

桥接模式(Bridge、Implementor)(具体不同平台⽇志记录,抽象与实现分离)桥接模式(Bridge Pattern):将抽象部分与它的实现部分分离,使它们都可以独⽴地变化。
它是⼀种对象结构型模式,⼜称为柄体(Handle and Body)模式或接⼝(Interface)模式。
假如我们需要建⽴⼀个⽇志记录器,可以实现数据库记录和⽂本记录。
根据我们的经验我们应该将⽇志记录抽象化,在分别⽤数据库记录和⽂本记录来实现具体的功能。
后来我们需要将他分别应⽤到net平台和java平台,考虑到不同平台的记录不同我们分别将数据库记录细化为net平台上的数据库机记录和java平台上的数据库记录。
以及不同的⽂本记录。
在后来我们打算添加xml平台以及更多的平台进去。
现在发现我们的设计变得庞⼤脆弱,即便平台不同但总有相似之处,这其中的冗余代码会有很多。
假如我们不⽌沿着平台这⼀⽅向扩展呢。
因此我们需要使⽤桥接模式进⾏更加合理的设计。
桥接模式将抽象部分与他的实现部分分离,使他们都可以独⽴的变化。
抽象化:多个实体中共同的概念性联系。
如:⽇志记录实现化:抽象化的具体实现。
如:在Net平台上进⾏数据库⽇志记录。
我们可以进⾏如下设计:桥接类:抽象⽇志1public abstract class log {2private ImpLog impLog;34public log(ImpLog impLog) {5super();6this.impLog = impLog;7 }89abstract public void write(String log);1011public ImpLog getImpLog() {12return impLog;13 }1415public void setImpLog(ImpLog impLog) {16this.impLog = impLog;17 }18 }实现化⾓⾊:抽象平台1public abstract class ImpLog {23abstract public void execute(String msg);45 }具体实现化⾓⾊:java平台1public class JImpLog extends ImpLog{23 @Override4public void execute(String msg) {5 System.out.println("在java平台上," + msg);6 }78 }net平台1public class NImpLog extends ImpLog{23 @Override4public void execute(String msg) {5 System.out.println("在Net平台上,"+msg);67 }89 }桥接具体类:数据库⽇志:public class DataBaseLog extends log{public DataBaseLog(ImpLog impLog) {super(impLog);}@Overridepublic void write(String log) {getImpLog().execute("数据库⽇志:" + log);}}⽂本⽂件⽇志1public class TextFileLog extends log{23public TextFileLog(ImpLog impLog) {4super(impLog);5 }67 @Override8public void write(String log) {9 getImpLog().execute(log);10 }1112 }客户测试类:1public class BridgePattern {23public static void main(String[] args) {4 ImpLog j= new JImpLog();//建⽴java平台5 log jl = new DataBaseLog(j);//建⽴基于java 的数据库⽇志写⼊6 jl.write(" I am fine!"); //写⼊⽇志⽂件789 }1011 }。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
public class Client { public static void Main( string[] args ) { Abstraction abstraction = new RefinedAbstraction(); // Set implementation and call abstraction.Implementor = new ConcreteImplementorA(); abstraction.Operation(); // Change implemention and call abstraction.Implementor = new ConcreteImplementorB(); abstraction.Operation(); } }
你想对客户完全隐藏抽象的实现部分。 正如在意图一节的第一个类图中所示的那样, 有许多类要生成。这样一种类层次结构说明 你必须将一个对象分解成两个部分。 Rumbaugh称这种类层次结构为“嵌套的普 化”(nested generalizations)。 你想在多个对象间共享实现(可能使用引用 计数),但同时要求客户并不知道这一点。 一个简单的例子便是Coplien的String类,在 这个类中多个对象可以共享同一个字符串表 示(String Rep)。
4. 适用性
不希望在抽象和它的实现部分之间有一个固定 的绑定关系。
例如这种情况可能是因为,在程序运行时刻实现部 分应可以被选择或者切换。
类的抽象以及它的实现都应该可以通过生成子 类的方法加以扩充。这时Bridge模式使你可以 对不同的抽象接口和实现部分进行组合,并分 别对它们进行扩充。 对一个抽象的实现部分的修改应对客户不产生 影响,即客户的代码不必重新编译。
— 定义实现类的接口,该接口不一定要与A b s t r a c t i o n的接口完 全一致;事实上这两个接口可以完全不同。一般来讲, I m p l e m e n t o r接口仅提供基本操作,而Abstraction则定义了基于这些基本操作 的较高层次的操作。
ConcreteImplementor (XwindowImp, PMWindowImp )
一个类层次结构针对窗口接口( Window、IconWin dow、TransientWindow) 另外一个独立的类层次结构针对平台相关的窗口实现 部分,这个类层次结构的根类为WindowImp。
对Window子类的所有操作都是用 WindowImp接口中的抽象操作实现的。 这就将窗口的抽象与系统平台相关的实 现部分分离开来。因此,我们将Window 与WindowImp之间的关系称之为桥接, 因为它在抽象类与它的实现之间起到了 桥梁作用,使它们可以独立地变化。
// "Abstraction" class Abstraction { // Fields protected Implementor implementor; // Properties public Implementor Implementor { set{ implementor = value; } } // Methods virtual public void Operation() { implementor.Operation(); } }
// "ConcreteImplementorA" class ConcreteImplementorA : Implementor { // Methods override public void Operation() { Console.WriteLine("ConcreteImplementorA Operation"); } } // "ConcreteImplementorB" class ConcreteImplementorB : Implementor { // Methods override public void Operation() { Console.WriteLine("ConcreteImplementorB Operation"); } }
— 实现Implementor接口并定义它的具体实现。
7. 协作
• Abstraction将client的请求转发给它的 Implementor对象。
8. 效果
1) 分离接口及其实现部分 2) 提高可扩充性 3 ) 实现细节对客户透明
9. 实现
1) 仅有一个Implementor 2) 创建正确的Implementor对象 3 ) 共享Implementor对象 4) 采用多重继承机制
5. 结构
6. 参与者
Abstraction (Window )
— 定义抽象类的接口。 — 维护一个指向Implementor类型对象的指针。
RefinedAbstraction (IconWindow )
— 扩充由Abstraction定义的接口。
Implementor (WindowImp )
// "RefinedAbstraction" class RefinedAbstraction : Abstraction { // Methods override public void Operation() { implementor.Operation(); } } // "Implementor" abstract class Implementor { // Methods abstract public void Operation(); }
BRIDGE(桥接)
1. 意图
将抽象部分与它的实现部分分离,使它们都 可以独dy
3. 动机
当一个抽象可能有多个实现时,通常用继承 来协调它们。抽象类定义对该抽象的接口, 而具体的子类则用不同方式加以实现。但是 此方法有时不够灵活。 继承机制将抽象部分与它的实现部分固定在 一起,使得难以对抽象部分和实现部分独立 地进行修改、扩充和重用。
运用继承机制,我们可以定义Window抽 象类和它的两个子类XWindow与 PMWindow,由它们分别实现不同系统 平台上的Window界面。 但是继承机制有两个不足之处:
1) 扩展Window抽象使之适用于不同种类的 窗口或新的系统平台很不方便。 2) 继承机制使得客户代码与平台相关。
客户在创建窗口时应该不涉及到其具体实现部分。 仅仅是窗口的实现部分依赖于应用运行的平台。 这样客户代码在创建窗口时就不应涉及到特定的 平台。 Bridge模式解决以上问题的方法是,将Window 抽象和它的实现部分分别放在独立的类层次结构 中。其中