《HeadFirst设计模式》笔记(下)

news2025/1/12 8:23:53

11 代理模式

代理要做的就是控制和管理访问。
你的客户对象所做的就像是在做远程方法调用,但其实只是调用本地堆中的“代理”对象上的方法,再由代理处理所有网络通信的低层细节。
在这里插入图片描述
在这里插入图片描述

Java的RMI提供了客户辅助对象和服务辅助对象,为客户辅助对象创建和服务对象相同的方法。RMI的好处在于你不必亲自写任何网络或I/O代码。客户程序调用远程方法(即真正的服务所在)就和在运行在客户自己的本地JVM上对对象进行正常方法调用一样。
RMI将客户辅助对象称为stub(桩),服务辅助对象成为skeleton(骨架)。

在这里插入图片描述

定义代理模式

代理模式为另一个对象提供一个替身或占位符以控制对这个对象的访问。

public class NonOwnerInvocationHandler implements InvocationHandler {
	PersionBean person;
	
	public NonOwnerInvocationHandler(PersionBean person) {
		this.person = person;
	}
	
	public Object invoke(Object proxy, Method method, Object[] args) throws IllegalAccessException {
		try{
			if(method.getName().startsWith("get")){
				return method.invoke(person, args);
			} else if(method.getName().equals("setHotOrNotRating")){
				return method.invoke(person, args);
			} else if(method.getName().startsWith("set")) {
				return IllegalAccessException();
			}
		} catch(InvocationTargetException e) {
			e.printStackTrace();
		}
		return null;
	}
}
PersionBean getNonOwnerProxy(PersionBean person) {
	return (PersionBean) Proxy.newProxyInstance(
			person.getClass().getClassLoader(),
			person.getClass().getInterfaces(),
			new NonOwnerInvocationHandler(person));
}

在这里插入图片描述
真实世界中还有很多代理:
在这里插入图片描述
在这里插入图片描述

12 复合模式(模式的模式)

模式通常被一起使用,并被组合在同一个设计解决方案中。复合模式在一个解决方案中结合两个或多个模式,以解决一般或重复发生的问题。

在这里插入图片描述

在这里插入图片描述

public class QuackCounter implements Quackable {
	Quackable duck;
	static int numberOfQuacks;
	//Observable observable;
	
	public QuackCounter(Quackable duck) {
		this.duck = duck;
		observable = new Observable(this);
	}
	public void quack() {
		duck.quack();
		numberOfQuacks++;
		//notifyObservers();
	}
	public static int getQuacks(){
		return numberOfQuacks;
	}
	public void registerObserver(Observer observer) {
		duck.registerObserver(observer);
	}
	public void notifyObservers() {
		duck.notifyObservers();
	}
}

注:Observable表示被观察者类,Observer表示观察者类。

在这里插入图片描述

public class Flock implements Quackable {
	ArrayList ducks = new ArrayList();
	public void add(Quackable duck) {
		ducks.add(duck);
	}
	
	public void quack() {
		Iterator iterator = ducks.iterator();
		while(iterator.hasNext()) {
			Quackable duck = (Quackable)iterator.next();
			duck.quack();
		}
	}
	public void registerObserver(Observer observer) {
		Iterator iterator = ducks.iterator();
		while(iterator.hasNext()) {
			Quackable duck = (Quackable)iterator.next();
			duck.registerObserver(observer);
		}
	}
	public void notifyObservers() {}
}

在这里插入图片描述

在这里插入图片描述
复合模式之王
复合模式:Model-View-Controller,MVC。

在这里插入图片描述
MVC是由数个设计模式结合起来的模式,当你通过研究设计模式来学习MVC时,突然之间它开始变得清晰明了。

在这里插入图片描述
具体来说,MVC涉及下面的设计模式:
在这里插入图片描述
在这里插入图片描述

Model 2是MVC在Web上的调整:
观察者和策略都隐藏起来了,但实际上还是有的。
在这里插入图片描述

复合模式结合两个或以上的模式,组成一个解决方案,解决一再发生的一般性问题。

13 与设计模式相处

定义设计模式

模式是在某情境(context)下,针对某问题的某种解决方案。
第一个也是最权威的设计模式目录是《设计模式:可复用面向对象软件的基础》,由 Gamma、Helm、Johnson 和 Vlissides(Addison Wesley 出版社)所著。这个目录阐述了23个基本的设计模式。

如何当一个设计模式模式的作家?

  • 做好家庭作业。发掘新模式之前,你必须先精通现有的模式。许多模式看起来像是全新的,但是事实上只是现有模式的变种。通过研究现有的模式,你可以比较容易地识别模式,并且学会将某一模式与其他模式联系起来。
  • 花时间反思与评估。
  • 将你的想法写在纸上,好让其他人能够理解。
  • 让其他人使用你的模式,然后再持续改进。
  • 不要忘了三次规则。除非你的模式已经再真实世界的三个方案中被成功地采用了,否则就不够资格被当成模式。
    我画的:

在这里插入图片描述
迭代器:在对象的集合之中游走,而不暴露集合的实现。
工厂方法:由子类决定要创建的具体类是哪一个。
组合:客户用一致的方式处理对象集合和单个对象。
抽象工厂:允许客户创建对象的家族,而无需指定他们的具体类。

答案:
在这里插入图片描述

根据模式目标分为三个不同的类目:创建型、行为型和结构型。
在这里插入图片描述
反模式告诉你如何采用一个不好的解决方案解决一个问题。

原本的解决方案:
反正就使用熟悉的技术好了。将熟悉的技术强迫性地用在许多问题上,甚至在明显不适当地地方也照用。
重构的解决方案:
开发人员通过教育、培训和读书会,可以学会新的解决方案。

剩下的模式

还有一些不太常用的模式。

桥接

桥接:使用桥接模式不只改变你的实现,也改变你的抽象。
在这里插入图片描述
现在你有了两个层次结构,其中一个是遥控器,而另一个是平台特定的电视机实现。有了桥接的存在,你就可以独立地改变这两个层次。
在这里插入图片描述

生成器

生成器:使用生成器模式封装一个产品地构造过程,并允许按步骤构造。
我们将旅游规划的创建过程,封装到一个对象中(此对象被称为生成器),然后让客户调用生成器为它创建旅游计划。
在这里插入图片描述

在这里插入图片描述

责任链

责任链:当你想要让一个以上的对象有机会能够处理某个请求的时候,就使用责任链模式(Chain of Responsibility Pattern)。
在这里插入图片描述
在这里插入图片描述

蝇量模式

蝇量模式:如想让某个类的一个实例能用来提供许多“虚拟实例”,就使用蝇量模式。
只用一个树实例和一个客户对象来维护“所有”树的状态。
在这里插入图片描述

// TreeManager.java
public class TreeManager {
    private Tree[][] treeArray;

    public TreeManager(int rows, int cols) {
        this.treeArray = new Tree[rows][cols];
    }

    public void displayTrees() {
        for (int i = 0; i < treeArray.length; i++) {
            for (int j = 0; j < treeArray[i].length; j++) {
                if (treeArray[i][j] != null) {
                    treeArray[i][j].display(i, j, calculateAge(i, j));
                }
            }
        }
    }

    private int calculateAge(int x, int y) {
        // 示例:假设树龄是基于位置的简单计算
        return x + y;
    }
}

// Tree.java
public class Tree {
    public void display(int x, int y, int age) {
        System.out.println("Displaying tree at (" + x + ", " + y + ") with age " + age);
        // 这里可以添加更复杂的显示逻辑
    }
}

// 主程序
public class Main {
    public static void main(String[] args) {
        TreeManager manager = new TreeManager(3, 3);
        // 假设已经初始化了treeArray中的某些树对象
        manager.displayTrees();
    }
}

在这里插入图片描述

解释器

解释器:使用解释器模式为语言创建解释器。

在这里插入图片描述

在这里插入图片描述
要想解释这种语言,就调用每个表达式类型的interpret()方法。此方法需要传入一个上下文(Context)——也就是我们正在解析的语言字符串输入流——然后进行比对并采取适当的动作。
在这里插入图片描述

中介者

中介者:使用中介者模式来集中相关对象之间复杂的沟通和控制方式。
**中介者内包含了整个系统的控制逻辑。**当某装置需要一个新的规则时,或者是一个新的装置被加入系统内,其所有需要用到的逻辑也都被加入了中介者内。
在这里插入图片描述

备忘录

备忘录:当你需要让对象返回之前的状态时(例如,你的用户请求撤销),就使用备忘录模式。
备忘录模式两个目标:

  • 储存系统关键对象的重要状态
  • 维护关键对象的封装

在这里插入图片描述

在这里插入图片描述

原型

原型:当创建给定类的实力的过程很昂贵或很复杂时,就使用原型模式。

原型模式允许你通过复制现有的实例来创建新的实例。这个模式的重点在于,客户的代码在不知道要实例化何种特定类的情况下,可以制造出新的实例。
在这里插入图片描述

访问者

访问者:当你想要为一个对象的组合增加新的能力,且封装并不重要时,就使用访问者模式。
在这里插入图片描述

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

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

相关文章

【Uniapp-Vue3】v-if条件渲染及v-show的选择对比

如果我们想让元素根据响应式变量的值进行显示或隐藏可以使用v-if或v-show 一、v-show 另一种控制显示的方法就是使用v-show&#xff0c;使用方法和v-if一样&#xff0c;为true显示&#xff0c;为false则不显示。 二、v-if v-if除了可以像v-show一样单独使用外&#xff0c;还…

【MySQL数据库】基础总结

目录 前言 一、概述 二、 SQL 1. SQL通用语法 2. SQL分类 3. DDL 3.1 数据库操作 3.2 表操作 4. DML 5. DQL 5.1 基础查询 5.2 条件查询 5.3 聚合函数 5.4 分组查询 5.5 排序查询 5.6 分页查询 6. DCL 6.1 管理用户 6.2 权限控制 三、数据类型 1. 数值类…

ubuntu/kali安装c-jwt-cracker

1.下载安装包 可以去GitHub下载解压&#xff0c;我这直接在kali克隆下来了。&#xff08;网络不好可能克隆不下来&#xff09; git clone https://github.com/brendan-rius/c-jwt-cracker.git 2.如果下载的压缩包就需要进行解压&#xff0c;克隆的直接进入目录就好了。 unzi…

H266/VVC 帧内预测中 ISP 技术

帧内子划分 ISP ISP 技术是在 JVET-2002-v3 提案中详细介绍其原理&#xff0c;在 VTM8 中完整展示算法。ISP是线基内预测&#xff08;LIP&#xff09;模式的更新版本&#xff0c;它改善了原始方法在编码增益和复杂度之间的权衡&#xff0c;ISP 算法的核心原理就是利用较近的像…

《拉依达的嵌入式\驱动面试宝典》—计算机网络篇(二)

《拉依达的嵌入式\驱动面试宝典》—计算机网络篇(二) 你好,我是拉依达。 感谢所有阅读关注我的同学支持,目前博客累计阅读 27w,关注1.5w人。其中博客《最全Linux驱动开发全流程详细解析(持续更新)-CSDN博客》已经是 Linux驱动 相关内容搜索的推荐首位,感谢大家支持。 《…

【2024年华为OD机试】 (A卷,100分)- 对称美学(Java JS PythonC/C++)

一、问题描述 题目描述 对称就是最大的美学&#xff0c;现有一道关于对称字符串的美学。已知&#xff1a; 第1个字符串&#xff1a;R第2个字符串&#xff1a;BR第3个字符串&#xff1a;RBBR第4个字符串&#xff1a;BRRBRBBR第5个字符串&#xff1a;RBBRBRRBBRRBRBBR 相信你…

c#集成npoi根据excel模板导出excel

NuGet中安装npoi 创建excel模板&#xff0c;替换其中的内容生成新的excel文件。 例子中主要写了这四种情况&#xff1a; 1、替换单个单元格内容&#xff1b; 2、替换横向多个单元格&#xff1b; 3、替换表格&#xff1b; 4、单元格中插入图片&#xff1b; using System.IO; …

【数据库系统概论】第5章 数据库完整性【!触发器】

目录 5.1数据库完整性概述 5.2 实体完整性 5.3 参照完整性 5.4 用户定义的完整性 属性上的约束 1. 列值非空&#xff08;NOT NULL&#xff09; 2. 列值唯一&#xff08;UNIQUE&#xff09; 3. 检查列值是否满足条件&#xff08;CHECK&#xff09; 元组上的约束 5.5 完…

一键部署Netdata系统无需公网IP轻松实现本地服务器的可视化监控

文章目录 前言1.关于Netdata2.本地部署Netdata3.使用Netdata4.cpolar内网穿透工具安装5.创建远程连接公网地址6.固定Netdata公网地址 &#x1f4a1; 推荐 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。…

HBuilderX(uniapp)实现微信小程序获取用户头像、昵称、授权登录、获取用户手机号

前言&#xff1a;微信文档写的零零散散的&#xff0c;网上搜的教程&#xff0c;23年的教程还在教22年改版之前的东西&#xff0c;导致踩坑无数&#xff0c;所以自己写一下文档记录一下&#xff0c;帮助后来者&#xff0c;记录于2024.11.14 一.获取用户头像和昵称 首先阅读微信…

RabbitMQ基础(简单易懂)

什么是RabbitMQ&#xff1f; 它基于AMQP协议&#xff08;Advanced Message Queuing Protocol&#xff09;&#xff0c;一种为应用构建消息队列的标准协议。过程中&#xff0c;它提供了一些重要模块&#xff1a;为消息发送的Producer&#xff08;生产者&#xff09;&#xff0c…

【web靶场】之upload-labs专项训练(基于BUUCTF平台)

前言 该靶场&#xff0c;是通过平台BUUCTF在线评测中的靶场进行的&#xff0c;基于linux搭建的 当然若是想要该靶场&#xff0c;可以采用github上的醒目&#xff0c;点击后面文字即可访问c0ny1/upload-labs: 一个想帮你总结所有类型的上传漏洞的靶场 或者本人分享在网盘中&a…

美摄科技为企业打造专属PC端视频编辑私有化部署方案

美摄科技&#xff0c;作为视频编辑技术的先行者&#xff0c;凭借其在多媒体处理领域的深厚积累&#xff0c;为企业量身打造了PC端视频编辑私有化部署解决方案&#xff0c;旨在帮助企业构建高效、安全、定制化的视频创作平台&#xff0c;赋能企业内容创新&#xff0c;提升品牌影…

Vue3(elementPlus) el-table替换/隐藏行箭头,点击整行展开

element文档链接&#xff1a; https://element-plus.org/zh-CN/component/form.html 一、el-table表格行展开关闭箭头替换成加减号 注&#xff1a;Vue3在样式中修改箭头图标无效&#xff0c;可能我设置不对&#xff0c;欢迎各位来交流指导 转变思路&#xff1a;隐藏箭头&…

【C++入门】详解(中)

目录 &#x1f495;1.函数的重载 &#x1f495;2.引用的定义 &#x1f495;3.引用的一些常见问题 &#x1f495;4.引用——权限的放大/缩小/平移 &#x1f495;5. 不存在的空引用 &#x1f495;6.引用作为函数参数的速度之快&#xff08;代码体现&#xff09; &#x1f4…

【题解】—— LeetCode一周小结53

&#x1f31f;欢迎来到 我的博客 —— 探索技术的无限可能&#xff01; &#x1f31f;博客的简介&#xff08;文章目录&#xff09; 【题解】—— 每日一道题目栏 上接&#xff1a;【题解】—— LeetCode一周小结52 30.二叉树中的链表 题目链接&#xff1a;1367. 二叉树中的链…

Vue方法、计算机属性及侦听器

数组变化侦测 假设我们写了一个数组&#xff0c;现在想让该数组中新增一条数据,那么如何去实现呢&#xff1f; <template><h3>数组变化侦听</h3><button click"addListHandler">添加数据</button><ul><li v-for"(item…

TIOBE编程语言排行靠前的编程语言的吉祥物

Python的吉祥物&#xff1a;小蟒蛇 Python语言的吉祥物是一只名叫"Pythonidae"&#xff08;或简称"Py"&#xff09;的小蟒蛇。这个吉祥物由Tobias Kohn设计于2005年&#xff0c;它的形象借鉴了真实的蟒蛇&#xff0c;但加入了一些可爱和友善的特点。小蟒蛇…

Linux (CentOS) 安装 Docker 和 Docker Compose

&#x1f680; 作者主页&#xff1a; 有来技术 &#x1f525; 开源项目&#xff1a; youlai-mall ︱vue3-element-admin︱youlai-boot︱vue-uniapp-template &#x1f33a; 仓库主页&#xff1a; GitCode︱ Gitee ︱ Github &#x1f496; 欢迎点赞 &#x1f44d; 收藏 ⭐评论 …

Unity热更新 之 Addressables(2) 本地/远端打包 流程测试

基础篇&#xff1a;Unity热更新 之 Addressables(1) 资源基础加载-CSDN博客 基础方法来源于唐老狮,我也是初学热更这一块&#xff0c;所有不保证步骤完全正确&#xff0c;如有不足还请斧正 目录 0.前提 1.本地打包 1.1.资源放入包 1.2.简化路径名称给出标签(如有需要的话) …