结构型模式

news2024/11/23 15:24:30

1.代理模式

  • 提供对象的替代品或其占位符。 代理控制着对于原对象的访问, 并允许在将请求提交给对象前后进行一些处理
  • 结构
    • 抽象主题类:通过接口或抽象类声明真实主题和代理对象实现的业务方法
    • 真实主题类:实现抽象主题中的具体业务,是代理对象所代理的真实对象,是最终要引用的对象
    • 代理类:提供与真实主题相同的接口,其内部含有对真实主题的引用,可以访问、控制或扩展真实主题的功能

2.适配器模式

  • 将一个类的接口转换成客户端希望的另外一个接口,使得原本由于接口不兼容而无法工作的类一起工作。适配器分为类适配器模式和对象适配器模式,前者耦合度比后者高。

  • 结构

    • 目标:当前系统业务所期待的接口,可以是抽象类或接口

    • 适配者:它是被访问和适配的现存组件库中的组件接口

    • 适配器:转换器,通过继承或引用适配器的对象,把适配者接口转换成目标接口,让客户按目标接口的格式访问适配者

      image-20230116165111908

  • 实现

    public interface TfCard {
        String readTf();
        void writeTf(String msg);
    }
    
    public class TfCardImpl implements TfCard{
        @Override
        public String readTf() {
            return "read TfCard data";
        }
    
        @Override
        public void writeTf(String msg) {
            System.out.println("write TfCard data"+msg);
        }
    }
    
    public interface SdCard {
        String readSd();
        void writeSd(String msg);
    }
    
    public class SdCardImpl implements SdCard{
        @Override
        public String readSd() {
            return "read SdCard data";
        }
    
        @Override
        public void writeSd(String msg) {
            System.out.println("write SdCard data"+msg);
        }
    }
    
    public class Computer {
    
        public String readSd(SdCard sdCard) {
            return sdCard.readSd();
        }
    
        public void writeTF(SdCard sdCard, String msg) {
            sdCard.writeSd(msg);
        }
    }
    
    public class SdAdapterTf implements SdCard{
        private TfCard tfCard;
    
        public SdAdapterTf(TfCard tfCard) {
            this.tfCard = tfCard;
        }
    
        @Override
        public String readSd() {
            return tfCard.readTf();
        }
    
        @Override
        public void writeSd(String msg) {
            tfCard.writeTf("SdAdapterTf");
        }
    }
    
  • 优缺点

    • 优点
      • 单一职责可以将接口或数据转换代码从程序主要业务逻辑中分离
      • 开闭原则只要客户端代码通过客户端接口与适配器进行交互,就能在不修改客户端代码情况下添加新类型的适配器
    • 缺点
      • 整体复杂度增加,因为需要新增一系列接口和类,有时直接更改服务器类使其与其它代码兼容会更简单

3.装饰者模式

  • 不改变现有对象结构的情况下,动态地给该对象增加一些职责

  • 结构

    • 抽象构件:定义一个抽象接口以规范准备接收附加责任的对象

    • 具体构件:实现抽象构件,通过装饰角色为其添加一些职责

    • 抽象装饰:继承或实现抽象构件,并包含具体构件的实例,可以通过其子类扩展具体构件的功能

    • 具体装饰:实现抽象装饰的相关方法,并给具体构件对象添加附加的责任

      image-20230116220050268

  • 实现

    // 抽象构件角色
    @Data
    public abstract class FastFood {
        private float price;
    
        private String desc;
    
        public FastFood(float price, String desc) {
            this.price = price;
            this.desc = desc;
        }
    
        public abstract float cost();
    }
    
    // 具体构件角色
    public class FriedRice extends FastFood{
    
        public FriedRice() {
            super(10,"炒饭");
        }
    
        @Override
        public float cost() {
            return getPrice();
        }
    }
    
    // 抽象装饰
    public abstract class Garnish extends FastFood {
        private FastFood fastFood;
    
        public FastFood getFastFood() {
            return fastFood;
        }
    
        public void setFastFood(FastFood fastFood) {
            this.fastFood = fastFood;
        }
    
        public Garnish(float price, String desc, FastFood fastFood) {
            super(price, desc);
            this.fastFood = fastFood;
        }
    }
    
    // 具体装饰
    public class Egg extends Garnish {
    
        public Egg(FastFood fastFood) {
            super(1, "鸡蛋", fastFood);
        }
    
        @Override
        public float cost() {
            return getPrice() + getFastFood().cost();
        }
    
        @Override
        public String getDesc() {
            return super.getDesc() + getFastFood().getDesc();
        }
    }
    
  • 优点与缺点

    • 优点
      • 无需创建新子类即可扩展对象的行为
      • 以在运行时添加或删除对象的功能
      • 用多个装饰封装对象来组合几种行为
      • 单一职责原则, 你可以将实现了许多不同行为的一个大类拆分为多个较小的类
    • 缺点
      • 在封装器栈中删除特定封装器比较困难
      • 实现行为不受装饰栈顺序影响的装饰比较困难
      • 各层的初始化配置代码看上去可能会很糟糕

4.桥接模式

  • 抽象与实现分离,使它们可以独立变化,用组合关系替代继承方式来实现,降低抽象和实现这两个可变维度的耦合度

  • 结构

    • 抽象化:定义抽象类,包含一个对实例化对象的引用

    • 扩展抽象化:抽象化角色的子类,实现父类中的业务方法,通过组合关系调用实现化角色中的业务方法

    • 实现化:定义实现化角色的接口,供扩展抽象化角色调用

    • 具体实现化:实现化角色接口的具体实现

      image-20230116225823358

  • 实现

    // 实现化角色
    public interface VideoFile {
    
        void decode(String fileName);
    }
    
    // 具体实现化角色
    public class RmVbFile implements VideoFile {
        @Override
        public void decode(String fileName) {
            System.out.println("RmVbFile:" + fileName);
        }
    }
    
    // 抽象化角色
    public abstract class OperatingSystem {
    
        protected VideoFile videoFile;
    
        public OperatingSystem(VideoFile videoFile) {
            this.videoFile = videoFile;
        }
    
        public abstract void playString(String fileName);
    }
    
    // 扩展抽象化
    public class Mac extends OperatingSystem{
        @Override
        public void playString(String fileName) {
           videoFile.decode("mac:"+fileName);
        }
    
        public Mac(VideoFile videoFile) {
            super(videoFile);
        }
    }
    

优点与缺点

  • 优点
    • 可以创建与平台无关的类和程序
    • 客户端代码仅与高层抽象部分进行互动, 不会接触到平台的详细信息
    • 开闭原则。 你可以新增抽象部分和实现部分, 且它们之间不会相互影响
    • 单一职责原则。 抽象部分专注于处理高层逻辑, 实现部分处理平台细节
  • 缺点
    • 对高内聚的类使用该模式可能会让代码更加复杂。

5.外观模式

  • 别名门面模式,通过多个复杂子系统提供一个一致的接口,而使这些子系统更加容易被访问的模式。该模式对外有一个统一接口,外部应用程序不用关心内部子系统的具体细节,大大降低应用程序的复杂性,提供程序的可维护性

  • 结构

    • 外观:多个子系统对外提供一个共同的接口

    • 子系统:实现系统的部分功能,客户可以通过外观角色访问它

      image-20230117094108267

  • 实现

    // 外观
    public  class SmartApplicationFacade {
    
        private Light light;
    
        private Tv tv;
    
        public SmartApplicationFacade() {
            this.light = new Light();
            this.tv = new Tv();
        }
    
        public void say(String msg) {
            if (msg.contains("开启")) {
                on();
            } else if (msg.contains("关闭")) {
                off();
            } else {
                System.out.println("听不懂");
            }
        }
    
        private void on(){
            light.on();
            tv.on();
        }
    
        private void off(){
            light.off();
            tv.off();
        }
    }
    
    // 子系统
    public class Light {
        public void on(){
            System.out.println("开灯");
        }
    
        public void off(){
            System.out.println("关灯");
        }
    }
    
    public class Tv {
        public void on(){
            System.out.println("开电视");
        }
    
        public void off(){
            System.out.println("关电视");
        }
    }
    
  • 优缺点

    • 优点
      • 代码独立于复杂子系统
    • 缺点
      • 外观可能成为与程序中所有类都耦合的对象

6.组合模式

  • 又名整体模式,用于把一组相似对象当作一个单一的对象。组合模式依据树形结构来组合对象,用来表示部分以及整体层次,这种类型的设计模式属于结构型模式,它创建了对象组的树形结构

  • 结构

    • 抽象根节点:定义系统各层次对象的共有方法和属性,预先定义一些默认行为和属性

    • 树枝节点:定义树枝节点的行为,存储子节点,组合树枝节点和叶子节点形成一个树形结构

    • 叶子结点:叶子节点对象,其下再无分枝,是系统层次遍历的最小单位

      image-20230117134149495

  • 实现

    // 抽象根节点
    public abstract class MenuComponent {
        protected String name ;
    
        protected  int level;
    
        public void  add(MenuComponent menuComponent){
            throw new UnsupportedOperationException();
        }
    
        public void remove(MenuComponent menuComponent){
            throw new UnsupportedOperationException();
        }
    
        public MenuComponent getChild(int index){
            throw new UnsupportedOperationException();
        }
    
        public String getName(){
            return name;
        }
    
        public abstract void print();
    }
    
    // 树枝节点
    public class Menu extends MenuComponent {
    
        List<MenuComponent> menuComponentList = new ArrayList<>();
    
        public Menu(String name, int level) {
            super.name = name;
            super.level = level;
        }
    
        @Override
        public void add(MenuComponent menuComponent) {
            menuComponentList.add(menuComponent);
        }
    
        @Override
        public void remove(MenuComponent menuComponent) {
            menuComponentList.remove(menuComponent);
        }
    
        @Override
        public MenuComponent getChild(int index) {
            return menuComponentList.get(index);
        }
    
        @Override
        public void print() {
            for (int i = 0; i < level; i++) {
                System.out.print("-");
            }
            System.out.println(name);
    
            for (MenuComponent menuComponent : menuComponentList) {
                menuComponent.print();
            }
        }
    }
    
    // 叶子结点
    public class MenuItem extends MenuComponent {
    
        public MenuItem(String name, int level) {
            super.name = name;
            super.level = level;
        }
    
        @Override
        public void print() {
            for (int i = 0; i < level; i++) {
                System.out.print("-");
            }
            System.out.println(name);
        }
    }
    
  • 优缺点

    • 优点
      • 利用多态和递归机制更方便地使用复杂树结构
      • 开闭原则 无需更改现有代码, 你就可以在应用中添加新元素, 使其成为对象树的一部分
    • 缺点
      • 对于功能差异较大的类,提供公共接口或许会有困难,在特定情况下,你需要过度一般化组件接口,使其变得令人难以理解。

7.享元模式

  • 运用共享技术来有效地支持大量细粒度对象的复用,通过共享已经存在的对象来大幅度减少需要创建的对象数量、避免大量相似对象的开销,从而提高系统资源的利用率

  • 结构

    • 享元模式中存在两种状态:

      • 内部状态:不会随着环境的改变而改变的可共享部分
      • 外部状态:随环境改变而改变的不可以共享的部分,享元模式的实现要领就是区分应用中的这两种状态,并将外部状态外部化
    • 抽象享元角色:通常是一个接口或抽象类,在抽象享元类中声明了具体享元类公共的方法,这些方法可以向外界提供享元对象的内部数据,同时也可以通过这些方法来设置外部数据

    • 具体享元:实现抽象享元类,称为享元对象,在具体享元类中为内部状态提供了存储空间,通常我们可以结合单例模式来设计具体享元类,为每一个具体享元类提供唯一的享元对象

    • 非享元:并不是所有的抽象享元类的子类都需要被共享,不能被共享的子类可设计为非共享具体享元类,当需要一个非共享具体享元类的对象时可以直接通过实例化创建

    • 享元工厂:负责创建和管理享元角色,当客户对请求一个享元对象时,享元工厂检查系统中是否存在符合要求的享元对象,如果存在则提供给角色,如果不存在则创建一个新的享元对象

      image-20230117150820688

优缺点

  • 优点
    • 程序中有很多相似对象, 那么你将可以节省大量内存
  • 缺点
    • 需要牺牲执行速度来换取内存, 因为他人每次调用享元方法时都需要重新计算部分情景数据

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

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

相关文章

小程序API

小程序APIapi介绍api类型示例小程序api-网络请求示例合法域名npm基础应用核心步骤npm下载vant-weapp组件库核心步骤api介绍 小程序开发中&#xff0c;会使用到很多内置的功能&#xff0c;这些功能都被封装到小程序的api中了。比如 弹出提示框发送网络请求等上传文件、下载文件…

centos的官网下载和vm16虚拟机安装centos8【保姆级教程图解】

centos8的官网下载和vm16虚拟机安装centos8【保姆级图解】centos下载vm虚拟机安装centos可能出现的问题vcpu-0centos下载 centos官网&#xff1a;https://www.centos.org/ 进入官网后&#xff0c;点击Download 选择 Centos Stream 8 x86_64,并且点击进入 然后会出现国内的…

穿越寒冬 向新而行 | 智和信通2022年度年终总结大会圆满落幕

岁序更迭&#xff0c;新程再启&#xff0c;2022年在挑战与成就中谢幕。日迈月征&#xff0c;朝暮轮转&#xff0c;2023年在希望中启航。2023年1月13日&#xff0c;北京智和信通技术有限公司&#xff08;以下简称“智和信通”&#xff09;召开2022年度年终总结大会。会议全面总结…

Tp5 通过crontab 执行定时任务

声明&#xff1a;此处为ThInkCmf 为例&#xff1a;在主题中的command 中新建php文件如图在PHP文件中设置脚本名称及注释&#xff0c;并编写业务逻辑。protected $output ;/*** 作者&#xff1a;执着* 说明&#xff1a;定义脚本名称及添加注释* param setName:定义脚本名称* pa…

【Python百日进阶-数据分析】Day227 - plotly的子图

文章目录一、Plotly 图形工厂子图1.1 垂直图形工厂图表1.2 水平表格和图表1.3 垂直表格和图表二、表格和图表子图三、地理子图四、混合子图和 Plotly Express一、Plotly 图形工厂子图 Plotly 的 Python API 包含一个图形工厂模块&#xff0c;其中包含许多包装函数&#xff0c;…

可执行文件的装载

装载方式回顾一下操作系统的知识&#xff0c;程序执行的时候需要的指令和数级都必须在内存中时&#xff0c;程序才能正常运行&#xff0c;最简单的方式就是将指令和数级全部加载到内存中&#xff0c;这样肯定可以顺利执行&#xff0c;但这样的方式对内存大小来说是一个考验。因…

python中的socket网络编程

目录 一.服务端开发 1.什么是Socket网络编程 2.基于Socket完成服务端程序开发 步骤 演示 二.客户端开发 步骤 演示 一.服务端开发 1.什么是Socket网络编程 socket(简称套接字)是进程之间通信一个工具&#xff0c;好比现实生活中的插座,所有的家用电器要想工作都是基于…

Git系列:入门必备指令详解

Git系列&#xff1a;入门必备指令详解总览高频指令参考资料总览 常用指令使用流程如下图&#xff1a; workspace&#xff1a;工作区staging area&#xff1a;暂存区/缓存区local repository&#xff1a;版本库或本地仓库remote repository&#xff1a;远程仓库 ——引用自&…

线程学习笔记

线程 出现原因 MP3多个模块放在一个进程中&#xff0c;CPU处理能力&#xff0c;播放可能不连续&#xff1b;放在多个进程中&#xff0c;资源传递、进程维护等开销很大 进程相比于进程&#xff0c;地址空间直接共享 定义 线程是进程的执行流程&#xff0c;除了线程&#xf…

WPF之调用Iconfont

一、调用iconfont 1、首先再Iconfont中新建一个项目&#xff0c;注意修改font family 2、将在线的icon添加到项目中 3、下载安装包到本地 4、更改本地的fontfamily格式如下‘./路径文件夹名/#***’ ***是指再iconfont中的fontfamily 注意如果显示为口 可能是路径不对 如果…

数据结构——栈和队列

目录 一、栈&#xff08;Stack&#xff09; 1、定义 2、顺序结构模拟实现栈和常用方法 &#xff08;1&#xff09;.栈的顺序存储 &#xff08;2&#xff09;.基本方法 3、栈的链式结构与顺序结构对比 &#xff08;1&#xff09;.对比 4、区分概念 &#xff08;1&#x…

JavaScript 库之 vanilla-tilt(一个平滑的 3D 倾斜库)

JavaScript 库之 vanilla-tilt&#xff08;一个平滑的 3D 倾斜库&#xff09;参考获取vanilla-tilt特点使用示例使用1. data-tilt2. VanillaTilt.init()优先级示例配置选项其他参考 项目描述GitHub前往Vanilla-tilt.js前往 获取 Vanilla-tilt.jsGitHubnpm npm install vanil…

【开发环境】JRE 裁剪 ② ( 裁剪 bin 目录下的 dll 动态库文件 | 压缩 rt.jar 文件 )

文章目录一、裁剪 lib 目录下的 jar 文件二、压缩 rt.jar 文件参考博客 : 精简jre1.8精简jre步骤裁剪JRE(嵌入式设备的java环境移植) 资源下载地址 ( 本篇博客的资源快照 , 不是最终版的裁剪效果 ) : https://download.csdn.net/download/han1202012/87389091 JRE 裁剪分为三…

Pytorch深度学习【十五】

微调 网络架构 一个神经网络一般可以分成两块 特征抽取将原始像素变成容易线性分割的特征线性分类器来做分类 微调 思路—将相同功能的网络及其参数直接进行迁移使用&#xff0c;而并不是通过重新学习&#xff0c;只改变部分层次即可 训练 是一个目标数据集上的正常训练任务…

老杨说运维 | 2023,浅谈智能运维趋势(二)

&#xff08;文末附视频&#xff0c;一键观看精彩内容&#xff09; 前言&#xff1a; 上文提到了智能运维现状中的变化趋势以及 上文提到了智能运维现状中的变化趋势以及过往误区&#xff0c;老杨认为智能运维的体系化建设还需从抓牢数据治理为起点&#xff0c;以终为始做好规…

miniconda虚拟环境安装使用jupyter notebook及相关

一、安装jupyter 1创建miniconda虚拟环境。&#xff08;前面文章讲过了&#xff09; 2在创建的虚拟环境下&#xff0c;conda install ipython jupyter 3在该环境下执行jupyter notebook。 注意&#xff1a;此时打开的jupyter notebook内核Python 3(ipykernel)对应该虚拟环境&am…

数据安全治理 1

数据安全治理应以数据为中心&#xff0c;多元化主体共同参与&#xff0c;兼顾发展与安全。 数据安全总体视图&#xff0c;包含了体系&#xff0c;维度&#xff0c;目标&#xff0c;实践。 制度建设 技术体系&#xff0c;如加密、脱敏等手段&#xff0c;进行数据全生命周期的管…

盘点:2022年豆瓣评分8.0以上的计算机书籍有哪些?

2022年已经结束 &#xff0c;小编来盘点一下过去一年里出版的计算机图书里&#xff0c;有哪些计算机书籍是豆瓣评分8.0以上图书。 1、人工智能&#xff1a;现代方法&#xff08;第4版&#xff09;&#xff08;上下册&#xff09; ​ 系统性总结人工智能的方方面面&#xff0c;…

寒假每日一题2023——4261. 孤独的照片

写在前面 题目来源&#xff1a;AcWing 寒假每日一题2023活动 链接&#xff1a;https://www.acwing.com/problem/content/description/4264/ 题目 Farmer John 最近购入了 N 头新的奶牛&#xff0c;每头奶牛的品种是更赛牛&#xff08;Guernsey&#xff09;或荷斯坦牛&#x…

论文解读12——NGBoost: Natural Gradient Boosting for Probabilistic Prediction

目录1、文章贡献2、评分规则3、自然梯度4、自然梯度提升算法NGBoost1、文章贡献 由吴恩达团队提出的NGBoost是一种通过梯度提升进行概率预测的算法&#xff0c;与经典的回归模型返回一个点估计结果不同&#xff0c;概率回归模型返回全概率分布&#xff0c;将条件分布的参数视为…