当前位置:编程学习 > C/C++ >>

外观模式

外观模式<facade>
生活:
所谓的外观,无非是生活中形形色色展现给我们的一个外观,小时候玩过四驱赛车,我那时就特喜欢那种酷酷的车型,至于内部复杂结构,比如马达是怎么运转的,前后轮是怎么联动的,我可以完全不去理会,而我要做的是,在赛车底部有一个开关,我只需要稍微一动,赛车就能毫无差错的跑起来,除非电池没有电了。还有就是较流行的炒股,有些菜鸟级的股民,看到别人能打捞黄金,也想到股海里捞一把,就匆匆的去买了一只股,小挣一把,就起野心了,多买了几只股票,最后发现自己招架不住了,周旋了好久,最后搭进去了,这时有人给他建议,去做基金,说只要将要投资的钱交由专业的经理人尽心管理,然后坐做等收益,这个专业的经理人就是将分散的基金集中起来,一用其专业技能,进行投资,这样对于每一个股民来说,就不需要每天操心那堆股票了...
 
编程世界:
当存在多个细粒度的子应用程序时,如果他们各自分散,互相独立,当我们要用到这些功能时,就不得不去熟悉这些个细粒度的应用程序,这就大大增加了对这些应用程序的依赖性,无形之中增加了耦合性,这是违背我们面向对象设计原则的,要解决这个问题,我们就可以考虑是否可以将这些细粒度的子应用程序集中起来,然后进行封装,提供一个统一的接口,这个接口是一个高于这些子应用程序接口的一个统一接口,从而方便了我们的调用,降低了对这些子应用程序的依赖性。还有就是在一些业务接口中,我们要同时对数据库几个不同的表进行操作时,会将这些个事务封装起来,放在一个业务接口中,我们调用的时候就只需调用这个业务接口就可以了。
 
设计模式:
外观模式:为众多个子系统众多额一组接口提供一个一致的界面,定义了一个高层接口,这个接口使得这些子系统更加容易使用。
 
故事背景:
“这个世界太安全,只有音乐最安全...”,音乐似乎成了现代人生活中不可缺的一部分,在大学生时代,酷狗音乐也是在我们中间比较流行的一款音乐播放器,我个人更是honest fans了,将一些自己爱听的歌曲放到酷狗音乐播放器的目录中,然后轻轻一点,就扫描出来,一般是顺序播放,有时候来劲了,就来个随机播放,抽风的时候,会单曲循环,当然今天不抽风...
 
面向对象分析:
这个酷狗音乐播放器,可以是一个facade,顺序播放,随机播放就是两个高层的接口了,那么那些具体的歌曲中的play就是一些分散的接口,当然我们也可以放完一首哥,手动点到下一首,这样是不是我们必须知道每一首歌曲的位置啊,这样谁也不愿意干,要是这样,酷狗就不会这么流行的,所以,我们只需要调用一个统一的接口,比如说顺序播放,我们只需鼠标一点,就可以尽情听音乐了。
 
1.抽取对象:核心是这个facade了,也就是KuGouMusic;
然后就是一个抽象的Music对象;
那么子系统就是这些歌曲了,这里罗列我常听的三首,Grass(小草),Sailor(水手),OldBoy(老男孩)
2.类的职责:外观KuGouMusic:orderPlay()--顺序播放
  randomPlay()--随机播放
抽象Music:play()--播放功能;
3.类的交互:在KouGouMusic中两个个高层接口中以不同的方式调用三首音乐的播放接口;
 
 
UML类图:
 
 
代码实现:
首先我们要有先要听的音乐吧,这里抽取了一个抽象类,也可以不这么设计,直接是具体的类:
Music:
[java] 
public abstract class Music {  
    protected String name;  
      
    /** 
     * 音乐播放 
     */  
    public abstract void play();  
}  
@任何音乐都要有play的行为,也许有人会问播放行为不是播放器的嘛,这样说好比人开门的经典案例了,在面向对象分析与设计中,这个play是音乐自身的行为,播放器只是调用了音乐的这个方法。
 
然后是我喜欢的歌曲:
小草
Grass:
[java]  
public class Grass extends Music {  
  
    public Grass(String name) {  
        this.name = name;  
    }  
  
    @Override  
    public void play() {  
        System.out.println("《" + name + "》 -- 郑智化:");  
        System.out.println(MusicUtils.getLyricByName(name));  
    }  
}  
 
水手Sailor:
[java] 
public class Sailor extends Music {  
  
    public Sailor(String name) {  
        this.name = name;  
    }  
  
    @Override  
    public void play() {  
        System.out.println("《" + name + "》--郑智化:");  
        System.out.println(MusicUtils.getLyricByName(name));  
    }  
}  
 
老男孩OldBoy:
[java]  
public class OldBoy extends Music {  
  
    public OldBoy(String name) {  
        this.name = name;  
    }  
  
    @Override  
    public void play() {  
        System.out.println("《" + name + "》--筷子兄弟:");  
        System.out.println(MusicUtils.getLyricByName(name));  
    }  
}  
@上面用到了一个MusicUtils的工具类,这里是我编写的一个工具类,用来存放歌词信息的,用展示歌词的方式来演示播放功能:MusicUtils:
[java]  
public final class MusicUtils {  
  
  
    private static Map<String, String> lyrics = new HashMap<String, String>();  
  
  
    static {  
        // 老男孩 -- 筷子兄弟  
        lyrics.put("老男孩", "那是我日夜思念深深爱着的人啊\n" + "到底我该如何表达 她会接受我吗 \n"  
                + "也许永远都不会跟她说出那句话\n " + "注定我要浪迹天涯 怎么能有牵挂\n "  
                + "梦想总是遥不可及 是不是应该放弃...");  
        // 小草 -- 郑智化  
        lyrics.put("小草", "小小的草 迎风在摇\n" + "狂风暴雨之中挺直了腰\n" + "别笑我小 别笑我孬 \n"  
                + "风吹雨打之后依然不倒 \n" + "动荡的大地之中落地生根\n" + " 苦难的时代之中不屈不挠...");  
        // 水手 -- 郑智化  
        lyrics.put("水手", "苦涩的沙吹痛脸庞的感觉 \n" + "像父亲的责骂母亲的哭泣 \n"  
                + "永远难忘记 年少的我喜欢一个人在海边 \n" + "卷起裤管光着脚丫踩在沙滩上 \n"  
                + "总是幻想海洋的尽头有另一个世界 \n" + "总是以为勇敢的水手是真正的男儿 \n"  
                + "总是一副弱不禁风孬种的样子 \n" + "在受人欺负的时候总是听见水手说 \n" + "他说风雨中这点痛算什么 \n"  
           
补充:软件开发 , C++ ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,