设计模式之桥接模式
一、桥接模式:如果软件系统中某个类存在多个独立变化的维度,我们可以将这多个维度分离出来,使这些维度可以独立扩展,比如一个表示教师的类 ,他原本包含教师资格级别和所教学科这个两个维度,如果我们抽象出一个教师类,然后要实现各个级别、各个学科的教师的话 ,就需要实现教师资格级别数量(M)和教学学科数量(N)的乘积M*N个实现类,而如果我们 将教师资格级别、教学学科从教师类中抽象出来,我们只需要实现这两个抽象的所有实现类(M个教师资格级别实现类、N个教学学科实现类 ),然后在教师类中使用组合模式方式去引用这两类实现类,则只需要M+N个实现类就可以满足需求,客户端需要什么样的实现类由它自己指定,这样既减少了实现类的数量,又增强了程序的灵活性,这种设计模式我们称之为桥接模式。
二、实现思路 :将一个类中多个独立变化的纬度分别抽象出一个抽象类,把具体的变化情况作为其对应抽象的实现类,在类中保留对这些抽象类的引用,由客户端指定其具体的实现类以满足不同的需求。
三、代码举例:

A、多重继承模式下的类代码:
1、抽象教师类:
namespace Bridge.继承模式
{
public abstract class Teacher
{
public abstract string TeachSubject { get; set; }//教学学科
public abstract string SchoolRank { get; set; }//教学学校等级
public abstract void BeginClass();//开始上课
}
}
2、实现类:
namespace Bridge.继承模式
{
/// <summary>
/// 高中语文老师
/// </summary>
public class HighchoolChineseTeacher : Teacher
{
public HighchoolChineseTeacher()
{
this.TeachSubject = "语文";
this.SchoolRank = "高中";
}
public override string TeachSubject { get ; set; }
public override string SchoolRank { get; set; }
public override void BeginClass()
{
Console.WriteLine(this.SchoolRank+ "教师级别的"+ this.TeachSubject + "老师开始上" + this.TeachSubject+"课.....");
}
}
}
namespace Bridge.继承模式
{
/// <summary>
/// 高中英语老师
/// </summary>
public class HighchoolEnglishTeacher : Teacher
{
public HighchoolEnglishTeacher()
{
this.TeachSubject = "英语";
this.SchoolRank = "高中";
}
public override string TeachSubject { get; set; }
public override string SchoolRank { get; set; }
public override void BeginClass()
{
Console.WriteLine(this.SchoolRank + "教师级别的" + this.TeachSubject + "老师开始上" + this.TeachSubject + "课.....");
}
}
}
namespace Bridge.继承模式
{
/// <summary>
/// 初中语文老师
/// </summary>
public class MiddlechoolChineseTeacher : Teacher
{
public MiddlechoolChineseTeacher()
{
this.TeachSubject = "语文";
this.SchoolRank = "初中";
}
public override string TeachSubject { get; set; }
public override string SchoolRank { get; set; }
public override void BeginClass()
{
Console.WriteLine(this.SchoolRank + "教师级别的" + this.TeachSubject + "老师开始上" + this.TeachSubject + "课.....");
}
}
}
namespace Bridge.继承模式
{
/// <summary>
/// 高初中英语老师
/// </summary>
public class MiddlechoolEnglishTeacher : Teacher
{
public MiddlechoolEnglishTeacher()
{
this.TeachSubject = "英语";
this.SchoolRank = "初中";
}
public override string TeachSubject { get; set; }
public override string SchoolRank { get; set; }
public override void BeginClass()
{
Console.WriteLine(this.SchoolRank + "教师级别的" + this.TeachSubject + "老师开始上" + this.TeachSubject + "课.....");
}
}
}
namespace Bridge.继承模式
{
/// <summary>
/// 小学语文老师
/// </summary>
public class PrimaryschoolChineseTeacher : Teacher
{
public PrimaryschoolChineseTeacher()
{
this.TeachSubject = "语文";
this.SchoolRank = "小学";
}
public override string TeachSubject { get; set; }
public override string SchoolRank { get; set; }
public override void BeginClass()
{
Console.WriteLine(this.SchoolRank + "教师级别的" + this.TeachSubject + "老师开始上" + this.TeachSubject + "课.....");
}
}
}
namespace Bridge.继承模式
{
/// <summary>
///小学英语教师
/// </summary>
public class PrimaryschoolEnglishTeacher : Teacher
{
public PrimaryschoolEnglishTeacher()
{
this.TeachSubject = "英语";
this.SchoolRank = "小学";
}
public override string TeachSubject { get; set; }
public override string SchoolRank { get; set; }
public override void BeginClass()
{
Console.WriteLine(this.SchoolRank + "教师级别的" + this.TeachSubject + "老师开始上" + this.TeachSubject + "课.....");
}
}
}
B、 桥接模式下的类代码:
1、学科接口:
namespace Bridge.桥接模式
{
public interface ISubject
{
string Subject();
}
}
2、教学等级接口:
namespace Bridge.桥接模式
{
public interface ISchool
{
String Rank();//学校等级
}
}
3、学科接口实现类:
namespace Bridge.桥接模式
{
public class ChineseSubject : ISubject
{
public string Subject()
{
return "语文";
}
}
}
namespace Bridge.桥接模式
{
public class EnglishSubject : ISubject
{
public string Subject()
{
return "英语";
}
}
}
4、教学等级接口实现类:
namespace Bridge.桥接模式
{
public class Middlechool : ISchool
{
public string Rank()
{
return "中学";
}
}
}
namespace Bridge.桥接模式
{
class Primaryschool:ISchool
{
public string Rank()
{
return "小学";
}
}
}
5、Teacher类:
namespace Bridge.桥接模式
{
public class Teacher
{
public ISchool _school = null;
public ISubject _subject = null;
public void BeginClass()
{
Console.WriteLine(this._school.Rank() + "教师级别的" + this._subject.Subject() + "老师开始上" + this._subject.Subject() + "课.....");
}
}
}
6、客户端调用:
{
//桥接模式与继承模式的对比:
Bridge.继承模式.Teacher teacher0 = new Bridge.继承模式.PrimaryschoolChineseTeacher();
teacher0.BeginClass();
Bridge.继承模式.Teacher teacher1 = new Bridge.继承模式.MiddlechoolEnglishTeacher();
teacher1.BeginClass();
Console.WriteLine("..........以下是桥接模式代码...................");
//如果按照以上的继承方式进行设计,假如现在教师资格固定为小学、初中、高中、大学这几类,客户端分别需要这几个资格的生物老师各一名,那么就需要同时增加4个生物老师实现类。
//如果还需要这几个资格的化学老师各一名,则又需要4个化学老师实现类,以此类推,政理化史地生语数英这9大学学科都分别需要一名老师的话,那么老师实现类的数量为9*4=32名。
//万一客户端还需要研究生导师、博士生导师等教师资格的老师呢?那全部计算下来需要实现类的数量为6*9=54个Teacher实现类,这造成了实现类爆炸性的增加,这下子这程序还怎么往下写?
//有没有办法能够让扩展时减少实现类的数量?答案是使用桥接模式。
Bridge.桥接模式.Teacher techer2 = new Bridge.桥接模式.Teacher();
techer2._school = new Bridge.桥接模式.HighSchool();
techer2._subject = new Bridge.桥接模式.EnglishSubject();
techer2.BeginClass();
Bridge.桥接模式.Teacher techer3 = new Bridge.桥接模式.Teacher();
techer3._school = new Bridge.桥接模式.Middlechool();
techer3._subject = new Bridge.桥接模式.ChineseSubject();
techer3.BeginClass();
//使用桥接模式将抽象和实现分离,使他们可以独立的变化:假如需要加入需要一组数学老师,我们只需要新增一个实现ISubject 接口的数学类,通过上端指定参数,就可以取得各个学校级别的数学老师
//如果按照上面的继承模式,当我们需要新增一组数学老师时,就需要分别创建一个小学、初中、高中、大学的实现类对象。使用桥接模式,假如教师资格固定为小学、初中、高中、大学、研究生导师、博士生导师6类
//学科为政理化史地生语数英这9大学学科,则需要实现类数量为6个ISchool实现类+9个ISubject实现类=15个,比继承模式中54个少了几倍。,
//在以上两种模式中,如果还需要区分老师性别,继承模式中实现类的数量为2*6*9=108个,桥接模式中实现类数量为2+6+9=17个。两种模式相比,桥接模式的优点就出来了。桥接模式也有使用起来比较
//麻烦的缺点:继承模式只需要new一个实现类即可,而桥接模式需要多new几个实现类进行指定,对于客户端而言需要了解更多的细节。
Console.ReadKey();
}
7、运行结果:

四、桥接模式的优缺点及应用:该模式适用于一个类具有多维度变化的情况,易于扩展,使用灵活,但客户端需要了解更多的细节,使用较为麻烦。

浙公网安备 33010602011771号