适配器模式/外观模式--Head First设计模式【笔记】
适配器模式:将一个类的接口,转换成客户期望的另一个接口。适配器让原本接口不兼容的类可以合作无间。
地球村动物园中有鸭和鸡这两种动物:
/// <summary> /// 鸭子类的接口 /// /// 是鸭子都要实现这个接口 /// 能叫能跳 /// </summary> interface IDuck { void Quack(); void Fly(); }
/// <summary> /// 鸭子的实例类 绿头鸭 /// /// /// </summary> class MallardDuck:IDuck { public void Quack() { Console.WriteLine("鸭子 嘎嘎叫"); } public void Fly() { Console.WriteLine("鸭子 慢慢的跳舞"); } }
/// <summary> /// 鸡的接口 /// /// 是鸡都要实现这个接口 /// 能叫能跳 /// </summary> interface ITurkey { void Gobble(); void Fly(); }
/// <summary> /// 鸡的实例 /// /// 鸡的实例 火鸡 /// </summary> class WildTurkey:ITurkey { public void Gobble() { Console.WriteLine("火鸡 唧唧叫"); } public void Fly() { Console.WriteLine("火鸡 摇摆的跳舞"); } }
现在地球村要举办合唱比赛,合唱队伍有成员数要求,要达到N位。可是鸭子合唱队只有(N-1)位成员,绿头鸭提议让来火鸡替补最后一位成员。
怎么可能!!!!!虽然鸡也能叫能跳,但是鸡就是鸡,你当评委都是瞎子啊???
那我们试试给火鸡画个妆,打扮的像鸭子试试!!!!我们需要化妆师:适配器模式
/// <summary> /// 适配器 /// /// </summary> class TurkeyAdapter:IDuck //要装扮成鸭子,那么要具有鸭子的种族特征,所以继承IDuck { //要鸡来装扮,那么就要传一只鸡进来。 ITurkey turkey; public TurkeyAdapter(ITurkey turkey) { this.turkey = turkey; } public void Quack()//用鸡叫装扮成鸭叫 { turkey.Gobble(); } public void Fly()//用鸡跳装扮成鸭跳 { turkey.Fly(); } }
装扮好了,关键时刻,团队成员审核(验明正身)
static void Main(string[] args) { WildTurkey wildTurkey = new WildTurkey();//火鸡 IDuck turkeyAdapter = new TurkeyAdapter(wildTurkey );//适配器 DuckSing(turkeyAdapter );//鸭子合唱成员审核 Console.ReadKey(); } static void DuckSing(IDuck duck)//鸭子成员审核,是鸭子都要实现IDuck { duck.Quack(); duck.Fly(); }
运行:
审核通过 ,YE!!!!
接下来我们做什么?合唱,那当然要先排练了。
///伪代码 class Rehearse
{
turkeyAdapter.Quack();
mallardDuck.Quack();
aADuck.Quack();
bBDuck.Quack();
cCDuck.Quack();
dDDuck.Quack();
turkeyAdapter.Fly();
mallardDuck.Fly();
aADuck.Fly();
bBDuck.Fly();
cCDuck.Fly();
dDDuck.Fly();
}
这样写有什么坏处呢?
这样写违反了设计原则:
1.为了交互对象之间的松耦合设计而努力。
2.最少知识原则:只和你的密友谈话。
当你正在设计一个系统,不管是任何对象,你要要注意它所交互的类有哪些,并注意它和这些类是如何交互的。
我们希望不要让太多的类耦合在一起,免得修改系统中一部分,会影响到其他部分。
在这里我们该怎么办?
我们可以使用外观模式:提供了一个统一的接口,用来访问子系统中的一群接口。外观定义了一个高层接口,让子系统更容易使用。
//伪码 class Rehearse { TurkeyAdapter turkeyAdapter; MallardDuck mallardDuck; AADuck aADuck; BBDuck bBDuck; CCDuck cCDuck; DDDuck dDDuck; public Rehearse (TurkeyAdapter turkeyAdapter,MallardDuck mallardDuck,AADuck aADuck,BBDuck bBDuck,CCDuck cCDuck,DDDuck dDDuck) { this.turkeyAdapter =turkeyAdapter; this.mallardDuck =mallardDuck; this.aADuck =aADuck; this.bBDuck =bBDuck; this.cCDuck =cCDuck; this.dDDuck =dDDuck; } public void Sing()//想听唱歌只要调用这个统一的接口(Sing方法),实现了松耦合。 { turkeyAdapter.Quack(); mallardDuck.Quack(); aADuck.Quack(); bBDuck.Quack(); cCDuck.Quack(); dDDuck.Quack(); } public void Dance()//想听跳舞只要调用这个统一的接口(Dance方法),实现了松耦合。 { turkeyAdapter.Fly(); mallardDuck.Fly(); aADuck.Fly(); bBDuck.Fly(); cCDuck.Fly(); dDDuck.Fly(); } }
//伪码 运行 Rehearse rehearse = new Rehearse( turkeyAdapter, mallardDuck, aADuck, bBDuck,cCDuck,dDDuck); rehearse.Sing(); rehearse.Dance();