外观模式学习总结

外观模式提供了一个统一的接口,使得客户端可以方便地访问子系统的多个组件,降低了系统复杂性。通过一个实例,展示了如何用外观模式制作咖啡,减少客户端与子系统间的耦合。总结了模式的优点,如简化代码、松耦合,但也指出其潜在缺点,如可能增加客户端直接访问子系统的风险。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

 

外观模式

引言

定义

模式类图

实例

实例描述

实例类图

代码实现

模式扩展

外观类的数量

抽象外观类

总结

模式优点

模式缺点


外观模式

引言

一般情况下,一个Web网站都会提供一个首页,作为网站的入口,我们只需要记住这个首页的地址,即可访问它的各个子页面的超链接。当然,用户也可以记住每个子页面的地址,直接通过子页面的地址直接访问。实际上用户是不会记住每一个子页面的地址,此时可以通过首页间接的访问期望访问的子页面,在这里首页就扮演了一个“外观角色”。

定义

英文定义:"Provide a unified interface to a set of interfaces in a subsystem. Facade defines a higher-level interface that makes the subsystem easier to use."。

中文定义:外部与一个子系统的通信必须通过一个统一的外观对象进行,为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层次接口,这个接口使得这一子系统更加容易使用。

            外观模式重要等级★★★★★          外观模式难度等级★☆☆☆☆

模式类图

外观模式包含俩个角色:

1.Facade(外观角色)

2.SubSystem(子系统角色) 

实例

实例描述

自己泡咖啡需要自己准备开水(Boil Water)、准备咖啡(Prepare Coffee)、准备杯子(Prepare Cup)、还要自己去煮(Cook Coffee),而去咖啡厅喝咖啡只需要把要求告诉服务员,所有的过程由服务员来完成,此时服务员就是外观角色。用外观模式实现该场景,并且在测试代码中可以体现外观模式的有点。

实例类图

代码实现

1.Water 水类,提供烧水方法。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;


class Water
{
    public void Boil()
    {
        Console.WriteLine("烧开水");
    }
}

2.Coffee 咖啡类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;


class Coffee
{
    private string brand;
    public Coffee(string brand)
    {
        this.brand = brand;
    }

    public void PrepareCoffee()
    {
        Console.WriteLine("准备{0}咖啡原料",brand);
    }
}

3.Cup 杯子类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

class Cup
{
    public enum CupType
    {
        CoffeeCup,
        VacuumCup,
        masturbationCup
    }
    private CupType type;
    public Cup(CupType type)
    {
        this.type = type;
    }
    public void PrepareCup()
    {
        Console.WriteLine("准备杯子:" + type);
    }
}

4.Cooker 厨师类,提供煮咖啡方法

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;


class Cooker
{
    public void CookCoffee(Coffee coffee,Cup cup,Water water)
    {
        Console.WriteLine("煮咖啡:");
        water.Boil();
        coffee.PrepareCoffee();
        cup.PrepareCup();
    }
}

5.Waiter 服务员类,提供点咖啡方法。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;


class Waiter
{
    public void Order(string coffeeName)
    {
        Cooker cooker = new Cooker();
        Water water = new Water();
        Cup cup = new Cup(Cup.CupType.CoffeeCup);
        Coffee coffee = new Coffee(coffeeName);
        cooker.CookCoffee(coffee, cup, water);
    }
}

6.不使用外观模式的测试代码(不使用Waiter外观类)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

class Program
{
    static void Main(string[] args)
    {
        Cooker cooker = new Cooker();
        Water water = new Water();
        Cup cup = new Cup(Cup.CupType.CoffeeCup);
        Coffee coffee = new Coffee("摩卡");
        cooker.CookCoffee(coffee, cup, water);
        Console.ReadKey();
    }
}

7.运行结果

8.使用外观模式的测试代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

class Program
{
    static void Main(string[] args)
    {
        Waiter waiter = new Waiter();
        waiter.Order("摩卡");
        Console.ReadKey();
    }
}

9.运行结果

对比俩种测试代码,可以明显发现,它们都达到了相同的效果,但是使用外观类降低了客户端与子系统之间的耦合,客户端调用时无需再关心各个类如何使用,大大地简化了客户端代码。

模式扩展

外观类的数量

在外观模式中,通常只需要一个外观类,并且次外观类只有一个实例,换而言之他是一个单例类。在很多情况下为了节约系统资源,一般将外观类设计为单例类。当然,整个系统中也可以存在多个外观类,每个外观类都与一些特定的子系统交互,向用户提供相应的业务功能。

抽象外观类

外观模式在增加新的子系统或者移除子系统时需要修改外观类,违背了“开闭原则”。引入抽象外观类在一定程度上可以解决该问题:面对新的业务需求,不修改原有的外观类,而是通过新增一个具体外观类,客户端针对抽象编程,这样只需要修改配置文件或者反射即可更换新的外观类。

总结

模式优点

1.通过引入外观模式,外观类,客户端代码只和外观类直接通信,代码变得简单。

2.实现了子系统与客户之间的松耦合关系。

3.客户端依然可以直接访问子系统。

模式缺点

1.客户端依然可以直接访问子系统。(这既是优点有是缺点,如果客户端频繁直接访问子系统,那么会增加它们之间的耦合度)

2.在不引入抽象外观类的情况下,新增的需求可能需要修改外观类(违背了开闭原则)。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值