当前位置: 首页 > news >正文

企业建站系统漏洞/网页制作成品

企业建站系统漏洞,网页制作成品,tomcat做网站,建湖做网站的公司一、上篇回顾 上篇我们主要讲述了简单工厂模式和工厂模式。并且分析了每种模式的应用场景和一些优缺点,我们现在来回顾一下: 简单工厂模式:一个工厂负责所有类型对象的创建,不支持无缝的新增新的类型对象的创建。 工厂模式&…

一、上篇回顾

上篇我们主要讲述了简单工厂模式和工厂模式。并且分析了每种模式的应用场景和一些优缺点,我们现在来回顾一下:

简单工厂模式:一个工厂负责所有类型对象的创建,不支持无缝的新增新的类型对象的创建。

工厂模式:多个工厂负责多个类型对象的创建,每个工厂只负责具体类型对象的创建,支持无缝的新增类型对象的创建,需要实现工厂接口类和具体的类型对象类。

我们来简单的对比下这2个模式的优缺点:

模式名称优点缺点
简单工厂模式一个工厂负责所有对象的创建,简单灵活不符合高内聚的原则,不支持无缝的扩展
工厂模式可以无缝的新增类型,每个工厂职责单一,符合高内聚的原则工厂类太多,难以维护。

工厂模式,很优雅的解决了应用程序使用对象时的无限new()的操作,同时降低了系统应用之间的耦合性,提高了系统的可维护性和适应性。

二、摘要

本文主要是针对创建型模式中的抽象工厂模式进行讲述,抽象工厂模式是在简单工厂模式的基础上扩展而成的新模式,将简单工厂中的对象的创建过程进行了很优雅的动态配置来完成无

缝的扩展,当然通过一些扩展,可以构建出可支持动态新增或者删除对象的抽象工厂模式。本文将会给出具体的实现方案,相比工厂模式,抽象工厂模式是一个工厂负责多个对象的创建,返回

的具体的类型是这个对象的抽象类型。这样,在客户端引用的时候只需要使用这个工厂返回的对象类型,抽象工厂会自动根据对象的类型动态的创建这个类型对象的实例。大体的过程如下:

image

上面的图片呢,主要是针对经典的抽象工厂模式给出了一个实现草图的模拟,而我们在实际的项目中可能并不希望给出这么多的抽象工厂工厂实现,我只想给出一个通用的抽象

工厂实现,通过静态方法直接调用,返回我想要的对象类型的实例,而且这个对象类型是可以动态配置的,那么我们如何做到呢?这就是本篇需要讨论的实现方案。本篇将会从

以下几点进行讲述抽象工厂模式:

1、抽象工厂模式的简单实例代码-这里给出的是经典的抽象工厂模式实例代码。我们从经典的实例代码中可以看出这个工厂模式的一些缺点。

2、根据经典工厂模式的缺点,我们给出改进的方案,进一步给出项目中可以使用的通用方案实现。

3、给出上篇中的通过委托来实现的工厂模式方案。

4、通过特性+反射的形式来动态的创建对象。

三、本文大纲

a、上篇回顾。

b、摘要。

c、本文大纲。

d、抽象工厂模式的特点及使用场景。

e、抽象工厂模式的实现方案。

f、抽象工厂模式使用总结。

g、系列进度。

h、下篇预告。

四、抽象工厂模式的特点及使用场景

抽象工厂可以说是三类工厂模式中使用最广泛的,也是最受大家喜爱的模式之一,因为抽象工厂模式解决了一系列相互依赖的对象或者有组合关系的对象的创建过程。举个简单的例子来

说,我们以电脑的显卡和风扇来说吧,我们知道显卡一般在玩游戏的时候,由于渲染图形会产生大量的热量,如果没有好的风扇那么可能无法达到好的散热的效果,这个时候我们可以把显卡和

风扇的创建放在一个抽象工厂中进行创建,因为这2个对象是具有依赖关系的对象,那么我们来给出这个例子的完整实例代码:

先看看2个对象类型的接口和抽象工厂的接口定义

///
/// 定义显卡抽象对象接口
///
public interface IDisplayCard
{
}

///
/// 定义显卡风扇抽象对象接口
///
public interface IDisplayFan
{
}

///
/// 定义显卡设备抽象工厂接口
///
public interface IAbstractDriveFactory
{
IDisplayCard CreateDisplayCard();

IDisplayFan CreateDisplayFan();
}

我们来看看具体类型的实现和抽象工厂的具体实现。

///
/// 定义华硕显卡的具体对象
///
public class DisplayCardAsus : IDisplayCard
{
}

///
/// 华硕显卡配套风扇
///
public class DisplayFanAsus : IDisplayFan
{
}

///
/// 华硕显卡具体实现工厂
///
public class DriveFactoryAsus : IAbstractDriveFactory
{
IDisplayCard CreateDisplayCardAsus()
{
return new DisplayCardAsus();
}

IDisplayFan CreateDisplayFanAsus()
{
return new DisplayFanAsus();
}
}

通过上面的代码,我们给出了抽象工厂的一个经典实例的实现方案,当然这不是我们开发中使用的实际形式,那么实际我们在项目中如何使用这个抽象工厂模式呢?我们一般是改进的方

案去使用这个抽象工厂模式,我们如何改进呢?对于目前的,如果我不光创建显卡设备和配套的风扇设备,我还想创建其他的类型的东西,这时候可能我们定义的抽象工厂就无法满足具有相互

依赖或者组合关系的对象类型实例的创建工作了,那么我们如何改进呢,这就是下面要讲述的几类方案。

五、抽象工厂模式的实现方案

5.1、通过配置文件来实现

  • 我们先给出基于上面的经典抽象工厂的一个改进的方案,可以支持动态配置的抽象工厂,一个工厂负责动态的创建一些列的可动态配置的对象列表,我们如何做呢,我想一提到配置。大家都知道要么是通过XML文件来实现或者是通过泛型集合来做。我们这里可以提供的方案是这样的,通过工厂初始化时从配置文件中读取配置项,构造一个字典,然后从这个字典中查询要创建的类型是否在字典中,如果在字典中存在则创建这个类型的对象,否则返回NULL,我们这里通过泛型来实现。
  • 我们来看看具体的代码实现吧:

///
/// 定义抽象工厂接口
///
public interface IAbstractFactory
{
///
/// 通用的泛型对象创建工厂
///
///
///
T Create();
}

给出具体的实现这个接口的抽象工厂类

///
/// 具体的通用工厂实现
///
public class AbstractFactory : IAbstractFactory
{
private static readonly IDictionary<Type, Type> instances = null;

public static AbstractFactory()
{
//从具体的配置项中读取,从配置文件中读取或者通过某个方法来硬编码实现等。
//这里推荐的做饭是从配置文件中读取。
instances = new Dictionary<Type, Type>();
instances.Add(Type.GetType(“”), Type.GetType(“”));
instances.Add(Type.GetType(“”), Type.GetType(“”));
}
public T Create()
{
if (!instances.ContainsKey(typeof(T)))
return default(T);

Type typeInstance = instances[typeof(T)];

T obj = (T)Activator.CreateInstance(typeInstance);

return obj;
}
}

  • 通过上面给出的代码,基本上可以满足一般项目的需求,大家当然有好的思路和建议也可以提出,给出更好的改进方案,下面我给出大概的配置文件格式,其实就是父子级节点,父级节点是负责创建的工厂
  • 类,那么这个父节点下的子节点就是工厂要创建的具体的对象类型。

image

上图中描述的思路,我们大概知道了,对应这样的一个支持多个具有依赖关系或者组合关系的对象的动态抽象工厂的实现,那么如果我们想实现支持多个具有依赖关系或者组合

关系的不同的创建形式的通用创建工厂时,我们如何来做呢?同上面的思路,只不过我们外部需要再添加一个字典,负责类型和抽象工厂的映射,即抽象工厂可以创建的字典列

表及抽象工厂具体实例类型之间的键值对关系,或者通过配置文件来组织父子级的关系。我们大概的看下配置文件的组织吧:

<?xml version="1.0" encoding="utf-8" ?>

那么具体的抽象工厂的代码又如何组织呢?如下形式:

///
/// 具体的通用工厂实现
///
public class AbstractFactory : IAbstractFactory
{
///
/// 工厂与工厂能够创建的对象类型字典之间的映射字典
///
private static readonly IDictionary<Type, Dictionary<Type, Type>> typeMapper = null;
private Type factoryType = null;

public static AbstractFactory()
{
//从具体的配置项中读取,从配置文件中读取或者通过某个方法来硬编码实现等。
//这里推荐的做饭是从配置文件中读取。
//根据配置文件中的ObjectInstance 节点放在对应的工厂下的字典中
//每个工厂节点FactorySection 就会创建一个字典,并且将这个工厂能够创建的类型放在这个字典中
typeMapper = new Dictionary<Type, Dictionary<Type, Type>>();
}

public AbstractFactory(string typeName)
{
this.factoryType = Type.GetType(typeName);
}
public T Create()
{
if(typeMapper.ContainsKey(this.factoryType))
return default(T);

Dictionary<Type, Type> instances = typeMapper[this.factoryType];

if (!instances.ContainsKey(typeof(T)))
return default(T);

Type typeInstance = instances[typeof(T)];

T obj = (T)Activator.CreateInstance(typeInstance);

return obj;
}
}

通过上面的代码我们就给出了一个通用的抽象工厂的可行的解决方案。

5.2、通过委托来实现工厂模式

我们先要定义一个委托:

public delegate string DelegateFunctionHandler(string userName);

基于这个委托的工厂实现方案

///
/// 具体的通用工厂实现
///
public class DegelateFactory
{
private DelegateFunctionHandler handler = null;

public static DelegateFunctionHandler Create()
{
if (handler == null)
handler = new DelegateFunctionHandler(this.Test);

return handler;
}

public string Test(string name)
{
return “Test!”;
}

}

工厂返回一个委托类型的对象,当然我上面为了简单给出的test方法其实就是工厂内部的方法,当然这里还可以进行相应的改进,也可以通过配置文件来完成,通过配置文件把相应相

应的委托事件方法,通过配置来通过工厂动态的创建。下面给出个思路吧,具体的实现我就不贴出来了:

image也希望大家给出更好的实现思路和方案。希望能多多的交流。

六、抽象工厂模式使用总结

通过上面的实现方式和思路,我们来对比一下抽象工厂、工厂模式、简单工厂模式之间的差异和相同点。

相同点:

1、都是为客户调用程序与具体的对象类型之间提供了一个解耦作用,这里怎么说呢?其实就是应用程序不关心这个对象是怎么出来的,只关系如何使用这个对象,而且以后就算对象发生变化,那么也不需

要修改用户应用程序的代码。

2、提高了程序的可维护性和低耦合性。

异同点:

1、简单工厂模式:是简单的一些列没有任何依赖关系的对象的创建,内部包含复杂的逻辑关系,一半是通过配置或者参数来进行创建对象,适合对象类型不多,并且不会经常新增的情况下。

工厂模式:每个工厂负责具体类型对象的创建,提供了可以动态新增产品类型的创建,并不需要修改现有的程序就可以无缝的新增产品类型。

抽象工厂模式:支持动态的新增对象类型和新增工厂类型,实现多种依赖关系的对象或者组合关系的创建,适合现有项目中的对象创建过程。

2、简单工厂模式:内部逻辑复杂,不符合高内聚的原则。

工厂模式:每次新增一个对象类型,就必须新增一个对应的创建工厂,无疑这是一个非常大的工作量。

抽象工厂模式:是在简单工厂模式的基础上经过改进具有前2个模式的优点,又屏蔽了他们的一些缺点。

当然我们在具体的项目中,还是需要具体的情况具体分析,一般情况下,我们对于这种数据库平滑迁移时,简单工厂可能比其他2类工厂更容易做,也很灵活。

七、系列进度。

创建型

1、系统架构技能之设计模式-单件模式

2、系统架构技能之设计模式-工厂模式

3、系统架构技能之设计模式-抽象工厂模式

4、系统架构技能之设计模式-创建者模式

5、系统架构技能之设计模式-原型模式

结构型

1、系统架构技能之设计模式-组合模式

2、系统架构技能之设计模式-外观模式

3、系统架构技能之设计模式-适配器模式

4、系统架构技能之设计模式-桥模式

5、系统架构技能之设计模式-装饰模式

6、系统架构技能之设计模式-享元模式

7、系统架构技能之设计模式-代理模式

行为型

1、系统架构技能之设计模式-命令模式

2、系统架构技能之设计模式-观察者模式

3、系统架构技能之设计模式-策略模式

4、系统架构技能之设计模式-职责模式

5、系统架构技能之设计模式-模板模式

6、系统架构技能之设计模式-中介者模式

7、系统架构技能之设计模式-解释器模式

八、下篇预告。

下篇将会针对创建者模式进行讲述,该模式也是创建型模式中最复杂的设计模式之一,该 模式是对一个对象的各个创建部分进行划分,最后创建出完整的对象,当然这里面的实现方式可以说还是

那几类思路,我将会给出几个方案的关键代码,希望大家多提宝贵意见,错误之处还请指出,请大家继续支持。
转自:https://www.cnblogs.com/hegezhou_hot/archive/2010/12/01/1893388.html

相关文章:

系统架构技能之设计模式-抽象工厂模式

一、上篇回顾 上篇我们主要讲述了简单工厂模式和工厂模式。并且分析了每种模式的应用场景和一些优缺点&#xff0c;我们现在来回顾一下&#xff1a; 简单工厂模式&#xff1a;一个工厂负责所有类型对象的创建&#xff0c;不支持无缝的新增新的类型对象的创建。 工厂模式&…...

clangd的使用,实现跳转提示

一、插件卸载c插件下载clangd 二、设置搜索clangd --compile-commands-dirbuild文件中compile_commands的绝对路径若没有找到compile_commands.json文件可以通过如下方式之后再便于即可生成 cmake项目&#xff1a; 在项目最顶层的.cmake文件中或者CMakeList文件中加入如下命令…...

2023应届生java面试搞笑之一:CAS口误说成开心锁-笑坏面试官

源于&#xff1a;XX网&#xff0c;如果冒犯&#xff0c;表示歉意 面试官&#xff1a;什么是CAS 我&#xff1a;这个简单&#xff0c;开心锁 面试官&#xff1a;WTF&#xff1f; 我&#xff1a;一脸自信&#xff0c;对&#xff0c;就是这个 面试官&#xff1a;哈哈大笑&#xff…...

nginx-concat

为了减少tcp请求数量&#xff0c;nginx从上有服务器获取多个静态资源&#xff08;css&#xff0c;js&#xff09;的时候&#xff0c;将多个静态资源合并成一个返回给客户端。 这种前面有两个问号的请求都是用了cancat合并功能。 先到官网下载安装包&#xff0c;拷贝到服务器编译…...

Java 大厂面试 —— 常见集合篇 List HashMap 红黑树

23Java面试专题 八股文面试全套真题&#xff08;含大厂高频面试真题&#xff09;多线程_软工菜鸡的博客-CSDN博客 常见集合篇-01-集合面试题-课程介绍 02-算法复杂度分析 2 List相关面试题 2.1 数组 2.1.1 数组概述 数组&#xff08;Array&#xff09;是一种用连续的内存空…...

剪枝基础与实战(5): 剪枝代码详解

对模型进行剪枝,我们只对有参数的层进行剪枝,我们基于BatchNorm2d对通道重要度 γ \gamma γ参数进行稀释训练。对BatchNorm2d及它的前后层也需要进行剪枝。主要针对有参数的层:Conv2d、BatchNorm2d、Linear。但是我们不会对Pool2d 层进行剪枝,因为Pool2d只用来做下采样,没…...

Acwing 897. 最长公共子序列 (每日一题)

最长公共子序列 题目描述 给定两个长度分别为 N 和 M 的字符串 A 和 B&#xff0c;求既是 A 的子序列又是 B 的子序列的字符串长度最长是多少。 输入格式 第一行包含两个整数 N和 M。 第二行包含一个长度为 N 的字符串&#xff0c;表示字符串 A。 第三行包含一个长度为 M …...

CSS中border-radius的来美化table的实战方案

border-radius是一种CSS属性&#xff0c;用于设置元素的边框的圆角程度。其具体的用法如下&#xff1a; 设置一个值&#xff1a;可以为元素设置一个单一的圆角半径&#xff0c;这个半径将应用于元素的四个角。例如&#xff1a; div {border-radius: 10px; }设置四个值&#x…...

移除链表元素_每日一题

“路虽远&#xff0c;行则将至” ❤️主页&#xff1a;小赛毛 ☕今日份刷题&#xff1a;移除链表元素 题目描述&#xff1a; 给你一个链表的头节点 head 和一个整数 val &#xff0c;请你删除链表中所有满足 Node.val val 的节点&#xff0c;并返回 新的头节点 。 示例1&…...

spring boot + Consul 示例 (Kotlin版)

文章目录 1.docker 安装consul2.创建基于springboot的client2.1 依赖版本2.2 pom.xml2.3 启动类2.4 application.properties 3 搭建完成4. 总结 1.docker 安装consul docker-compose.yaml version: "3"services:consul:image: consul:1.4.4container_name: consule…...

Git企业开发控制理论和实操-从入门到深入(四)|Git的远程操作|Gitee

前言 那么这里博主先安利一些干货满满的专栏了&#xff01; 首先是博主的高质量博客的汇总&#xff0c;这个专栏里面的博客&#xff0c;都是博主最最用心写的一部分&#xff0c;干货满满&#xff0c;希望对大家有帮助。 高质量博客汇总 然后就是博主最近最花时间的一个专栏…...

SpringCloudAlibaba Gateway(二)详解-内置Predicate、Filter及自定义Predicate、Filter

Predicate(断言) ​ Predicate(断言)&#xff0c;用于进行判断&#xff0c;如果返回为真&#xff0c;才会路由到具体服务。SpirnngCloudGateway由路由断言工厂实现&#xff0c;直接配置即生效&#xff0c;当然也支持自定义路由断言工厂。 内置路由断言工厂实现 ​ SpringClo…...

调用chat-gpt

调用chat-gpt 依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifact…...

Element组件浅尝辄止6:Dialog 对话框组件

Dialog 对话框组件&#xff1a;在保留当前页面状态的情况下&#xff0c;告知用户并承载相关操作。 大白话就是弹窗组件&#xff0c;日常开发中比较常见 1.怎样使用&#xff1f; //触发方式 <el-button type"text" click"dialogVisible true">打开&…...

Bert和LSTM:情绪分类中的表现

一、说明 这篇文章的目的是评估和比较 2 种深度学习算法&#xff08;BERT 和 LSTM&#xff09;在情感分析中进行二元分类的性能。评估将侧重于两个关键指标&#xff1a;准确性&#xff08;衡量整体分类性能&#xff09;和训练时间&#xff08;评估每种算法的效率&#xff09;。…...

【面试经典150题】跳跃游戏

题目链接 给你一个非负整数数组 nums &#xff0c;你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后一个下标&#xff0c;如果可以&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 1 < nums…...

【Rust】003-基础语法:流程控制

【Rust】003-基础语法&#xff1a;流程控制 文章目录 【Rust】003-基础语法&#xff1a;流程控制一、概述二、if 表达式1、语法格式2、多个3、获取表达式的值 三、循环1、loop&#xff1a;无限循环&#xff0c;可跳出无限循环跳出循环返回值 2、while&#xff1a;条件循环&…...

0829【综述】面向时空数据的区块链研究综述

摘要:时空数据包括时间和空间2个维度,常被应用于物流、供应链等领域。传统的集中式存储方式虽然具有一定的便捷性,但不能充分满足时空数据存储及查询等要求,而区块链技术采用去中心化的分布式存储机制,并通过共识协议来保证数据的安全性。研究现有区块链1.0、2.0和以Block-DAG为…...

MySQL高级篇(SQL优化、索引优化、锁机制、主从复制)

目录 0 存储引擎介绍1 SQL性能分析2 常见通用的JOIN查询 SQL执行加载顺序七种JOIN写法3 索引介绍 3.1 索引是什么3.2 索引优劣势3.3 索引分类和建索引命令语句3.4 索引结构与检索原理3.5 哪些情况适合建索引3.6 哪些情况不适合建索引4 性能分析 4.1 性能分析前提知识4.2 Expla…...

YOLOV8模型使用-检测-物体追踪

这个最新的物体检测模型&#xff0c;很厉害的样子&#xff0c;还有物体追踪的功能。 有官方的Python代码&#xff0c;直接上手试试就好&#xff0c;至于理论&#xff0c;有想研究在看论文了╮(╯_╰)╭ 简单介绍 YOLOv8 中可用的模型 YOLOv8 模型的每个类别中有五个模型用于检…...

springmvc:设置后端响应给前端的json数据转换成String格式

设置spring-mvc.xml: xml <?xml version"1.0" encoding"UTF-8"?> <beans xmlns"http://www.springframework.org/schema/beans"xmlns:context"http://www.springframework.org/schema/context"xmlns:xsi"http://www.w…...

Mac安装brew、mysql、redis

mac安装brew mac安装brewmac安装mysql并配置开机启动mac安装redis并配置开机启动 mac安装brew 第一步&#xff1a;执行. /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"第二步&#xff1a;输入开机密码 第三…...

MLC-LLM 部署RWKV World系列模型实战(3B模型Mac M2解码可达26tokens/s)

0x0. 前言 我的 ChatRWKV 学习笔记和使用指南 这篇文章是学习RWKV的第一步&#xff0c;然后学习了一下之后决定自己应该做一些什么。所以就在RWKV社区看到了这个将RWKV World系列模型通过MLC-LLM部署在各种硬件平台的需求&#xff0c;然后我就开始了解MLC-LLM的编译部署流程和…...

Unity 之 参数类型之值类型参数的用法

文章目录 基本数据类型结构体结构体的进一步补充 总结&#xff1a; 当谈论值类型参数时&#xff0c;我们可以从基本数据类型和结构体两个方面详细解释。值类型参数指的是以值的形式传递给函数或方法的数据&#xff0c;而不是引用。 基本数据类型 基本数据类型的值类型参数&…...

VScode远程连接主机

一、前期准备 1、Windows安装VSCode&#xff1b; 2、在VSCode中安装PHP Debug插件&#xff1b; 3、安装好Docker 4、在容器中安装Xdebug ①写一个展现phpinfo的php文件 <?php phpinfo(); ?>②在浏览器上打开该文件 ③复制所有信息丢到Xdebug: Installation instr…...

【iOS】属性关键字

文章目录 前言一、深拷贝与浅拷贝1、OC的拷贝方式有哪些2. OC对象实现的copy和mutableCopy分别为浅拷贝还是深拷贝&#xff1f;3. 自定义对象实现的copy和mutableCopy分别为浅拷贝还是深拷贝&#xff1f;4. 判断当前的深拷贝的类型&#xff1f;(区别是单层深拷贝还是完全深拷贝…...

【计算机基础】Git从安装到使用,详细每一步!扩展Github\Gitlab

&#x1f4e2;&#xff1a;如果你也对机器人、人工智能感兴趣&#xff0c;看来我们志同道合✨ &#x1f4e2;&#xff1a;不妨浏览一下我的博客主页【https://blog.csdn.net/weixin_51244852】 &#x1f4e2;&#xff1a;文章若有幸对你有帮助&#xff0c;可点赞 &#x1f44d;…...

深入了解Docker镜像操作

Docker是一种流行的容器化平台&#xff0c;它允许开发者将应用程序及其依赖项打包成容器&#xff0c;以便在不同环境中轻松部署和运行。在Docker中&#xff0c;镜像是构建容器的基础&#xff0c;有些家人们可能在服务器上对docker镜像的操作命令不是很熟悉&#xff0c;本文将深…...

嵌入式开发-单片机学习介绍

一、单片机入门篇 单片机的定义和历史 单片机是一种集成了微处理器、存储器、输入输出接口和其他功能于一体的微型计算机&#xff0c;具有高度的集成性和便携性。单片机的历史可以追溯到20世纪70年代&#xff0c;随着微电子技术的不断发展&#xff0c;单片机逐渐成为了工业控…...

5、Spring之Bean生命周期源码解析(销毁)

Bean的销毁过程 Bean销毁是发送在Spring容器关闭过程中的。 在Spring容器关闭时,比如: AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class); UserService userService = (UserService) context.getBean("userSe…...