外观模式C

示例代码为了尽可能突显设计模式的特征,采用了极简代码。尽量避免其他代码对理解设计模式产生干扰

定义:

为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
简而言之就是,外观模式可以使客户端不用关心各个子系统之间的交互逻辑,它只需要知道担任“外观角色”的接口是哪个就足够了。

结构导图(刘伟老师的博客)


代码:

场景1

某个周六临近中午时,我饿了!为了填饱肚子,我只能从床上爬起来,准备做饭。
要知道,这可不是件容易的事情!毕竟我需要先去菜市场买菜,再洗菜,做菜。前后起码得折腾一小时,才能吃上饭!
没办法,银行卡里没钱了,没办法在线付款点外卖。动手吧!

    class BuyVegetables
    {
        /// <summary>
        /// 买菜
        /// </summary>
        public static void Buy()
        {
            Console.WriteLine("买完食材了。");
        }
    }
    class Cleanout
    {
        /// <summary>
        /// 洗菜
        /// </summary>
        public static void Clean()
        {
            Console.WriteLine("该洗的菜都洗好了。");
        }
    }
    class Cooking
    {
        /// <summary>
        /// 做菜
        /// </summary>
        public static void Cook()
        {
            Console.WriteLine("饭菜做好了。");
        }
    }

该忙的都忙完了,可算是可以吃了!

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("我饿了···");
            BuyVegetables.Buy();
            Cleanout.Clean();
            Cooking.Cook();
            Console.WriteLine("吃饱喝足。");
        }
    }

虽然吃的挺过瘾,但着实折腾!!!

场景2

一周过去了···

又到了周六,又到了临近中午的时间点,又饿了···
多么似曾相识的一幕~~~
难道今天我为了吃顿饭,还要这么辛苦吗?
不!因为我发工资了!银行卡里有钱了!我可以订外卖了!!!

首先,我们得有餐馆的联系方式

    class Restaurant
    {
        /// <summary>
        /// 外卖服务
        /// </summary>
        public static void Order()
        {
            Console.WriteLine("已收到订单,正在出餐···");
            BuyVegetables.Buy();
            Cleanout.Clean();
            Cooking.Cook();
            Console.WriteLine("已出餐,正在配送中···");
        }
    }

有了餐馆的联系方式后,就简单了。

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("我饿了,点个外卖吧···");
            Restaurant.Order();
            Console.WriteLine("抓起外卖我就猛吃呀!");
            Console.WriteLine("吃饱喝足,顺便还打了个饱嗝···");
        }
    }

这下舒坦了。

总结:

场景1中,客户(我)与吃饭这件事的交互相当麻烦,整个流程我自己做下来要费不少心思!实际工作中,这种场景非常常见,每一次都把子系统的逻辑耦合到客户端内,那么客户端将变得相当臃肿,且不稳定。
此时,提供一个中间件(外观者),也就是场景2中的“餐馆”,我只要一个电话,买菜,洗菜,做菜这种事情就都有人帮我解决了。实际工作中,也可以提供一个外观者,由它来负责和各个子系统(或者子功能)的交互,这样就减轻了客户端的复杂度。

补充讨论:

如果某一天,我只是随便点了一份清汤面,餐馆不用洗什么菜,只要买面条,并且煮好送到我手里就好了。那怎么办呢?我是不是就要改外观者的代码,把里面的Cleanout.Clean();代码删掉?这岂不是很不合理,违反了开闭原则?
是的,如果这样处理,那么势必会违反开闭原则!

怎么办呢?此时可以把外观者角色抽象出来!

    interface IRestaurant
    {
        /// <summary>
        /// 订餐服务
        /// </summary>
        void Order();
    }
    class NoodleRestaurant : IRestaurant
    {
        public void Order()
        {
            Console.WriteLine("已收到订单,正在出餐···");
            BuyVegetables.Buy();
            Cooking.Cook();
            Console.WriteLine("已出餐,正在配送中···");
        }
    }

这样我只需要在想吃面的时候,使用new NoodleRestaurant().Order() 即可成功订餐!

以上。

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理