设计模式——结构型模型

一:目录
1. 装饰者模式(Decorator)
2. 代理模式(Proxy)
3. 组合模式(Composite)
4. 桥接模式(Bridge)
5. 适配器模式(Adapter)
6. 蝇量模式(Flyweight)
7. 外观模式(Facade)

二:详细介绍

2.1 装饰者模式(Decorator)
2.1.1 简介:
动态的给一些对象增加一些额外的职责。采用组合的方式,比继承更为灵活。
应用场景:
问题:你从何处来,要到哪里去,能够解决什么样的问题,有什么样的应用场景,和别的模式有什么区别?
2.1.2 类图:

在这里插入图片描述
1. 组件接口:

public interface Component
{void operation();
}

2. 组件实现类:

public class ConcreteComponent implements Component
{public void operation(){// Write your code here}
}

3. 装饰器接口:

interface Decorator {void operation();
}

4. 装饰器实现类:

class ConcreteDecorator implements Decorator{private Component component;public void operation(){//addBehavior也可以在前面component.operation();addBehavior();}private void addBehavior(){//your code}
}

2.1.4 实例:
Java IO设计,就用到了装饰者模式,见上边的类图(PS:拓展,看看NIO)

2.2 代理模式(Proxy)
2.2.1 简介:
代理模式(Proxy)与装饰者模式(Decorator)的区别:
装饰模式是新增行为,代理模式是控制访问

2.2.2 类图:
在这里插入图片描述

2.2.3 代码:

简单静态模式代码:

public class ProxyDemo {public static void main(String args[]){Subject subject = new RealSubject();Proxy p = new Proxy(subject);p.request();}
}
interface Subject {void request();
}
class RealSubject implements Subject{public void request(){System.out.println("request");}
}
class Proxy implements Subject{private Subject subject;public Proxy(Subject subject){this.subject = subject;}public void request(){System.out.println("PreProcess");subject.request();System.out.println("PostProcess");}
}

实例

Java动态代理(只能代理接口):

interface UserDao {void drink();
}
class UserImpl implements UserDao {@Overridepublic void drink() {System.out.println(getClass().getName() + " drink.");}
}
class UserProxy implements InvocationHandler {private UserDao userDao;public UserProxy(UserDao userDao) {this.userDao = userDao;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args)throws Throwable {this.beforeDrink();userDao.drink();this.afterDrink();return null;}public void beforeDrink() {System.out.println(getClass().getName() + " beforeDrink.");}public void afterDrink() {System.out.println(getClass().getName() + " afterDrink.");}
}public class ProxyClient {public static void main(String[] args) {UserDao userDao = new UserImpl();UserProxy userProxy = new UserProxy(userDao);UserDao userDaoProxy = (UserDao) Proxy.newProxyInstance(userDao.getClass().getClassLoader(), userDao.getClass().getInterfaces(), userProxy);userDaoProxy.drink();}
}

Java Cglib代理:
Cglib代理可以代理类,广泛的应用在Spring AOP、日志记录里
Cglib包的底层是用字节码处理框架ASM来转换字节码并生成新的子类
代理的类不能是final,否则会报错;目标对象的方法为final/static,那么就不会拦截

class User {public void eat() {System.out.println(this.getClass().getName() + " is eating!");}
}class ProxyFactory implements MethodInterceptor {private Object target;public ProxyFactory(Object target) {this.target = target;}public Object getProxyInstance() {//1.工具类Enhancer en = new Enhancer();//2.设置父类en.setSuperclass(target.getClass());//3.设置回调函数en.setCallback(this);//4.创建子类(代理对象)return en.create();}@Overridepublic Object intercept(Object paramObject, Method method, Object[] args,MethodProxy paramMethodProxy) throws Throwable {System.out.println(this.getClass().getName() + " before proxy.");Object returnValue = method.invoke(target, args);System.out.println(this.getClass().getName() + " after proxy.");System.out.println("返回结果:" + returnValue);return null;}}public class CglibDynamicProxyClient {public static void main(String[] args) {User user = new User();User proxyUser = (User) new ProxyFactory(user).getProxyInstance();proxyUser.eat();}
}

Java远程代理:

在这里插入图片描述

虚拟代理:
使用虚拟代理的场景:
(1) 由于对象本身的复杂性或者网络等原因导致一个对象需要较长的加载时间,此时可以用一个加载时间相对较短的代理对象来代表真实对象。
(2) 当一个对象的加载十分耗费系统资源的时候,也非常适合使用虚拟代理。为节省空间,可以延迟加载。

缓冲代理:
使用缓冲代理的作用:
(1) 它为某一个操作的结果提供临时的缓存存储空间,以便在后续使用中能够共享这些结果,从而可以避免某些方法的重复执行,优化系统性能。

保护代理:
使用保护代理的作用:
(1) 保护代理可以控制对一个对象的访问权限,为不同用户提供不同级别的使用权限。

2.3 组合模式(Composite)

2.3.1 简介:
组合模式定义了如何将容器对象和叶子对象进行递归组合,使得客户在使用的过程中无需进行区分,可以对他们进行一致的处理。
有一个应用场景为文件夹的遍历。
优点:
1. 可以清楚地定义分层次的复杂对象,表示对象的全部或部分层次,使得增加新构建也更容易。
2. 客户端使用简单,客户端可以一致的使用组合结构或其中单个对象。
3. 定义了包含叶子对象和容器对象的类层次结构,叶子对象可以被组合成更复杂的容器对象,而这个容器对象又可以被组合,不断递归,可以形成复杂的树状结构,就像文件夹系统一样。
4. 使得在组合体内加入对象构建更加容易,客户端不必因为加入了新的对象构建而更改原有代码

缺点:
1. 使得设计变得更加抽象,对象的业务逻辑如果很复杂,则实现难度会很大,并且不是所有的方法都与叶子对象子类有关联

使用场景:
1. 组合模式用于将多个对象组合成树状结构以表示“整体-部分”的结构层次。组合模式对单个对象(叶子对象)和组合对象(容器对象)的使用具有一致性
2. 组合对象的关键在于它定义了一个抽象构建类,它既可以表示叶子对象,也可以表示容器对象,客户仅需要对这个抽象构建进行编程,无论是叶子还是容器对象,都一致对待

2.3.2 类图:

在这里插入图片描述

2.3.3 代码:
PS:上面的类图用的是接口,下面用的是虚类,道理是一样的。

abstract class File {String name;abstract void display();
}
class ImageFile extends File {public ImageFile(String name) {this.name = name;}@Overridevoid display() {System.out.println(getClass().getName() + " " + name + " display.");}
}class TextFile extends File {public TextFile(String name) {this.name = name;}@Overridevoid display() {System.out.println(getClass().getName() + " " + name + " display.");}
}class Folder extends File {private List<File> files ;public Folder(String name) {this.name = name;files = new ArrayList<>();}@Overridevoid display() {for(File file : files) {file.display();}}public void addFile(File file) {files.add(file);}public void deleteFile(File file) {files.remove(file);}
}public class CompositeClient {public static void main(String[] args) {File image = new ImageFile("Image");File text = new TextFile("Text");Folder folder = new Folder("folder");Folder subFolder = new Folder("subFolder");File subImage = new ImageFile("subImage");File subText = new TextFile("subText");folder.addFile(image);folder.addFile(text);folder.display();folder.addFile(subFolder);subFolder.addFile(subImage);subFolder.addFile(subText);folder.display();}}

2.4 桥接模式(Bridge)

2.4.1 简介:
桥梁模式是对象的结构模式。又称为柄体(Handle and Body)模式(注:水杯的杯柄与杯子的关系)或接口(Interface)模式
桥梁模式的用意是:将抽象化(Abstraction)与实现化(Implementation)脱耦,使得二者可以独立的变化。
通过组合的方式,使重复逻辑以及类的数量最小化,更加方便扩展。
优点:
分离抽象、实现部分,极大的提供了系统的灵活性。

抽象化:从众多的事物中,抽取出共同的、本质的特征,而舍弃其非本质的特征,就是抽象化。在抽象中,同与不同,取决于从哪个角度进行抽象,而角度取决于分析问题的目的。

实现化:抽象化给出的具体实现,就是实现化。
一个类的实例就是类的实例化,一个具体自雷就是他的抽象超类的实例化。

耦合:指的是两个实体行为的某种强关联。而将他们的强关联去掉,就是耦合的解脱,或称脱耦。
在这里,脱耦是指将抽象化与实现化之间的耦合解脱开,或者说将他们的强关联改成弱关联。

在这里插入图片描述

上图两个层级结构:
1. 由抽象化角色和修正抽象化角色组成的抽象化等级结构
2. 由实现化角色和两个具体实现化角色所组成的实现化等级结构

涉及到的角色:
抽象化(Abstraction)角色:抽象化给出的定义,并保存一个对实现化对象的引用
修正抽象化(RefinedAbstraction)角色:扩展抽象化角色,改变和修正父类对抽象化的定义
实现化角色(Implementor):这个角色给出实现化角色的接口,但不给出具体的实现。一般,实现化角色只给出底层的操作,而抽象化角色给出更高一层的操作
具体实现化角色(ConcreteImplementor):这个角色给出实现化角色接口的具体实现

桥梁模式的应用实例

在这里插入图片描述

2.5 适配器模式(Adapter)
2.5.1 简介
适配器模式把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配无法一起工作的两个类能协同工作
适配器模式里有一种缺省适配器,应用比较广泛。他是为了方便建立一个不平庸的适配器类而提供的一种平庸实现。
2.5.2 类图

在这里插入图片描述

2.6 蝇量模式(Flyweight)
2.6.1简介:
享元模式(Flyweight Pattern):运用共享技术有效的支持大量细粒度对象的复用。系统只使用少量的对象,而这些对象都很相似,状态变化很小,可以实现对象的多次复用。由于享元模式要求能够共享的对象必须是细粒度对象,因此它又被称为轻量级模式,它是一种对象结构型模式。
Flyweight(抽象享元类):通常是一个接口或抽象类,其中生命了具体想元类公共的方法
ConcreteFlyweight(具体享元类):实现了抽象想元类,实例被称为享元对象;通常结合单例模式来设计具体享元类,为每一个具体享元类提供唯一的享元对象。
UnsharedConcreteFlyweight(非共享具体享元类):并不是抽象想元类的子类都要被共享,不能被共享的子类可设计为此;
FlyweightFactory(享元工厂类):享元工厂类用于创建并管理享元对象,提供一个享元对象的享元池。一般设计为单例模式
2.6.1类图:

在这里插入图片描述

2.6.1应用实例:
Java的String类设计就用了Flyweight模式.String对象为final,内部char[]存储在常量池里

2.7 外观模式(Facade)

2.7.1简介:
通过引入一个外观角色来简化客户端与子系统之间的交互,为复杂的子系统调用提供一个统一的入口,降低子系统与客户端的耦合度,且方便客户端调用

2.7.2结构图:

在这里插入图片描述

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

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

相关文章

利用Helm简化Kubernetes应用部署(1)

目录利用Helm简化Kubernetes应用部署 Helm基础 安装Helm 使用Visual Studio 2019为Helm编写一个简单的应用 利用Helm简化Kubernetes应用部署Helm是Kubernetes生态系统中的一个软件包管理工具&#xff0c;有点类似于Linux操作系统里面的“apt-get”和“yum”。结合上一节内容&am…

设计模式——行为型模式

一&#xff1a;目录 1. 策略模式&#xff08;Strategy&#xff09; 2.状态模式&#xff08;State&#xff09; 3.责任链模式&#xff08;Chain Of Responsibility&#xff09; 4.解释器模式&#xff08;Interpreter&#xff09; 5.命令模式&#xff08;Command&#xff09; 6.观…

网络编程——常用协议解析

** 1、网络基础知识 ** 1.1> 什么是OSI模型 OSI 模型(Open System Interconnection model)是一个由国际标准化组织?提出的概念模型,试图?供一个使各种不同的计算机和网络在世界范围内实现互联的标准框架。 它将计算机网络体系结构划分为七层,每层都可以提供抽象良好的…

在 ABP vNext 中编写仓储单元测试的问题一则

一、问题新项目是基于 ABP vNext 框架进行开发的&#xff0c;所以我要求为每层编写单元测试。在同事为某个仓储编写单元测试的时候&#xff0c;发现了一个奇怪的问题。他的对某个聚合根的 A 字段进行了更新&#xff0c;随后对某个导航属性 B 也进行了变更&#xff0c;最后通过仓…

TCP协议——三次握手与四次关闭

1. TCP协议基础 网络编程基础见&#xff0c;传送门 TCP是面向连接的&#xff0c;无论哪一方向另一方发送数据之前&#xff0c;都必须先在双方之间建立一条连接。 在TCP/IP协议中&#xff0c;TCP协议提供可靠的连接服务&#xff0c;连接是通过三次握手进行初始化的。 三次握手…

TCP协议——流量控制和拥塞控制

** 一、流量控制 ** 1.1 什么是流量控制 Sender won’t overflow receiver’s buffer by transmitting too much, too fast. &#xff08;防止发送方发的太快&#xff0c;耗尽接收方的资源&#xff0c;从而使接收方来不及处理&#xff09; 1.2 流量控制的一些知识点 &#x…

征集.NET中国峰会议题

月初做的调查《》&#xff0c;参与人数576人&#xff0c;愿意参与分享.NET Core经验的142人&#xff0c;今天发起分会场主题演讲和闪电演讲议题.2014年微软组织成立.NET基金会&#xff0c;微软在成为主要的开源参与者的道路上又前进了一步。2014年以来已经有众多知名公司加入.N…

TCP协议——粘包与拆包

TCP的基础 TCP协议基础&#xff0c;传送门 TCP协议流量控制&#xff0c;传送门 1.1 什么是TCP粘包/拆包 TCP是个“流”协议&#xff0c;所谓流&#xff0c;就是没有界限的一串数据。大家可以想想河里的流水&#xff0c;是连成一片的&#xff0c;其间并没有分界线。TCP底层并…

你的通勤时间都去哪了?

大家好&#xff0c;我是Z哥。今天我来唠叨一下。最近无意间看到一份报告&#xff0c;关于我们职场人士上下班通勤时间的。有时候想想也挺无奈的&#xff0c;我们越想去发达一些的城市打拼&#xff0c;反而越被通勤这种琐碎的事情给耽误更多的奋斗时间。但是没办法&#xff0c;在…

规模化敏捷必须SAFe

引子&#xff1a;规模化敏捷转型从来不是一件容易的事情。当只有1-2个敏捷团队进行协同的时候&#xff0c;计划和工作同步是可控的。团队和产品负责人互相聊一聊&#xff0c;基本就能搞清楚需要做什么&#xff0c;一个简单的SOS架构&#xff08;Scrum of Scrums&#xff09;就能…

http1.0 http1.1 http2 之间的区别

一、HTTP基础 1.1 HTTP定义 HTTP协议&#xff08;HyperTextTransferProtocol&#xff0c;超文本传输协议&#xff09;是用于从WWW服务器传输超文本到本地浏览器的传输协议。 1.2 HTTP发展史 1.3 HTTP1.0 早先1.0的HTTP版本&#xff0c;是一种无状态、无连接的应用层协议。 …

漫画:程序员一时单身一时爽,一直单身...有点惨

1妹子没吃早饭早啊敲哥&#xff0c;你在吃早饭啊嗯啊&#xff0c;你吃了吗&#xff1f;没呢&#xff0c;早上实在是太赶了&#xff0c;没来得及嗯...那我还是换个地方吃吧免得馋着你。。。2代码重要还是女朋友重要女朋友能哄好&#xff0c;代码能哄好吗&#xff1f;写代码是赚钱…

AutoMapper多个对象映射到一个Dto对象

一、定义源映射对象为了体现AutoMapper映射特性&#xff0c;在SocialAttribute中的Name属性没有定义在People中&#xff0c;People的Ear属性也不存在与SocialAttribute和PhysicalAttribute中。代码如下&#xff1a;二、注入AutoMapper例子中使用的IOC容器是Autofac&#xff0c;…

cookie 与 session

1 背景介绍 什么是会话&#xff1f; 用户打开一个浏览器, 点击多个超链接, 访问服务器多个web资源, 然后关闭浏览器, 整个过程称之为一个会话。我们知道&#xff0c;HTTP协议是一种"无状态"协议&#xff0c;客户浏览器与服务器建立连接&#xff0c;发出请求&#x…

Java写一个简单的静态文件的HTTP服务器(基于Socket)

** 一、实现思路 ** 1、使用 ServerSocket 监听某一端口&#xff0c;然后等待连接获取 Socket对象。 2、创建一个类 HttpServer 继承 java.lang.Thread 类&#xff0c;重写 run()方法&#xff0c;执行浏览器请求。 3、获得浏览器请求&#xff0c;解析资源文件路径。 4、读…

asp.net core 使用HttpClientFactory Polly实现熔断降级

前言在NET Core2.1后也是增加更新了很多东西,当然HttpClientFactory更新中的一部分.虽然说HttpClient这个实现了disposable,但使用它的时候用using包装块的方式通常不是最好的选择。处理HttpClient,底层socket套接字不会立即释放。该HttpClient类是未多个请求重复使用而创建的。…

Azure Application Insights REST API使用教程

本文是Azure Application Insights REST API的简单介绍&#xff0c;并会包含一个通过Python消费API的示例/小工具。新加入的team中的一项工作是制作日常的运维报表&#xff0c;制作方式是手工前往portal.azure.com&#xff0c;在网页中多次执行不同的查询语句、导出excel&#…

用Java Socket实现SMTP邮件发送

目录&#xff1a; 1、邮件基础概念2、Java Mail API介绍3、收发邮件代码示例 PS&#xff1a;如果你想直接拿代码用&#xff0c;可以直接跳到第3部分。 ** 一、邮件基础概念 ** 1.1 邮件服务器和电子邮箱 要在Internet上提供电子邮件功能&#xff0c;必须有专门的电子邮件…

微软开源新字体Cascadia Code,源于Windows Terminal

微软开源了一套新的字体 Cascadia Code。Cascadia Code 是微软在 5 月份的 Build 大会上宣布推出的等宽字体&#xff0c;微软介绍它是与新的终端 Windows Terminal 一起开发的&#xff0c;官方建议将其与终端应用和 VS、VS Code 等文本编辑器一起使用。Cascadia Code 为命令行和…

进程间通讯的7种方式

1、常见的通信方式 管道pipe&#xff1a;管道是一种半双工的通信方式&#xff0c;数据只能单向流动&#xff0c;而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。命名管道FIFO&#xff1a;有名管道也是半双工的通信方式&#xff0c;但是它允许无亲缘…