[原译]理解并实现外观设计模式

著作权声明:本文由http://leaver.me 翻译,欢迎转载分享。请尊重作者劳动,转载时保留该声明和作者博客链接,谢谢!

介绍
本文介绍外观模式,并给出简单的实现示例

背景

写软件的时候,有时候需要处理一系列的对象来完成一个确定的任务.比如,我们给一个万能遥控器写代码,我们需要关掉所有的设备,那么,我们有这样几种选择.第一个就是手动选择每一个设备,然后一个接一个的关闭,这好傻.那我们为什么不再遥控器上放一个按钮,我们按一下就关掉了.按钮的命令会与设备控制器通信然后关掉他们.

如果我们又想在晚上12的时候自动关闭设备,那么我们就会有一个基于事件的计时器,与设备通信,然后关闭设备,问题是在两种情况下我们都需要与这些对象通信的函数.

有很多方法解决这个问题,为什么不能有一个对象,该对象的责任就是关闭设备,当我要关闭设备的时候,我调用该对象就行了.这也是外观模式的理念Gof大神定义外观模式
"Provide a unified interface to a set of interfaces in a subsystem. Façade defines a higher-level interface that makes the subsystem easier to use."

为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。

看看模式图

注意外观对象仅仅是提供了对函数一起操作,.不能替换子系统的接口.子系统的类仍然可以被系统的其他部分访问.外观为子系统提供了一致的界面.

使用代码
为了模拟外观模式,我们模拟一个小例子.试着实现一个简单的外观对象,该外观对象操作一些WP手机的控制器对象,我们先定义问题

每天早上我跑步的时候,我都得对我的手机做出以下的事情..
1. 关闭wifi
2. 切换到移动网络
3. 打开GPS
4. 打开音乐
5. 开始跑步追踪器

跑完以后.,我又蛋疼的做出以下几件事
1. 在twitter和facebook上分享我的跑步数据
2. 关闭跑步追踪器
3. 关闭音乐
4. 关闭GPS
5. 关闭移动数据
6. 打开wifi

目前我都是手工做的.,我们来实现这些假想的控制器类吧.

class GPSController
{
    bool isSwitchedOn = false;

    public bool IsSwitchedOn
    {
        get
        {
            return isSwitchedOn;
        }
        set
        {
            isSwitchedOn = value;
            DisplayStatus();
        }
    }

    private void DisplayStatus()
    {
        string status = (isSwitchedOn == true) ? "ON" : "OFF";
        Console.WriteLine("GPS Switched {0}", status);
    }
}

 

其他的像MobileDataController, MusicController, WifiController 代码都是基本的一样的.

然后模拟一下跑步追踪器这个app

class SportsTrackerApp
{
    public void Start()
    {
        Console.WriteLine("Sports Tracker App STARTED");
    }

    public void Stop()
    {
        Console.WriteLine("Sports Tracker App STOPPED");
    }

    public void Share()
    {
        Console.WriteLine("Sports Tracker: Stats shared on twitter and facebook.");
    }
}

 

下面模拟一下我的手工过程

static void Main(string[] args)
{
// 手机启动,所有控制器运行
 GPSController gps = new GPSController();
    MobileDataController data = new MobileDataController();
    MusicController zune = new MusicController();
    WifiController wifi = new WifiController();

    ///////////// 要跑步了 /////////////////////

    // 1. 关闭wifi
    wifi.IsSwitchedOn = false;

    // 2. 切换 移动数据
    data.IsSwitchedOn = true;

    // 3. 打开 GPS
    gps.IsSwitchedOn = true;

    // 4. 打开音乐
    zune.IsSwitchedOn = true;

    // 5. 开始Sports-Tracker软件
    SportsTrackerApp app = new SportsTrackerApp();
    app.Start();

    ///////////// 跑步归来 /////////////////////
    Console.WriteLine();

    // 0. 在 twitter 和 facebook分享数据
    app.Share();

    // 1. 停止Sports Tracker软件
    app.Stop();

    // 2. 关闭音乐
    zune.IsSwitchedOn = false;

    // 3. 关闭GPS
    gps.IsSwitchedOn = false;

// 4. 关闭移动数据
 data.IsSwitchedOn = false;

    // 5. 打开wifi
    wifi.IsSwitchedOn = true;          
}

 

手工部分模拟完了.运行效果看看

好了.我们还是写个外观软件自动做这个吧 该软件对外提供两个接口StartJogging.和
StopJogging 帮我做这些事,(ps:这部分代码中的英文我就不翻译了,和前面的一样)

class MyJoggingFacade
{
    // These handles will be passed to this facade in a real application
    // also on actual device these controllers will be singleton too.
    GPSController gps = new GPSController();
    MobileDataController data = new MobileDataController();
    MusicController zune = new MusicController();
    WifiController wifi = new WifiController();

    SportsTrackerApp app = null;

    public void StartJogging()
    {
        // 1. Turn off the wifi
        wifi.IsSwitchedOn = false;

        // 2. Switch on the Mobile Data
        data.IsSwitchedOn = true;

        // 3. Turn on the GPS
        gps.IsSwitchedOn = true;

        // 4. Turn on the Music
        zune.IsSwitchedOn = true;

        // 5. Start the Sports-Tracker
        app = new SportsTrackerApp();
        app.Start();
    }

    public void StopJogging()
    {
        // 0. Share Sports tracker stats on twitter and facebook
        app.Share();

        // 1. Stop the Sports Tracker
        app.Stop();

        // 2. Turn off the Music
        zune.IsSwitchedOn = false;

        // 3. Turn off the GPS
        gps.IsSwitchedOn = false;

        // 4. Turn off the Mobile Data
        data.IsSwitchedOn = false;

        // 5. Turn on the wifi
        wifi.IsSwitchedOn = true;
    }
}

 

然后用户这样用

static void Main(string[] args)
{
    MyJoggingFacade facade = new MyJoggingFacade();

    facade.StartJogging();
    Console.WriteLine();
    facade.StopJogging();          
}

 

结果如图

总结之前,看看我们这个例子的结构图

注意,这只是一个例子,和真实情况有差距。理解就好了

亮点何在

本文讨论了外观模式,很容易和适配器模式混淆,事实上,适配器模式也给用户提供了一个接口,之前的接口就不可访问了。而外观模式的之前的接口还是可以访问的。希望对你有帮助。
Demo下载
FacadeDemo.zip

原文地址:UnderstandingplusandplusImplementingplusFacadeplus

著作权声明:本文由http://leaver.me 翻译,欢迎转载分享。请尊重作者劳动,转载时保留该声明和作者博客链接,谢谢!

posted @ 2012-10-23 18:44  lazycoding  阅读(1127)  评论(0编辑  收藏  举报