设计模式之适配器模式和外观模式


海底月是天上月,
眼前人是心上人。


适配器模式

    适配器模式应该到现在我看过的设计模式之中最容易理解、最简单的一个模式,不过它的能量却很大。简单来说,适配器模式就相当于我们“手机充电头”一样的东西,在插座和手机数据线USB接口之前做一个接口类型的转换。这样理解起来是不是很简单呢?
    适配器模式就是这样一个东西:将一个类的接口转换成客户期望的另一个接口。适配器可以让原本并不兼容的两个类可以合作。

1、简单来说适配器模式的实现过程是这样的:

(1)首先,定义一个适配器OO 实现用户所期望看到的接口A;
(2)然后,取得要适配的对象引用;即在这个适配器中定义一个适配对象接口的实例B;
(3)最后,实现接口A中的所有方法,使用实例B。
很明显,这里有三个对象:适配器OO(电源头)、被适配者A(插座)、客户B(USB接口)。
举个栗子:让火鸡来冒充鸭子的飞和叫的方式,代码如下:

//被适配者接口
public interface Duck {
    public void quack();
    public void fly();
}
//一个实现类
public class MallardDuck implents Duck {
    public void quack(){
        system.out.println("Quack")
    }
    public void fly(){
        system.out.println("fly")
    }
}
//现在有一个火鸡想模仿这个鸭子的行为,不想让人们发现,下面就是这只异想天开的火鸡
public interface Turkey{
    //火鸡叫的方式和鸭子不一样
    public void gobble();
    public void fly();
}
public class WildTurkey implents Turkey {
    public void gobble(){
        system.out.println("Gobble gobble")
    }
    public void fly(){
        system.out.println("fly")
    }
}

//下面就让这个适配器来帮助这只异想天开的火鸡实现它的 梦想
public class TurkeyAdapter implents Duck{
    Turkey turkey;

    public TurkeyAdapter(Turkey turkey){
        this.turkey = turkey;
    }

    public void quack(){
        turkey.gobble();
    }
    public void fly(){
        turkey.fly();
    }
}

public class TestAdapter{
    public static void main(String[] args){
        WildTurkey turkey = new WildTurkey();
        Duck testDuck = new TurkeyAdapter(turkey);
        testDuck.quack();
        testDuck.fly();
    }
    static void testDuck(Duck duck){
        duck.quack();
        duck.fly();
    }
}

这里的duck.quack();duck.fly();执行的时候,testDuck并不知道这里是不是真正的鸭子。

2.扩展知识

适配器有两种:类适配器和对象适配器。
(1)类适配器:就要进行多重继承,这在java中是不可能实现的;
(2)对象适配器:利用组合的方式,将请求传给被适配者,更具有弹性。


外观模式

    由于适配器模式中被适配者可能不止一个,可能这个适配器中要包含多个被适配者,这就引出了“外观模式”的概念。外观模式和多被适配者的模式很相似,但是不一样。多被适配者的适配器模式,让这个接口实现多个被适配者的接口中的方法即可,达到一个接口和其他所有原本不能合作的接口进行合作。而外观模式只是简单对许多接口进行一个高度的整合。
外观模式:主要用于简化接口,提供一个接口同时访问子系统中的多个接口,外观定义了一个高层接口,让子系统更容易使用。
    这个模式也很容易理解,比如说现在开始流行“家电自动化”,就是说回家之后,一键开关,打开窗帘、客厅和浴室的灯、音乐、空调、热水器,方便住户上班一天之后回到家,冲个热水澡,听着轻音乐,吹着空调,在柔和的灯光下,哇。。。(写的我自己都觉得这是别人家生活…),所以如果住户能够到家之后一键打开这些,那简直太棒了!那么这个外观模式就起到这样的作用。
    我们把开空调、窗帘、灯、热水器的这几个操作,都提供一个各自的接口,然后再将这些接口定义在同一个高接口中。这种方式就是“外观模式”。它存在的主要作用就是“简化接口”
这个模式很简单就能理解,所以不附代码。


最少知识原则

不知道为什么在“适配器模式”这一章节会讲到这个原则。。。
最少知识原则呢,大意就是减少对象所依赖的数目,(减少对象的创建以及嵌套调用),比如有这样一个方法:

public String A(){
    B b = a.getName();
    return b.getFirstElement();
}

//使用最少知识原则
public String A(){
    return a.getFirstElement();
}

就是这样子的。。。无奈吗?
因为它缺点有点多:
    虽然这个原则减少了对象之间的依赖,研究也显示这会减少软件的维护成本;但是采用这个原则也会导致更多的“包装”类被制造出来,用以处理和其他组件的沟通。,这可能会导致负责副和开发时间的增加,并降低运行时的性能。
    这里说一下,这个“最少知识原则”还叫做“墨忒耳法则(law of Demeter)”
    不过还是推荐不要使用这个原则了,感觉没多大意义。


章节总结

  1. 当需要使用一个现有的类而其接口并不符合你的需要时,就使用适配器;
  2. 当需要简化并统一一个很大的接口或者一群复杂的接口时,使用外观;
  3. 适配器改变接口一符合客户的期望;
  4. 外观将客户从一个复杂的子系统中解耦;
  5. 实现一个适配器可能需要一番功夫,也可能不费功夫;
  6. 你可以为一个子系统实现一个以上的外观;
  7. 适配器、装饰者、外观:适配器讲一个对象包装起来以改变接口;装饰着讲一个对象包装起来以增加新的行为和责任;而外观将一群对象“包装”起来,以简化接口。

猜你喜欢

转载自blog.csdn.net/amethyst128/article/details/78500458