设计模式15-门面模式

设计模式15-门面模式

  • "接口隔离"模式
    • 典型模式
      • 1. 适配器模式(Adapter Pattern)
      • 2. 装饰模式(Decorator Pattern)
      • 3. 桥接模式(Bridge Pattern)
      • 4. 代理模式(Proxy Pattern)
      • 5. 策略模式(Strategy Pattern)
      • 总结
  • 推导
    • A方案
    • B方案
  • 定义
  • 结构
    • 主要元素解释
    • 示意图的整体解释
  • 要点总结

"接口隔离"模式

组建构建过程中某些接口之间直接的依赖往往会带来许多问题。甚至根本无法实现。采用添加一层间接稳定的接口的方式来隔离。本来互相紧密关联的接口是一种常见的解决方式。

典型模式

接口隔离原则(Interface Segregation Principle, ISP)是面向对象设计中的一个重要原则。它强调不应强迫客户端依赖于他们不需要的方法,而应将接口拆分成更小和更具体的接口,使得客户端只需知道它们需要的方法。

在实际的软件设计中,有几个设计模式能够帮助实现接口隔离原则:

1. 适配器模式(Adapter Pattern)

动机: 将一个接口转换成客户希望的另一个接口,使得原本由于接口不兼容而不能一起工作的类可以一起工作。

实现:

  • 类适配器模式:通过多重继承实现,适配器继承自适配者类和目标接口。
  • 对象适配器模式:通过组合实现,适配器持有适配者对象的实例。

代码示例:

class ITarget {
public:virtual void request() = 0;
};class Adaptee {
public:void specificRequest() {std::cout << "Adaptee specific request." << std::endl;}
};class Adapter : public ITarget {
private:Adaptee* adaptee;public:Adapter(Adaptee* adaptee) : adaptee(adaptee) {}void request() override {adaptee->specificRequest();}
};

2. 装饰模式(Decorator Pattern)

动机: 动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式相比生成子类更为灵活。

实现:

  • 使用一个抽象接口和具体的装饰类,这些装饰类可以在运行时动态地添加行为到对象中。

代码示例:

class Component {
public:virtual void operation() = 0;
};class ConcreteComponent : public Component {
public:void operation() override {std::cout << "ConcreteComponent operation." << std::endl;}
};class Decorator : public Component {
protected:Component* component;public:Decorator(Component* component) : component(component) {}void operation() override {component->operation();}
};class ConcreteDecorator : public Decorator {
public:ConcreteDecorator(Component* component) : Decorator(component) {}void operation() override {Decorator::operation();std::cout << "ConcreteDecorator additional operation." << std::endl;}
};

3. 桥接模式(Bridge Pattern)

动机: 将抽象部分与它的实现部分分离,使它们都可以独立地变化。

实现:

  • 抽象类和实现类通过桥接模式分离开来,可以独立地对其进行扩展和变化。

代码示例:

class Implementor {
public:virtual void operationImpl() = 0;
};class ConcreteImplementorA : public Implementor {
public:void operationImpl() override {std::cout << "ConcreteImplementorA operation." << std::endl;}
};class Abstraction {
protected:Implementor* implementor;public:Abstraction(Implementor* implementor) : implementor(implementor) {}virtual void operation() {implementor->operationImpl();}
};class RefinedAbstraction : public Abstraction {
public:RefinedAbstraction(Implementor* implementor) : Abstraction(implementor) {}void operation() override {implementor->operationImpl();}
};

4. 代理模式(Proxy Pattern)

动机: 为其他对象提供一种代理以控制对这个对象的访问。

实现:

  • 使用代理类来控制对实际对象的访问,代理类实现了实际对象的接口。

代码示例:

class Subject {
public:virtual void request() = 0;
};class RealSubject : public Subject {
public:void request() override {std::cout << "RealSubject request." << std::endl;}
};class Proxy : public Subject {
private:RealSubject* realSubject;public:Proxy(RealSubject* realSubject) : realSubject(realSubject) {}void request() override {if (realSubject == nullptr) {realSubject = new RealSubject();}realSubject->request();}
};

5. 策略模式(Strategy Pattern)

动机: 定义一系列算法,并将它们封装起来,使它们可以相互替换,本模式使得算法可独立于使用它的客户而变化。

实现:

  • 定义一个策略接口和具体的策略实现类,客户端通过组合的方式使用策略接口来实现不同的行为。

代码示例:

class Strategy {
public:virtual void algorithm() = 0;
};class ConcreteStrategyA : public Strategy {
public:void algorithm() override {std::cout << "ConcreteStrategyA algorithm." << std::endl;}
};class ConcreteStrategyB : public Strategy {
public:void algorithm() override {std::cout << "ConcreteStrategyB algorithm." << std::endl;}
};class Context {
private:Strategy* strategy;public:Context(Strategy* strategy) : strategy(strategy) {}void setStrategy(Strategy* strategy) {this->strategy = strategy;}void executeAlgorithm() {strategy->algorithm();}
};

总结

接口隔离原则强调将大接口拆分成更小的、更加具体的接口,以便客户端只依赖于它们实际需要的接口。上述设计模式在一定程度上体现了这一原则,通过这些模式的合理运用,可以设计出更加灵活和可维护的系统。

推导

在这里插入图片描述这张图展示了系统设计中关于系统间耦合复杂度减少的一种对比方案。具体来说,图中分为A方案和B方案两种系统设计方案,通过这两种方案的对比,阐述了如何通过设计模式(特别是Facade模式)来降低系统间的耦合复杂度,从而提高系统的可维护性和可扩展性。

A方案

描述:
在A方案中,客户端类(client classes)与子系统类(subsystem classes)之间存在直接耦合。这意味着客户端类直接依赖于多个子系统类,这种直接依赖关系增加了系统的耦合度,使得系统变得复杂且难以维护。当子系统发生变化时,客户端类也需要进行相应的修改,这违反了开闭原则(软件实体应当对扩展开放,对修改关闭)。
问题:
直接耦合导致系统结构紧密,修改成本高,且不利于系统的扩展和维护。

B方案

描述:

  • 为了解决A方案中的问题,B方案引入了Facade模式。Facade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。在B方案中,Facade作为客户端类和子系统类之间的中介,客户端类不再直接与子系统类交互,而是通过Facade来进行交互。这样,客户端类与子系统类之间的耦合度大大降低,客户端类只需与Facade交互即可,无需了解子系统类的内部细节。

优势:

  • Facade模式降低了系统的耦合度,提高了系统的灵活性和可维护性。当子系统内部发生变化时,客户端类无需修改,只需调整Facade即可,从而降低了修改成本和风险。

定义

为此系统中的一组接口提供了一个一致稳定的界面。门面模式是定义了一个高层接口,这个接口使得这一子系统更容易的使用和复用。

结构

在这里插入图片描述

这张门面模式(Facade Pattern)结构示意图清晰地展示了该设计模式在软件架构中的应用。门面模式是一种结构型设计模式,它为子系统中的一组接口提供一个统一的接口,使得这一子系统更加容易使用。在这个示意图中,各个元素和它们之间的关系被巧妙地描绘出来,以便理解门面模式的工作原理。

主要元素解释

结构(Structure):

  • 这个词在图中可能指代整个软件系统的结构,特别是与门面模式相关的那部分结构。它强调了系统内部的组织和关系,尤其是门面如何作为这些内部结构的对外接口。

Facade:

  • 门面是此设计模式的核心。在图中,Facade被明确标出,作为子系统(subsystem classes)与客户端(未直接显示在图中)之间的中介。门面类为子系统提供了一个简化的接口,客户端通过这个接口与子系统交互,而无需直接与子系统中的多个类打交道。这样做的好处是降低了系统的耦合度,提高了系统的可维护性和可扩展性。

子系统类(subsystem classes):

  • 这些是系统中实际执行功能的类。在图中,虽然文本“suhsysiem ciasses”似乎是“subsystem classes”的拼写错误,但我们可以推断出它指的是多个子系统类。这些类之间可能存在复杂的依赖和交互关系,但通过使用门面模式,这些复杂性被封装在子系统内部,对外部客户端透明。

示意图的整体解释

整个示意图通过简洁的线条和清晰的标签,展示了门面模式在软件系统中的应用。客户端(尽管未在图中直接显示)通过门面与子系统交互,而不需要知道子系统内部的具体实现细节。这种设计使得系统更加模块化,易于管理和维护。同时,它也使得系统更加灵活,因为当子系统内部发生变化时,只要门面接口保持不变,客户端代码就无需修改。

综上所述,这张门面模式结构示意图通过直观的方式展示了该设计模式在软件架构中的关键作用,即提供一个简化的接口来封装子系统的复杂性。系统的复杂性。

要点总结

  • 从客户程序的角度来看,门面模式简化了一个组件系统的接口。组建内部与外部客户程序来说,达到了一种解耦的效果。内部子系统的任何变化都不会影响到门面模式接口的变化。
  • 平面设计模式更注重从架构的层次去看整个系统,而不是单个类的层次。美面膜是很多时候更是一种架构设计模式。
  • 平面设计模式并非一个集装箱可以任意的放进任何多个对象门面模式中组建的内部应该是相互和关系比较大的系列组件,而不是一个简单的功能集合。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/51665.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Git基本原理介绍及常用指令

文章目录 前言一、Git是什么&#xff1f;集中化的版本控制系统分布式版本控制系统 二、Git基本概念三、git命令操作配置用户信息常用指令 总结 前言 如果你用Microsoft Word写过论文&#xff0c;那你一定有这样的经历&#xff1a;想删除一个段落&#xff0c;又怕将来想恢复找不…

kafka cmd

list topic ./bin/kafka-topics.sh --list --zookeeper 127.0.0.1:2181指定 conf 如果是 ssl 协议指定 指定配置文件 /opt/kafka/bin/kafka-consumer-groups.sh --command-config /opt/kafka/bin/kafka-console-consumer.sh --consumer.config/opt/kafka/bin/kafka-console…

linux:用户管理,增删改

1.查看当前登录的用户信息 [root@bgx ~]# id #查看当前所登陆的用户信息 # uid:用户id,系统只能识别uid,不能识别名字,人看名字 # gid:组id uid=0(root) gid=0(root) groups=0(root) [root@bgx ~]# id oldboy #查看其它用户的信息 uid=1000(oldboy) gid=1000(oldboy) g…

【Linux】2.Linux 指令大揭秘:常见八个指令的妙用(上)

欢迎来到 CILMY23 的博客 &#x1f3c6;本篇主题为&#xff1a;Linux 指令大揭秘&#xff1a;常见八个指令的妙用&#xff08;上&#xff09; &#x1f3c6;个人主页&#xff1a;CILMY23-CSDN博客 &#x1f3c6;系列专栏&#xff1a;Python | C | C语言 | 数据结构与算法 | …

【SpringBoot】参数传递之@ModelAttribute

ModelAttribute标注的方法会在Controller类的每个映射URL的控制执行方法之前执行。 ModelAttribute public void findUserById(PathVariable("userId") Long userId,Model model){ model.addAttribute("user",userService.findUserById(userId)); } GetM…

千万别从系统中创建线程, 看看从线程池中调用的线程的效率(1)

本篇会加入个人的所谓鱼式疯言 ❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言 而是理解过并总结出来通俗易懂的大白话, 小编会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的. &#x1f92d;&#x1f92d;&#x1f92d;可能说的不是那么严谨.但小编初心是能让更多人…

Web3.js 4.x版本事件监听详解:从HTTP到WebSocket的迁移

项目场景 在一个使用以太坊区块链技术的项目中&#xff0c;需要监听智能合约的事件&#xff0c;以便在事件触发时能够及时响应。项目中使用了web3.js库的4.x版本&#xff0c;节点使用Geth启动&#xff0c;并通过HTTP与节点进行通信。 问题描述 合约DataStorage.sol文件已经定…

学习c语言第16天(数据的存储)

一、数据类型的介绍 c语言基本的内置类型 类型的意义&#xff1a; 1.使用这个类型开辟内存空间的大小(大小决定了使用范围) 2.如何看待内存空间的视角 1.类型的基本归类 整形家族 字符的本质是ASCII码值&#xff0c;是整形 int a等于 signed int a char稍微特殊一些…

新书速览|动手学PyTorch建模与应用:从深度学习到大模型

《动手学PyTorch建模与应用&#xff1a;从深度学习到大模型》 本书内容 《动手学PyTorch建模与应用:从深度学习到大模型》是一本从零基础上手深度学习和大模型的PyTorch实战指南。《动手学PyTorch建模与应用:从深度学习到大模型》共11章&#xff0c;第1章主要介绍深度学习的概念…

【检查 Android 设备上的热点(AP)状态】

在这篇教程中,我们将介绍如何使用 adb 命令检查 Android 设备上热点(AP)的状态。我们将通过命令行工具 ifconfig 来判断热点是否启用,并提供一个 Python 脚本示例来自动化这一过程。 前提条件 ADB 环境设置: 确保你已经在计算机上安装并配置好了 ADB (Android Debug Bridg…

【Go - redis client 单例模式】

以下是redis client单例&#xff0c;使用sync.Once保证无论单线程(协程)还是多线程(协程) 只执行一次。 示例 package mainimport ("context""fmt""sync""github.com/redis/go-redis/v9" )var (RedisClientSingleton *redis.Cliento…

深入浅出:Squid技术详解,让你的网络加速与安全无忧

在当今互联网高速发展的时代&#xff0c;网络的稳定性与安全性显得尤为重要。作为一款强大的代理服务器软件&#xff0c;Squid凭借其灵活的配置和强大的功能&#xff0c;成为了众多企业和个人用户的首选。本文将深入探讨Squid的核心技术、应用场景及优化技巧&#xff0c;帮助你…

Python --Pandas库基础方法(2)

文章目录 Pandas 变量类型的转换查看各列数据类型改变数据类型 重置索引删除行索引和切片seriesDataFrame取列按行列索引选择loc与iloc获取 isin()选择query()的使用排序用索引排序使用变量值排序 修改替换变量值对应数值的替换 数据分组基于拆分进行筛选 分组汇总引用自定义函…

Linux 中断的 CPU 亲和性

文章目录 1. 前言2. 背景3. 什么是中断的 CPU 亲和性3. IRQ 中断 默认的 CPU 亲和性4. 硬件架构 CPU 固有 IRQ 中断亲和性5. 中断芯片 各中断 CPU 亲和性 初始化5.1 GIC v2 芯片的 SPI 中断 CPU 亲和性 初始化5.1.1 软件层次: 中断 CPU 亲和性 初始化5.1.2 中断芯片层次: GIC v…

前端面试从基础到资深问题汇总

基础篇 前端基础知识问答-js篇 JavaScript是前端开发的核心语言之一&#xff0c;以下是一些关于JavaScript的基础知识问答&#xff1a; Q: 什么是JavaScript&#xff1f; A: JavaScript是一种高级的、解释型的编程语言&#xff0c;通常用于网页开发中&#xff0c;实现网页的交…

Spring-cloud Alibaba组件--Dubbo

远程调用技术 RestFul风格 基于HTTP协议实现&#xff0c;而HTTP是一种网络传输协议&#xff0c;基于TCP&#xff0c;规定了数据传输的格式。 RPC协议 Remote Produce Call 远程过程调用&#xff0c;类似的还有 RMI &#xff08; remote method invoke&#xff09;。自定义数…

优思学院|抽样检验的概念和21种抽样方式

抽样检验的概念 根据事先制定的抽样方案&#xff0c;从一批产品中随机抽取一部分作为样品&#xff0c;以这部分样品的检验结果&#xff0c;对整批产品质量合格与否作出判定的活动过程&#xff0c;称为抽样检验。除了用于质量控制之外&#xff0c;抽样检验同样适用于在六西格玛…

AI工作流程设计的自动化优化:微软与斯坦福的新成果 - Trace

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

学习网络安全 为什么Linux首择Kali Linux? 以及如何正确的使用Kali Linux

1.什么是kali linux&#xff1f; Kali Linux是一款基于Debian的Linux发行版&#xff0c;主要用于网络安全测试和渗透测试。它由全球顶尖的安全专家和黑客社区维护开发&#xff0c;提供了丰富的工具和资源&#xff0c;用于测试安全性、漏洞利用和渗透测试。此外&#xff0c;Kal…

修复msvcp120.dll丢失的问题的几种简单方法,msvcp120.dll是什么

在使用电脑时&#xff0c;你可能会遭遇一个提示称“msvcp120.dll丢失”的错误信息。这个问题比较普遍&#xff0c;主要是因为你的系统中缺失了某个特定的动态链接库&#xff08;DLL&#xff09;文件。msvcp120.dll是由 Microsoft Visual C 可再发行包提供的关键文件&#xff0c…