结构型---桥接模式(Bridge Pattern)
定义
桥接模式即将抽象部分与实现部分脱耦,使它们可以独立变化。桥接模式的目的就是使两者分离,根据面向对象的封装变化的原则,我们可以把实现部分的变化封装到另外一个类中,这样的一个思路也就是桥接模式的实现。
- Abstraction----抽象化角色
- Implementor----实现化角色
- RefindedAbstraction----修正抽象化角色
- ConereteImplementor----具体实现化角色
桥接模式实现
桥接模式的代码:
namespace ConsoleApplication1
{
/// <summary>
/// 实现化角色(待实现的接口)
/// </summary>
public interface Implementor
{
//基本方法
void doSomething();
void doAnything();
}
/// <summary>
/// 具体实现化角色
/// </summary>
public class ConcreteImplementor1 : Implementor
{
public void doSomething()
{
//业务逻辑处理
}
public void doAnything()
{
//业务逻辑处理
}
}
/// <summary>
/// 具体实现化角色
/// </summary>
public class ConcreteImplementor2 : Implementor
{
public void doSomething()
{
//业务逻辑处理
}
public void doAnything()
{
//业务逻辑处理
}
}
/// <summary>
/// 抽象化角色(调用者抽象)
/// </summary>
public abstract class Abstraction
{
//定义对实现化角色的引用
private Implementor imp;
//获得实现化角色
public Implementor Imp
{
get { return imp; }
}
//约束为子类必须实现该构造函数
public Abstraction(Implementor _imp)
{
this.imp = _imp;
}
//自身的行为和属性
public virtual void request()
{
this.imp.doSomething();
}
}
/// <summary>
/// 具体抽象化角色
/// </summary>
public class RefindAbstraction : Abstraction
{
public RefindAbstraction(Implementor _imp)
: base(_imp)
{
}
//重载父类的方法
public override void request()
{
//业务处理
base.request();
base.Imp.doAnything();
}
}
class Program
{
static void Main(string[] args)
{
//定义一个实现化角色
Implementor imp = new ConcreteImplementor1();
//定义一个抽象化角色
Abstraction abs = new RefindAbstraction(imp);
//执行行文
abs.request();
Console.ReadLine();
}
}
}
桥接模式的优缺点
介绍完桥接模式,让我们看看桥接模式具体哪些优缺点。
优点:
把抽象接口与其实现解耦。
抽象和实现可以独立扩展,不会影响到对方。
实现细节对客户透明,对用于隐藏了具体实现细节。
缺点: 增加了系统的复杂度
使用场景
我们再来看看桥接模式的使用场景,在以下情况下应当使用桥接模式:
- 如果一个系统需要在构件的抽象化角色和具体化角色之间添加更多的灵活性,避免在两个层次之间建立静态的联系。
- 设计要求实现化角色的任何改变不应当影响客户端,或者实现化角色的改变对客户端是完全透明的。
- 需要跨越多个平台的图形和窗口系统上。
- 一个类存在两个独立变化的维度,且两个维度都需要进行扩展。
一个实际应用桥接模式的例子
桥接模式也经常用于具体的系统开发中,对于三层架构中就应用了桥接模式,三层架构中的业务逻辑层BLL中通过桥接模式与数据操作层解耦(DAL),其实现方式就是在BLL层中引用了DAL层中一个引用。这样数据操作的实现可以在不改变客户端代码的情况下动态进行更换,下面看一个简单的示例代码:
namespace TempApplication
{
// 客户端调用
// 类似Web应用程序
class Client
{
static void Main(string[] args)
{
BusinessObject customers = new CustomersBusinessObject("ShangHai");
customers.Dataacces = new CustomersDataAccess();
customers.Add("小六");
Console.WriteLine("增加了一位成员的结果:");
customers.ShowAll();
customers.Delete("王五");
Console.WriteLine("删除了一位成员的结果:");
customers.ShowAll();
Console.WriteLine("更新了一位成员的结果:");
customers.Update("Learning_Hard");
customers.ShowAll();
Console.Read();
}
}
// BLL 层
public abstract class BusinessObject
{
// 字段
private DataAccess dataacess;
private string city;
public BusinessObject(string city)
{
this.city = city;
}
// 属性
public DataAccess Dataacces
{
get { return dataacess; }
set { dataacess = value; }
}
// 方法
public virtual void Add(string name)
{
Dataacces.AddRecord(name);
}
public virtual void Delete(string name)
{
Dataacces.DeleteRecord(name);
}
public virtual void Update(string name)
{
Dataacces.UpdateRecord(name);
}
public virtual string Get(int index)
{
return Dataacces.GetRecord(index);
}
public virtual void ShowAll()
{
Console.WriteLine();
Console.WriteLine("{0}的顾客有:", city);
Dataacces.ShowAllRecords();
}
}
public class CustomersBusinessObject : BusinessObject
{
public CustomersBusinessObject(string city)
: base(city) { }
// 重写方法
public override void ShowAll()
{
Console.WriteLine("------------------------");
base.ShowAll();
Console.WriteLine("------------------------");
}
}
///<summary>
/// 相当于三层架构中数据访问层(DAL)
///</summary>
public abstract class DataAccess
{
// 对记录的增删改查操作
public abstract void AddRecord(string name);
public abstract void DeleteRecord(string name);
public abstract void UpdateRecord(string name);
public abstract string GetRecord(int index);
public abstract void ShowAllRecords();
}
public class CustomersDataAccess:DataAccess
{
// 字段
private List<string> customers =new List<string>();
public CustomersDataAccess()
{
// 实际业务中从数据库中读取数据再填充列表
customers.Add("Learning Hard");
customers.Add("张三");
customers.Add("李四");
customers.Add("王五");
}
// 重写方法
public override void AddRecord(string name)
{
customers.Add(name);
}
public override void DeleteRecord(string name)
{
customers.Remove(name);
}
public override void UpdateRecord(string updatename)
{
customers[] = updatename;
}
public override string GetRecord(int index)
{
return customers[index];
}
public override void ShowAllRecords()
{
foreach (string name in customers)
{
Console.WriteLine("" + name);
}
}
}
}
结构型---桥接模式(Bridge Pattern)的更多相关文章
- 【设计模式】桥接模式 Bridge Pattern
开篇还是引用吕振宇老师的那篇经典的文章<设计模式随笔-蜡笔与毛笔的故事>.这个真是太经典了,没有比这个例子能更好的阐明桥接模式了,这里我就直接盗来用了. 现在市面上卖的蜡笔很多,各种型号, ...
- python 设计模式之桥接模式 Bridge Pattern
#写在前面 前面写了那么设计模式了,有没有觉得有些模式之间很类似,甚至感觉作用重叠了,模式并不是完全隔离和独立的,有的模式内部其实用到了其他模式的技术,但是又有自己的创新点,如果一味地认为每个模式都是 ...
- 桥接模式(Bridge Pattern)
1,定义 桥接模式(Bridge Pattern),也称为桥梁模式,其用意是将抽象化与实现化脱耦,使得两者可以独立的变化,它可以使软件系统沿着多个方向进行变化,而又不引入额外的复杂 ...
- 乐在其中设计模式(C#) - 桥接模式(Bridge Pattern)
原文:乐在其中设计模式(C#) - 桥接模式(Bridge Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 桥接模式(Bridge Pattern) 作者:webabcd 介绍 ...
- 二十四种设计模式:桥接模式(Bridge Pattern)
桥接模式(Bridge Pattern) 介绍将抽象部分与它的实现部分分离,使它们都可以独立地变化. 示例有一个Message实体类,对它的操作有Insert()和Get()方法,现在使这些操作的抽象 ...
- 结构型—桥接(Bridge)模式
1.意图: 将抽象部分(抽象接口)与它的实现部分(代码实现)分离,使它们都可以独立地变化. 理解:抽象部分是对外展现的接口(api),而实现部分是针对抽象接口提供的不同版本的功能实现,使两者独立变化指 ...
- Net设计模式实例之桥接模式( Bridge Pattern)
一.桥接模式简介(Brief Introduction) 桥接模式(Bridge Pattern),将抽象部分与它的实现部分分离,使的抽象和实现都可以独立地变化. Decouple an abstra ...
- 转:设计模式-----桥接模式(Bridge Pattern)
转自:http://www.cnblogs.com/houleixx/archive/2008/02/23/1078877.html 记得看原始链接的评论. 学习设计模式也有一段时间了,今天就把我整理 ...
- 七个结构模式之桥接模式(Bridge Pattern)
问题: 当存在多个独立的变化维度时,如果仍采用多层继承结构,会急剧的增加类的个数,因此可以考虑将各个维度分类,使他们不相互影响. 定义: 将抽象部分与它的实现部分进行分离,抽象部分只保留最为本质的部分 ...
随机推荐
- python猜数字游戏console版本
加入python学习小组后的第一次作业,python GUI写猜数字游戏.由于加班比较多,第一步先实现console版本,下一步再实现GUI版本. 虽然猜数字游戏是个小游戏,但是涉及到的基础知识点还是 ...
- springboot 不同环境切换不同的配置文件
开发的流程是本地>测试>预发布>正式,所以不同的环境,肯定是不同的配置文件,所以我们需要针对不同的环境做不同的配置切换. 下面我们来说说 springboot 是怎么来切换的: 1. ...
- 分析Ajax抓取今日头条街拍美图
spider.py # -*- coding:utf-8 -*- from urllib import urlencode import requests from requests.exceptio ...
- iOS 数据归档----温故而知新
#import "StudyViewController.h" #import "person.h" @interface StudyViewControlle ...
- 瞎搞poj1013
http://poj.org/problem?id=1013 题意:给你标记从A到L的石子,其中有一个石子,可能会轻于其它石子,也可能重于其它石子.你只能通过三次天平的测量去找到这个石子.天平的三个状 ...
- python之常用模块4
pyinotify模块 pip3 install pyinotify pyinotify提供的事件: 事件标志 事件含义 IN_ACCESS 被监控项目或者被监控目录中的文件被访问,比如一个文件被读取 ...
- MySQL--MHA原理
##==============================================================##MHA(Master High Availability)是一种My ...
- MySQL优化技巧
目录 MySQL的特点 数据类型优化 整型类型 小数类型 字符串类型 时间类型 主键类型的选择 特殊类型的数据 索引优化 一个使用Hash值创建索引的技巧 前缀索引 多列索引 聚簇索引 覆盖索引 重复 ...
- Redis安装和实际应用
上次介绍了Redis的来龙去脉以及相关一些情况,点击回顾<深入浅出Redis>,接下来我们再讲讲Redis的安装和实际应用. 一.Redis的安装 下载安装包,redis-3.2.9.ta ...
- Java初学者容易犯的代码错误
1. 不会判断空 空指针异常是所有Java初学者接触最多的异常,没有之一.原因是,你们拿到一个对象后容易不假思索的直接使用(直接给这个对象的属性赋值,直接调用这个对象的方法等),不报异常才怪呢!下面是 ...