理解并实现外观设计模式

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

背景

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

如果我们又想在晚上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下载 [downloadicon href=http://pan.baidu.com/share/link?shareid=90318&uk=1493685990]FacadeDemo.zip[/downloadicon]

原文地址:UnderstandingplusandplusImplementingplusFacadeplus

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

comments powered by Disqus