大话设计模式 —— 第十二章《外观模式》C++ 代码实现

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_34536551/article/details/89160536

目录

概述

定义

优点

缺点

使用场景

与适配器模式的区别


概述


  外观模式是一种使用频率非常高的结构型设计模式,它通过引入一个外观角色来简化客户端与子系统之间的交互,为复杂的子系统调用提供一个统一的接口,降低子系统与客户端的耦合度,且客户端调用非常方便。


定义


外观模式(也称为门面模式):

  • 为子系统中的一组接口提供一个一致的接口,此模式定义了一个更高级的接口,这个结口使得这子系统更加容易使用。
  •      说白了就是:外观类提供了一个接口,只有通过该类的函数接口才可以访问这些子系统,就像有一个类将所有的类都包装起来,子系统类有的方法外观类都有。当客户端调用这个高级接口时,不用关心高层内部调用是如何组合底层方法的,也不用关心底层函数是如何实现的。
UML图
  • Facade 外观角色: 在客户端可以调用它的方法,该角色持有所有底层类的对象,并且包含底层类中所有的方法,客户端通过调用该角色的方法来间接访问底层的子类。
  • subsystem子系统角色:子系统相当于多个类的集合,门面角色将其封装起来,使得客户端并不能直接调用它们的方法。子系统可以有多个。
  • Client:客户端,直接使用Facade接口提供的方法

这里就可以看出来,对Client来说只需要知道 Facade 一个就行,不需要知道Facade内部的复杂逻辑和结构,降低用户的使用成本。

      外观模式中所指的子系统是一个广义的概念,它可以是一个类、一个功能模块、系统的一个组成部分或者一个完整的系统。子系统类通常是一些业务类,实现了一些具体的、独立的业务功能,具体代码如下:

#include<iostream>
#include<string>
using namespace std;

class SubSystemOne final
{
public:
	void MethodOne()
	{
		std::cout << "子系统方法一" << std::endl;
	}
};

class SubSystemTwo final
{
public:
	void MethodTwo()
	{
		std::cout << "子系统方法二" << std::endl;
	}
};


class SubSystemThree final
{
public:
	void MethodThree()
	{
		std::cout << "子系统方法三" << std::endl;
	}
};

class SubSystemFour final
{
public:
	void MethodFour()
	{
		std::cout << "子系统方法四" << std::endl;
	}

};

class Facade final
{
private:
	SubSystemOne one;
	SubSystemTwo two;
	SubSystemThree three;
	SubSystemFour four;
public:
	void MethodA()
	{
		std::cout << "方法组A()------" << std::endl;
		one.MethodOne();
		two.MethodTwo();
		three.MethodThree();
		cout << endl;
	}
	void MethodB()
	{
		std::cout << "方法组B()------" << std::endl;
		two.MethodTwo();
		three.MethodThree();
		cout << endl;
	}
};



int main()
{
	{
		Facade myFacade;
		myFacade.MethodA();
		myFacade.MethodB();
		
	}
	system("pause");
	return 0;
}

可以看到,客户端通过访问外观类来调用子系统内部类的方法。客户端并不知道谁来执行该方法,只是知道子系统中有这个方法即可调用。


优点


  • 能够减少各个类之间的相互依赖,现在只依赖于外观类.
  • 外观模式为复杂子系统提供了一个简单接口,并不为子系统添加新的功能和行为。
  • 外观模式并没有封装子系统的类,只是提供了简单的接口。 如果应用需要,它并不限制客户使用子系统类。
  • 子系统中任何类对其方法的内容进行修改,不影响外观类的代码。 

降低了客户类与子系统类的耦合度,实现了子系统与客户之间的松耦合关系

  • 只是提供了一个访问子系统的统一入口,并不影响用户直接使用子系统类
  • 减少了与子系统的关联对象,实现了子系统与客户之间 的松耦合关系,松耦合使得子系统的组件变化不会影响到它的客户。

外观模式对客户屏蔽了子系统组件,从而简化了接口,减少了客户处理的对象数目并使子系统的使用更加简单。

  • 引入外观角色之后,用户只需要与外观角色交互;
  • 用户与子系统之间的复杂逻辑关系由外观角色来实现

降低原有系统的复杂度和系统中的编译依赖性,并简化了系统在不同平台之间的移植过程

  • 因为编译一个子系统一般不需要编译所有其他的子系统。一个子系统的修改对其他子系统没有任何影响,而且子系统内部变化也不会影响到外观对象。

缺点


  • 在不引入抽象外观类的情况下,增加新的子系统可能需要修改外观类或客户端的源代码,违背了“开闭原则”
  • 不能很好地限制客户使用子系统类,如果对客户访问子系统类做太多的限制则减少了可变性和灵活性。

使用场景


  • 构建一个有层次结构的子系统时,使用外观模式定义子系统中每层的入口点,如果子系统之间是相互依赖的,则可以让他们通过外观接口进行通信,减少子系统之间的依赖关系。这样可以对一个复杂的子系统对外提供一个简单的接口。
  • 子系统往往会因为不断的重构演化而变得越来越复杂,大多数的模式使用时也会产生很多很小的类,这给外部调用他们的用户程序带来了使用的困难,我们可以使用外观类提供一个简单的接口,对外隐藏子系统的具体实现并隔离变化。
  • 当维护一个遗留的大型系统时,可能这个系统已经非常难以维护和拓展,但因为它含有重要的功能,新的需求必须依赖于它,则可以使用外观类,来为设计粗糙或者复杂的遗留代码提供一个简单的接口,让新系统和外观类交互,而外观类负责与遗留的代码进行交互。
  • 在层次化结构中,可以使用外观模式定义系统中每一层的入口 ,层与层之间不直接产生联系,而通过外观类建立联系,降低层之间的耦合度。 

客户程序与多个子系统之间存在很大的依赖性 

  • 引入外观类将子系统与客户以及其他子系统解耦,可以提高子系统的独立性和可移植性。

与适配器模式的区别


  • 外观模式的实现核心主要是——由外观类去保存各个子系统的引用,实现由一个统一的外观类去包装多个子系统类,然而客户端只需要引用这个外观类,然后由外观类来调用各个子系统中的方法。
  • 这样的实现方式非常类似适配器模式,然而外观模式与适配器模式不同的是:适配器模式是将一个对象包装起来以改变其接口,而外观是将一群对象 ”包装“起来以简化其接口。它们的意图是不一样的,适配器是将接口转换为不同接口,而外观模式是提供一个统一的接口来简化接口。

猜你喜欢

转载自blog.csdn.net/qq_34536551/article/details/89160536