适配器模式/外观模式--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();

 

 

 

 

 

posted on 2012-09-06 16:34  妖叨叨  阅读(450)  评论(0编辑  收藏  举报

导航