急 的论文 急 通信网络仿真研究 急 求一篇关于
本文目录导航:
急 急 急 求一篇关于《通信网络仿真研究》的论文
帮您下了两篇,希望对您有所帮助哦!祝您愉快!1 题目:基于无线传感器网络仿真平台的研究一、引言 传感器网络(WSN)日新月异,各种网络方案和协议日趋复杂,网络规模日趋庞大,对网络研究人员而言,掌握网络仿真的重要性是不言而喻的。
WSN仿真能够在一个可控制的环境里研究WSN应用,包括操作系统和网络协议栈,能够仿真数量众多的节点,能够观察由不可预测的干扰和噪声引起的难以琢磨的节点间的相互作用,获取节点间详细的细节,从而提高节点投放后的网络成功率,减少投放后的网络维护工作。
目前无线传感器网络使用的仿真工具主要有NS2、TinyOS、OPNET、OMNET++等等。
其中TinyOS是专门针对无线传感器网络的特点而研究开发的。
二、无线传感器网络仿真简介 在传感器网络中,单个传感器节点有两个很突出的特点。
一个特点是它的并发性很密集;另一个特点是传感器节点模块化程度很高.上述这些特点使得无线传感器网络仿真需要解决可扩展性与仿真效率、分布与异步特性、动态性、综合仿真平台等等问题。
三、无线传感器网络常用仿真工具 无线传感器网络常用仿真工具有NS2、OPNET、OMNET++、TinyOS,下面我们简要介绍它们各自的性能和特点。
3.1 NS2 NS是一种可扩展、以配置和可编程的时间驱动的仿真工具,它是由REAL仿真器发展而来.在NS的设计中,使用C++和OTCL两种程序设计语言, C++是一种相对运行速度较快但是转换比较慢的语言,所以C++语言被用来实现网络协议, 编写NS底层的仿真引擎; OTCL是运行速度较慢,但可以快速转换的脚本语言,正好和C++互补,所以OTCL语言被用来配置仿真中各种参数,建立仿真的整体结构, OTCL的脚本通过调用引擎中各类属性、方法,定义网络的拓扑,配置源节点、目的节点建立链接,产生所有事件的时间表,运行并跟踪仿真结果,还可以对结果进行相应的统计处理或制图可以提供有线网络、无线网络中链路层及其上层精确到数据包的一系列行为仿真。
NS中的许多协议都和真实代码十分接近,其真实性和可靠性是非常高的。
3.2 OPNET OPNET是在MIT研究成果的基础上由MIL3公司开发的网络仿真软件产品。
OPNET的主要特点包括以下几个方面:(1)采用面向对象的技术,对象的属性可以任意配置,每一对象属于相应行为和功能的类,可以通过定义新的类来满足不同的系统要求; (2)OPNET提供了各种通信网络和信息系统的处理构件和模块;(3) OPNET采用图形化界面建模,为使用者提供三层(网络层、节点层、进程层)建模机制来描述现实的系统;(4) OPNET在过程层次中使用有限状态机来对其它协议和过程进行建模,用户模型及OPNET内置模型将会自动生成C语言实现可执行的高效、高离散事件的模拟流程;(5) OPNET内建了很多性能分析器,它会自动采集模拟过程的结果数据;(6)OPNET几乎预定义了所有常用的业务模型,如均匀分布、泊松分布、欧兰分等。
3.3 OMNET++ OMNET++是面向对象的离散事件模拟工具,为基于进程式和事件驱动两种方式的仿真提供了支持。
OMNET++采用混合式的建模方式,同时使用了OMNET++特有的ned(Network Discription,网络描述)语言和C++进行建模。
OMNET++主要由六个部分组成:仿真内核库、网络描述语言的编译器、图形化的网络编译器、仿真程序的图形化用户接口、仿真程序的命令行用户接口和图形化的向量输出工具。
OMNET++的主要模型拓扑描述语言NED,采用它可以完成一个网络模型的描述。
网络描述包括下列组件:输入申明、信道定义、系统模块定义、简单模块和复合模块定义。
使用NED描述网络,产生文件,该文件不能直接被C++编译器使用,需要首先采用OMNET++提供的编译工具NEDC将文件编译成文件。
最后,使用C++编译器将这些文件与用户和自己设计的简单模块程序连接成可执行程序。
3.4 TinyOS TinyOS是专门针对传感器研发出的操作系统。
在TinyOS上编程序使用的语言为nesC(C language for network embedded systems) 语言。
nesC语言是由C语言扩展而来的,意在把组件化/模块化思想和TinyOS基于事件驱动的执行模型结合起来。
nesC 组件有Module(模块)和Configuration(连接配置文件)两种。
在模块中主要实现代码的编制,在连接配置文件中主要是将各个组件和模块连接起来成为一个整体。
TinyOS程序采用的是模块化设计,所以它的程序核心往往都很小,能够突破传感器存储资源少的限制,这能够让TinyOS很有效的运行在无线传感器网络上并去执行相应的管理工作等。
TinyOS的特点主要体现在以下几个方面: (1)组件化编程(Componented-Based Architecture)。
TinyOS的组件通常可以分为以下三类:硬件抽象组件、合成组件、高层次的软件组件;硬件抽象组件将物理硬件映射到TinyOS组件模型.合成硬件组件模拟高级硬件的行为.高层次软件模块完成控制、路由以及数据传输等。
} (2)事件驱动模式(Event-Driven Architecture)。
事件驱动分为硬件驱动和软件事件驱动。
硬件事件驱动也就是由一个硬件发出中断,然后进入中断处理函数。
而软件驱动则是通过singal关键字发出一个事件。
(3)任务和事件并发模式(Tasks And Events Concurrency Model)。
任务用在对于时间要求不是很高的应用中,任务之间是平等的,即在执行时是按顺序先后来的,而不能相互抢占,TinyOS对任务是按简单的FIFO队列进行处理的。
事件用在对于时间的要求很严格的应用中,而且它可以占先优于任务和其他事件执行。
(4)分段执行(Split-Phase Operations)。
在TinyOS中由于tasks 之间不能互相占先执行,所以TinyOS没有提供任何阻塞操作,为了让一个耗时较长的操作尽快完成,一般来说都是将对这个操作的需求和这个操作的完成分开来实现,以便获得较高的执行效率。
(5) 轻量级线程(lightweight thread)。
轻量级线程(task, 即TinyOS中的任务)按FIFO方式进行调度,轻量级线程之间不允许抢占;而硬件处理线程(在TinyOS中,称为硬件处理器),即中断处理线程可以打断用户的轻量级线程和低优先级的中断处理线程,对硬件中断进行快速处理响应。
(6) 主动通信消息(active message)。
每一个消息都维护一个应用层和处理器。
当目标节点收到这个消息后,就会把消息中的数据作为参数,并传递给应用层的处理器进行处理。
应用层的处理器一般完成消息数据的解包操作、计算处理或发送响应消息等工作。
TinyOS操作系统中常用的仿真平台主要是TOSSIM和Avrora (1)TOSSIM(TinyOS simulation)是一个支持基于TinyOS的应用在PC机上运行的模拟器运行和传感器硬件相同的代码,仿真编译器能直接从TinyOS应用的组件表中编译生成仿真程序。
(2)Avrora是一种专门为Atmel和Mica2节点上以AVR单片机语言编写的程序提供仿真分析的工具。
它的主要特点如下:1) 为AVR单片机提供了cycle accurate级的仿真,使静态程序可以准确的运行。
它可以仿真片上(chip-on)设备驱动程序,并为片外(off-chip)程序提供了有规则的接口;2)可以添加监测代码来报告仿真程序运行的性能,或者可以在仿真结束后收集统计数据,并产生报告;3)提供了一套基本的监控器来剖析程序,这有助于分析程序的执行模式和资源使用等等;4)Avrora可以用gdb调试程序;5) Avrora可以为程序提供一个程序流图,通过这个流程图可以清楚的表示机器代码程序的结构和组织;6) Avrora中提供了分析能量消耗的工具,并且可以设置设备的带电大小;7) Avrora可以用来限制程序的最大堆栈空间,它会提供一些关于目前程序中的最大的堆栈结构,和一些关于空间和时间消耗的信息报告。
3.5性能比较 TinyOS 用行为建模,可以仿真跨层协议;仿真程序移植到节点上,不需要二次编码。
通过对上述几种仿真软件的分析比较,我们可以清楚的看到各个仿真软件的特点、适用范围,我们可以根据研究需要选择适合的仿真软件,使得我们的学习研究可以事半功倍。
结束语 网络仿真技术为通信网络规划和优化提供了一种科学高效的方法。
网络仿真在国内是近几年才发展起来的,但在国外网络仿真技术已经相当成熟,我们应该大胆地借鉴国外先进技术,促进国内网络仿真技术迅速发展。
参考文献 【1】于海斌,曾鹏等.智能无线传感器网络.科学出版社,2006,p283~p303, 【2】石怀伟,李明生,王少华,网络仿真技术与OPNET应用实践,计算机系统应用2006.第3期 【3】李玥,吴辰文,基于OMNeT++地TCP/IP协议仿真,兰州交通大学学报(自然科学版),2005年8月 【4】袁红林,徐晨,章国安,TOSSIM:无线传感器网络仿真环境,传感器与仪表仪器 ,2006年第22卷第7-1期 2集群虚拟服务器的仿真建模研究来源:电子技术应用 作者:杨建华 金笛 李烨 宁宇摘要:阐述了集群虚拟服务器的工作原理和三种负载均衡方式,通过实例讨论了虚拟服务器的仿真和建模方法,创建了测试和仿真系统性能的输入和系统模型,并依据Q—Q图和累积分布函数校验了其概率分布。
关键词:集群虚拟服务器负载均衡仿真建模概率分布 随着互联网访问量和数据流量的快速增长,新的应用层出不穷。
尽管Intemel服务器处理能力和计算强度相应增大,但业务量的发展超出了先前的估计,以至过去按最优配置建设的服务器系统也无法承担。
在此情况下,如果放弃现有设备单纯将硬件升级,会造成现有资源的浪费。
因此,当前和未来的网络服务不仅要提供更丰富的内容、更好的交互性、更高的安全性,还要能承受更高的访问量,这就需要网络服务具有更高性能、更大可用性、良好可扩展性和卓越的性价比。
于是,集群虚拟服务器技术和负载均衡机制应运而生。
集群虚拟服务器可以将一些真实服务器集中在一起,组成一个可扩展、高可用性和高可靠性的统一体。
负载均衡建立在现有网络结构之上,提供了一种廉价、有效和透明的方法建立服务器集群系统,扩展网络设备和服务器的带宽,增加吞吐量,加强网络数据处理能力。
提高网络的灵活性和可用性。
使用负载均衡机制.大量的并发访问或数据流量就可以分配到多台节点设备上分别处理。
系统处理能力得到大幅度提高,大大减少用户等待应答的时间。
实际应用中,虚拟服务器包含的真实服务器越多,整体服务器的性能指标(如应答延迟、吞吐率等)越高,但价格也越高。
在集群中通道或其他部分也可能会进入饱和状态。
因此,有必要根据实际应用设计虚拟服务器的仿真模型,依据实际系统的测量数据确定随机变量的概率分布类型和参数,通过分位点一分位点图即Q-Q图(Quaantile-Quantile Plot)和累积分布函数(Cumulative Distribution Functions)等方法校验应答或传播延迟等性能指标的概率分布,通过仿真软件和工具(如Automod)事先分析服务器的运行状态和性能特点,使得集群系统的整体性能稳定,提高虚拟服务器设计的客观性和设计的可靠性,降低服务器建设的投资风险。
1 集群虚拟服务器的体系结构一般而言,首先需要在集群虚拟服务器上建立互联网协议伪装(Internet Protocol Masquerading)机制,即IP伪装,接下来创立IP端口转发机制,然后给出在真实服务器上的相关设置。
图1为集群虚拟服务器的通用体系结构。
集群虚拟服务器通常包括:真实服务器(RealServers)和负载均衡器(Load Balmlcer)。
由于虚拟服务器的网络地址转换方式是基于IP伪装的,因此对后台真实服务器的操作系统没有特别要求,可以是windows操作系统,也可以是Lmux或其他操作系统。
负载均衡器是服务器集群系统的惟一入口点。
当客户请求到达时,均衡器会根据真实服务器负载情况和设定的调度算法从真实服务器中选出一个服务器,再将该请求转发到选出的服务器,并记录该调度。
当这个请求的其他报文到达后,该报文也会被转发到前面已经选出的服务器。
因为所有的操作都在操作系统核心空间中完成,调度开销很小,所以负载均衡器具有很高的吞吐率。
整个服务器集群的结构对客户是透明的,客户看到的是单一的虚拟服务器。
负载均衡集群的实现方案有多种,其中一种是Linux虚拟服务器LVS(Linux Virtual Server)方案。
LVS实现负载均衡的技术有三种:网络地址转换(Network Address Translation)、直接路由(Direct Routing)和IP隧道(IP Yunneling)。
网络地址转换按照IETF标准,允许一个整体机构以一个公用IP地址出现在Inlemet上。
通过网络地址转换,负载均衡器重写请求报文的目标地址,根据预设的调度算法,将请求分派给后端的真实服务器;真实服务器的应答报文通过均衡器时,报文的源地址被重写,把内部私有网络地址翻译成合法网络IP地址,再返回给客户,完成整个负载调度过程。
直接路由的应答连接调度和管理与网络地址转换的调度和管理相同,但它的报文是直接转发给真实服务器。
在直接路由应答中,均衡器不修改、也不封装IP报文.而是将数据帧的媒体接入控制MAC(Medium Aceess Control)地址改为选出服务器的MAC地址,再将修改后的数据帧在局域网上发送。
因为数据帧的MAC地址是选出的服务器,所以服务器肯定可以收到该数据帧,从中获得该IP报文。
当服务器发现报文的目标地址在本地的网络设备时,服务器处理该报文,然后根据路由表应答报文,直接返回给客户。
IP隧道是将一个IP报文封装在另一个IP报文中的技术。
该技术可以使目标为某个口地址的数据报文被封装和转发到另一个IP地址。
用户利用IP隧道技术将请求报文封装转发给后端服务器,应答报文能从后端服务器直接返回给客户。
这样做,负载均衡器只负责调度请求,而应答直接返回给客户,不需要再处理应答包,将极大地提高整个集群系统的吞吐量并有效降低负载均衡器的负载。
IP隧道技术要求所有的服务器必须支持IP Yunnehng或lP.封装(Encapsulation)协议。
2 集群虚拟服务器报文延迟的确定通过一个装有5台真实服务器并使用网络地址转换技术实现Linux虚拟服务器的实际系统,可以得到有关请求和应答报文的时戳(Time Stamp)文件n根据这些文件.能够计算出集群虚拟服务器的仿真和建模所需数据。
为了确定随机变量分布类型和参数,应该统计下列延迟:(1)从客户到负载均衡器的传播延迟(Transport Delay);(2)负载均衡器的应答延迟(Response Delay);(3)从负载均衡器到真实服务器的传播延迟;(4)真实服务器的应答延迟;(5)从真实服务器到负载均衡器的传播延迟;f61负载均衡器对真实服务器的应答延迟;(7)从负载均衡器到客户的传播延迟。
在实际系统产生的时戳文件中,问接地描述了上述各延迟时间。
文件包含的内容如下:当一个服务请求到达集群虚拟服务器系统时,即产生带有惟一序列号的同步请求报文(Synchronized Request Package),将该报文转发到某一真实服务器,同时建立该服务器与客户端的连接,每个这样的连接都带有惟一的端口号;该服务器处理通过该连接的确认请求报文(Acknowledgement Request Package),直到服务器收到结束请求报文(Finished Request Package)。
对每一种类型的请求报文,系统都给予一个相应的应答报文。
因此,在不同的报文时戳文件中,如果两条记录具有相同的端口号、报文类型和序列号,则它们是同一个请求或应答报文,对相关的时戳相减即可得到集群虚拟服务器系统的仿真和建模所需的延迟数据。
通过所编写的C++程序即可计算这些延迟。
3 系统仿真模型上述的集群虚拟服务器实际系统的仿真模型如图2所示,在负载均衡器、各通道、5台真实服务器中通过或处理的均为请求或应答报文。
4 随机变量模型的确定对具有随机变量的集群虚拟服务器进行仿真,必须确定其随机变量的概率分布,以便在仿真模型中对这些分布进行取样,得到所需的随机变量。
4.1 实际虚拟服务器的延迟数据概况在实际虚拟服务器的负载均衡器、各通道和5台真实服务器中,对请求和应答报文都有一定的延迟。
部分报文延迟的统计数据如表1所示。
由表l中的数据可见,报文延迟的中位数与均值差异较大,所以其概率分布不对称;变异系数不等于l,导致概率分布不会是指数分布,而可能是γ分布或其他分布。
4.2 随机变量的概率分布图3为第一台真实服务器到负载均衡器之间的通道报文传播延迟直方图,其中t为报文延迟时间,h(t)为报文延迟区间数。
由图3可知,通道内的报文传播延迟数据近似服从γ分布或对数正态分布。
描述γ分布需要两个参数:形状(Shape)参数α和比例(Scahj)参数口,这两个参数与均值M、方差V之间的关系是非线性的:描述对数正态分布也需要形状参数σ和比例参数μ,这两个参数与均值M、方差V之问的关系也是非线性的:式(1)~(4)都可以通过最大似然估计MLE(Maximum Likelihood Estimator)方法或最速下降法(Steepest Descent Method)求出。
表2给出了甩这两种方法求出的从第一台真实服务器到负载均衡器之间通道内的报文延迟概率分布参数。
使用累积分布函数和Q-Q图可以校验并进一步确定上述通道内报文传播延迟的概率分布。
取用表2中的参数,可以得到γ分布的累积分布函数,如图4所示,其中t为报文延迟时间,F(t)为报文延迟的累积分布函数。
为作比较,实验分布也画在该图中。
γ分布和对数正态分布的Q-Q图如图5所示。
由图4和图5可以看出,γ分布较好地拟合了该通道内的报文传播延迟数据分布。
其他通道报文延迟直方图也有类似形状。
经计算和分析,这些通道的报文传播延迟概率分布也近似服从γ分布。
根据表1中的数据以及相关的直方图都难以确定在负载均衡器和真实服务器中报文延迟的理论分布。
因此,采用实验分布作为其模型。
5 模型仿真在建立了图1所示的集群虚拟服务器的系统仿真模型并确定了其随机变量的分布特性后,可以采用由美国布鲁克斯自动化公司(Brooks Automation)开发的仿真软件Automod输入该模型,并通过在Automod环境中编程进行集群虚拟服务器的仿真和分析。
在Automod的仿真过程中,可以直接利用软件提供的资源(Resource)作为各种报文数据处理的单元;系统各部分的报文排队活动可以直接通过排队(Queue)实现;建立一个负载产生器,等效为在Inlemtet上使用虚拟服务器的客户。
通过采用Automod的属性变量(Attribute Variable)可以解决负载均衡器的双方向报文处理功能的问题。
负载均衡器使用轮转调度算法(Round Robin Scheduling),即假设所有真实服务器的处理性能均相同,依次将请求调度到不同的服务器。
验证仿真模型可以分别在实际虚拟服务器系统和Automod的仿真模型中从以下两方面进行对比:(1)在负载均衡器、各个真实服务器和通道中排队的应答或传播报文数量;(2)真实服务器及负载均衡器的cPU利用率。
例如,当使用实际的应答或传播报文延迟数据时,在Automod的仿真模型中,如果设置一个较低的资源量,则在仿真过程中就会发现大部分的负载都被堵在真实服务器的排队中,即真实服务器处理报文的能力过低,无法与实际系统的状况相比;如果设置一个较高的资源量,则意味着服务器的并行处理能力增加,真实服务器的利用率提高,负载就很少或不会滞留在真实服务器的排队中。
因此,在Automod中可以根据实际情况调整仿真模型的资源量大小。
如果在Automod中增加负载产生器的负载产生率,就等效为用户访问量增加,通过观察排队中的负载滞留比例,就可以发现系统的最大处理报文的能力以及系统各部分应答报文可能出现瓶颈之处。
例如,将负载产生率增加一倍,虽然系统仍然可以处理所有的报文,但各台真实服务器的平均利用率将达80%左右。
显然,这时系统应答报文的“瓶颈”为真实服务器,有必要在系统中增添一台新的真实服务器。
通过一个包括5台真实服务器的实际虚拟服务器系统。
收集并计算了仿真和建模的样板数据。
依据系统报文延迟的中位数、均值、变异系数和直方图等,确定了系统随机变量的概率分布;采用最大似然估计方法和最速下降法,得到了通道概率分布的具体参数;根据Q-Q图和累积分布函数进一步校验并最终确定通道的概率分布形式。
使用Automod软件进行了仿真建模和编程,借助仿真结果可以发现虚拟服务器的最大处理能力和可能的“瓶颈”之处。
通过及时定位系统“瓶颈”,可以有的放矢地进一步研究和改进系统,有效提高系统性能。
所采用的仿真方法也可以用于其他领域的仿真建模或分析中。
在仿真模型中,负载均衡方式和调度算法还需要进一步增加,以便于比较不同的虚拟服务器系统。
样本数据也需要进一步扩充,以避免报文延迟的自相关性。

fpga 是什么??做什么的???什么平台???一定采纳
FPGA由可配置逻辑块(CLB)与可编程互连相结合的网格构成。
制造完成后,FPGA还可以重新编程,以满足特定的功能或应用需求。
这一特性使FPGA有别于专用集成电路(ASIC)。
后者是明确地为给定的目标而制定的,以后无法更改。
虽然一次性可编程(OTP)FPGA是一种选择,但基于静态随机存取存储器(SRAM)的型号是最常见的,并且允许随着设计的变化而重新编程。
输入/输出焊盘、可重新编程的互连和可编程逻辑模块组成了一个现场可编程门阵列。
触发器或存储器模块可用作现场可编程门阵列逻辑模块中的存储器组件。
逻辑块可以执行简单到复杂的计算操作。
现场可编程门阵列和可编程只读存储器芯片有许多相似之处。
FPGA可以容纳数千个门阵列,这与可编程只读存储器芯片不同,可编程只读存储器芯片仅限于几百个门阵列。
现场可编程门阵列是可重新编程的,而不是ASIC,ASIC是为专业作业而开发的。
计算机用户可以使用现场可编程门阵列自定义微处理器的功能,以满足特定的个性化需求。
工程师使用FPGA来创建专用集成电路。
晶圆功能的缺乏使得现场可编程门阵列的生命周期更具可预测性。
其他优势包括潜在的重制、比其他解决方案更快的上市时间以及简单的设计周期。
FPGA用于许多行业和市场,包括无线通信、数据中心、汽车、医疗和航空航天。
FPGA中的芯片是完全可编程的,这是一个相当大的好处。
通过这种方式,它可以变成一个相当大的逻辑电路,一个遵循设计的设置,但用户也可以根据需要进行更新以进行调整。
换句话说,如果创建了一个电路卡或电路板,并且FPGA是电路的一个组件,则FPGA在创建过程中被编程,但随后可以重新编程以反映任何修改。
虽然第一批FPGA是在1980年代初推出的,但直到20世纪90年代末才开始流行起来。
除了Altera、赛灵思和德州仪器等少数几家企业之外,他们并不为人所知。
ASIC(专用集成电路)用于创建对于常规CPU或GPU来说过于复杂的系统,作为ASIC(专用集成电路)的替代方案。
由于它们使用户能够以更低的成本和更低的功耗生产产品,因此FPGA仍然是当今技术中的一个突出主题。
在网络和网络安全等其他应用中,它们也很有帮助。
将其与传统微控制器进行比较,传统微控制器无法容纳更大的设计,这是一项相当大的进步。
例如,8051微控制器采用了哈佛设计和CISC指令集。
FPGA没有这些内置指令集,这给了设计人员更多的自由度。
尽管FPGA经常与高端计算相关联,但消费电子行业的使用也在增加。
现场可编程门阵列芯片已经在顶级显卡中包含许多功能。
然而,它们比传统的视频卡更便宜,更耗电。
它们还支持许多同步流,并且具有明显更快的吞吐量。
因此,基于FPGA的图形卡在游戏机中越来越频繁地使用。
Verilog和VHDL只是FPGA使用的众多不同编程语言中的两种。
1984年,硬件描述语言Verilog被创建。
它可用于构建系统所需的任何类型的电路,并且是FPGA的设计标准。
另一种基于状态机对FPGA进行编程的常用语言是VHDL。
它与Verilog不同,因为它包含更多功能,如数据类型和信号名称,这使得创建复杂电路和提高效率变得更加简单。
定义了FPGA编程的语法和语法。
FPGA如何工作?每个FPGA制造商都有其独特的架构规范。
关键组件、原则和功能包括:1.可配置的逻辑块现场可编程门阵列的基本构建模块是CLB。
它是一个逻辑单元,可以设置或编程以执行特定任务。
连接块将连接到这些构建基块。
这些组件包括携带和控制逻辑、晶体管对和查找表(LUT)。
它们执行设计所需的逻辑操作。
可以使用基于逻辑的多路复用器或LUT来创建CLB。
基于LUT的逻辑中的模块由D触发器,查找表和2:1多路复用器组成。
多路复用器选择正确的输出。
2.可编程互连位于不同逻辑块中的逻辑单元之间的所有独特连接都存在于现场可编程门阵列的这一区域中。
包含多个基本半导体开关的开关盒通常用于实现互连。
这些电气可编程链路为这些可编程逻辑模块提供了路径。
不同长度的线段可以沿着布线路径找到,并由电气可编程开关连接。
FPGA密度由用于布线路径的器件数量决定。
FPGA的单元或输入焊盘的输出可以连接到电路中的任何其他单元或焊盘,利用对每个现场可编程门阵列至关重要的可编程互连点。
3.可编程路由可编程路由至关重要,因为它通常占结构表面的百分之五十以上以及应用程序的关键路由延迟。
可编程布线由预制线段和预配置的开关组成。
通过配置正确的开关组合,功能块的任何输出都可以链接到任何输入。
现场可编程门阵列路由架构有两种基本类型。
设计本质上是分层的,高级组件实例化较低级别的模块并链接其中的信号,从而为可编程门阵列提供了动力。
可编程门阵列可以使用连接芯片离散部分的短线来构建这些连接,因为在设计层次结构中靠近在一起的模块之间更频繁地进行通信。
FPGA的密度和性能受到路由设计的影响。
4.可编程I/O模块接口引脚用于将逻辑模块与外部组件连接起来。
现场可编程门阵列和外部电路之间的接口是IOB(输入输出模块),这是一种可编程输入和输出器件,用于满足各种电气特性下输入/输出信号的驱动和匹配需求。
I/O块将路由体系结构和CLB连接到外部元素。
在封装引脚和器件的底层电路之间,输入/输出模块提供可编程的单向或双向连接。
实现应用需要从头开始构建电路,因为以前的现场可编程门阵列缺乏运行任何软件的处理器。
因此,FPGA可能被编程为像OR门一样简单,或者像多核处理器一样复杂。
5.片上存储器集成在FPGA逻辑块中的FFS是FPGA系统中片上存储元件的一种形式。
尽管如此,随着现场可编程门阵列逻辑容量的提高,它被用于更广泛的系统中,这些系统几乎总是需要存储器来缓冲和重用芯片上的数据。
由于构建由寄存器和LUT组成的大型RAM的密度比SRAM块低100倍左右,因此还需要具有更密集的片上存储。
此外,在现场可编程门阵列上实现的应用程序的RAM要求差异大不相同。
6.数字信号处理(DSP)模块在运输链之前,商业现场可编程门阵列系统中使用的专用算术电路是加法器。
由于需要在利用LUT和携带链的软逻辑中加入乘法器,因此产生了严重的面积和延迟损失。
由于用于现场可编程门阵列的高乘法器密度信号处理和通信应用具有相当大的市场份额,设计人员开发了新颖的实现来解决软逻辑乘法器实现效率低下的问题,这称为数字信号处理或DSP。
无乘法分布式算术技术是使用基于LUT的现场可编程门阵列创建高效有限脉冲响应(FIR)滤波器设计的一种方法。
乘法器是FPGA系统中作为专用电路进行强化的主要候选者,因为它们在关键应用领域的现场可编程门阵列设计中普遍存在,并且在软逻辑中实现时尺寸、延迟和功耗都降低了。
7.系统级互连DDR内存和以太网的兴起只是FPGA容量和带宽稳步增长的几个原因。
管理这些高频端口和不断增长的结构之间的数据流量是一项挑战。
这种系统级链路过去是通过设置特定的FPGA逻辑和路由元件来形成软总线来建立的,这些总线在必要的端点之间完成流水线,多路复用和布线。
更宽总线是匹配这些外部接口带宽的唯一方法,因为它们以比现场可编程门阵列结构更高的频率运行。
由于大量和物理上很长的总线的组合,定时闭合具有挑战性,并且通常需要对总线进行相当大的流水线处理,从而增加了资源消耗。
现场可编程门阵列的应用FPGA在各行各业都有广泛的应用,特别是在工业物联网(IoT)领域。
它的一些关键应用领域:1.能源行业案例研究太阳能和风能等可再生能源越来越受欢迎。
它们在智能电网中是可靠的,其中法规仍在建立中。
输配电(T&D)变电站尤其需要高效的电力网络来实现智能电网的最佳运行。
自动化需要持续监控、调节和保护电网的技术,以实现更有效的峰值需求负载管理。
FPGA可以提高智能电网的性能和可扩展性,同时保持低功耗。
2.使用FPGA设计集成电路必须首先创建此类电路的体系结构。
然后,使用FPGA构建和测试原型,由于这种方法,错误是可以纠正的。
一旦原型按预期执行,就会开发一个ASIC项目。
这能够节省时间,因为创建集成电路可能是一项劳动密集型和复杂的操作。
此外,它还可以节省资金,因为可以使用单个FPGA来创建同一项目的大量修订版。
值得注意的是,当前的张量处理单元(TPU)或加密货币矿工最初是作为FPGA开发的,直到那时它们才被生产出来。
3.汽车体验的改善使用汽车芯片和IP实现车载信息娱乐、舒适性和便利性的解决方案。
借助MicrosemiFPGA,车载原始设备制造商(OEM)和供应商可以开发创新的安全应用,如巡航控制、盲点警告和防撞。
FPGA供应商提供网络安全功能,包括信息保证、防篡改和硬件安全,以及纠错内存和低静态功耗等可靠性功能。
由于其最小的泄漏和在低功耗环境中工作的能力,基于FPGA的存储可以提供低静态功耗。
4.支持实时系统在实时系统中,当响应时间至关重要时,会使用FPGA。
传统CPU的响应时间是不可预测的,因此无法准确估计一旦触发器触发,您将何时收到回复。
采用实时操作系统将反应时间保持在预定范围内。
在需要快速响应时间的情况下,这是不够的。
系统必须在FPGA中实现所需的方法,利用组合或顺序电路来解决这个问题并保证恒定的响应时间。
一旦准备就绪,就可以使用FPGA更改这样的实时系统并将其投入生产。
5.航空航天和国防使用案例为了满足恶劣环境的性能、可靠性和寿命要求,同时提供比传统ASIC实现更大的灵活性,工业制造公司提供了抗辐射可重构的FPGA,这些FPGA通常是空间级的。
抗辐射可重构FPGA适用于处理密集型空间系统。
6.在通信和软件定义网络(SDN)中的应用软件定义网络(SDN)和其他算法(如快速傅里叶变换(FFT))必须放入FPGA中,以便在复杂的实时环境中使用。
无线电的标准组件包括用于接收和传输信号的天线,以及用于通过过滤、更改信号频率等来处理信号的网络硬件。
这种硬件无法从根本上改变它所要实现的功能。
如今,此功能的很大一部分被转移到电子设备中,这通常是FPGA。
模拟器件通常仅限于天线、ADC和DAC转换器。
7.数据中心和云中的FPGA物联网(IoT)和大数据正在产生获取和处理的数据的指数级增长。
这与通过 并行的多个操作的深度学习技术进行计算分析相结合,导致对低延迟,灵活和安全的计算能力的高需求。
由于空间成本不断增加,无法通过添加更多服务器来解决。
由于FPGA能够加速处理,设计灵活性以及硬件对软件的安全性,数据中心世界的大门正在在很大程度上向他们敞开。
8.计算机视觉系统在现代世界中,计算机视觉系统存在于许多小工具中。
视频监控摄像机,机器人和其他设备就是这方面的例子。
许多这些小工具通常需要基于FPGA的系统,以便它们能够根据人的位置,周围环境和面部识别功能,以有意义的方式与人进行行动和交互。
要使用此功能,必须处理许多照片,其中大多数操作都是实时完成的,以检测物体,识别人脸等。
设计模式的设计原则
为什么要提倡“Design Pattern呢?根本原因是为了代码复用,增加可维护性。
那么怎么才能实现代码复用呢?面向对象有几个原则:单一职责原则 (Single Responsiblity Principle SRP)开闭原则(Open Closed Principle,OCP)、里氏代换原则(Liskov Substitution Principle,LSP)、依赖倒转原则(Dependency Inversion Principle,DIP)、接口隔离原则(Interface Segregation Principle,ISP)、合成/聚合复用原则(Composite/Aggregate Reuse Principle,CARP)、最小知识原则(Principle of Least Knowledge,PLK,也叫迪米特法则)。
开闭原则具有理想主义的色彩,它是面向对象设计的终极目标。
其他几条,则可以看做是开闭原则的实现方法。
设计模式就是实现了这些原则,从而达到了代码复用、增加可维护性的目的。
此原则是由Bertrand Meyer提出的。
原文是:“Software entities should be open for extension,but closed for modification”。
就是说模块应对扩展开放,而对修改关闭。
模块应尽量在不修改原(是“原”,指原来的代码)代码的情况下进行扩展。
那么怎么扩展呢?我们看工厂模式“factory pattern”:假设中关村有一个卖盗版盘和毛片的小子,我们给他设计一“光盘销售管理软件”。
我们应该先设计一“光盘”接口。
如图:[pre]______________|<>|| 光盘 ||_____________||+卖() || ||_____________|[/pre]而盗版盘和毛片是其子类。
小子通过“DiscFactory”来管理这些光盘。
代码为:publicclassDiscFactory{publicstatic光盘getDisc(Stringname){return(光盘)(name)();}}有人要买盗版盘,怎么实现呢?publicclass小子{publicstaticvoidmain(String[]args){光盘d=(盗版盘);d.卖();}}如果有一天,这小子良心发现了,开始卖正版软件。
没关系,我们只要再创建一个“光盘”的子类“正版软件”就可以了,不需要修改原结构和代码。
怎么样?对扩展开放,对修改关闭——“开闭原则”。
工厂模式是对具体产品进行扩展,有的项目可能需要更多的扩展性,要对这个“工厂”也进行扩展,那就成了“抽象工厂模式”。
合成/聚合复用原则(Composite/Aggregate Reuse Principle,CARP)经常又叫做合成复用原则。
合成/聚合复用原则就是在一个新的对象里面使用一些已有的对象,使之成为新对象的一部分;新的对象通过向这些对象的委派达到复用已有功能的目的。
它的设计原则是:要尽量使用合成/聚合,尽量不要使用继承。
就是说要少用继承,多用合成关系来实现。
我曾经这样写过程序:有几个类要与数据库打交道,就写了一个数据库操作的类,然后别的跟数据库打交道的类都继承这个。
结果后来,我修改了数据库操作类的一个方法,各个类都需要改动。
“牵一发而动全身”!面向对象是要把波动限制在尽量小的范围。
在Java中,应尽量针对Interface编程,而非实现类。
这样,更换子类不会影响调用它方法的代码。
要让各个类尽可能少的跟别人联系,“不要与陌生人说话”。
这样,城门失火,才不至于殃及池鱼。
扩展性和维护性才能提高。
设计模式分为三种类型,共23种。
创建型模式:单例模式、抽象工厂模式、建造者模式、工厂模式、原型模式。
结构型模式:适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式。
行为型模式:模版方法模式、命令模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式(Interpreter模式)、状态模式、策略模式、职责链模式(责任链模式)、访问者模式。
按字典序排列简介如下。
Abstract Factory(抽象工厂模式):提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
Adapter(适配器模式):将一个类的接口转换成客户希望的另外一个接口。
Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
Bridge(桥接模式):将抽象部分与它的实现部分分离,使它们都可以独立地变化。
Builder(建造者模式):将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
Chain of Responsibility(责任链模式):为解除请求的发送者和接收者之间耦合,而使多个对象都有机会处理这个请求。
将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它。
Command(命令模式):将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可取消的操作。
Composite(组合模式):将对象组合成树形结构以表示“部分-整体”的层次结构。
它使得客户对单个对象和复合对象的使用具有一致性。
Decorator(装饰模式):动态地给一个对象添加一些额外的职责。
就扩展功能而言, 它比生成子类方式更为灵活。
Facade(外观模式):为子系统中的一组接口提供一个一致的界面,Facade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
Factory Method(工厂模式):定义一个用于创建对象的接口,让子类决定将哪一个类实例化。
Factory Method使一个类的实例化延迟到其子类。
Flyweight(享元模式):运用共享技术有效地支持大量细粒度的对象。
Interpreter(解析器模式):给定一个语言, 定义它的文法的一种表示,并定义一个解释器, 该解释器使用该表示来解释语言中的句子。
Iterator(迭代器模式):提供一种方法顺序访问一个聚合对象中各个元素,而又不需暴露该对象的内部表示。
Mediator(中介模式):用一个中介对象来封装一系列的对象交互。
中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
Memento(备忘录模式):在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。
这样以后就可将该对象恢复到保存的状态。
Observer(观察者模式):定义对象间的一种一对多的依赖关系,以便当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动刷新。
Prototype(原型模式):用原型实例指定创建对象的种类,并且通过拷贝这个原型来创建新的对象。
Proxy(代理模式):为其他对象提供一个代理以控制对这个对象的访问。
Singleton(单例模式):保证一个类仅有一个实例,并提供一个访问它的全局访问点。
单例模式是最简单的设计模式之一,但是对于Java的开发者来说,它却有很多缺陷。
在九月的专栏中,David Geary探讨了单例模式以及在面对多线程(multi-threading)、类装载器(class loaders)和序列化(serialization)时如何处理这些缺陷。
State(状态模式):允许一个对象在其内部状态改变时改变它的行为。
对象看起来似乎修改了它所属的类。
Strategy(策略模式):定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。
本模式使得算法的变化可独立于使用它的客户。
Template Method(模板方法模式):定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。
Template Method使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
Visitor(访问者模式):表示一个作用于某对象结构中的各元素的操作。
它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。
从下一节开始,详细描述以下每一种设计模式。
意图定义一个用于创建对象的接口,让子类决定实例化哪一个类。
Factory Method 使一个类的实例化延迟到其子类。
适用性当一个类不知道它所必须创建的对象的类的时候。
当一个类希望由它的子类来指定它所创建的对象的时候。
当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候。
意图提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
适用性一个系统要独立于它的产品的创建、组合和表示时。
一个系统要由多个产品系列中的一个来配置时。
当你要强调一系列相关的产品对象的设计以便进行联合使用时。
当你提供一个产品类库,而只想显示它们的接口而不是实现时。
意图将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
适用性当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时。
当构造过程必须允许被构造的对象有不同的表示时。
意图用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
适用性当要实例化的类是在运行时刻指定时,例如,通过动态装载;或者为了避免创建一个与产品类层次平行的工厂类层次时;或者当一个类的实例只能有几个不同状态组合中的一种时。
建立相应数目的原型并克隆它们可能比每次用合适的状态手工实例化该类更方便一些。
意图保证一个类仅有一个实例,并提供一个访问它的全局访问点。
适用性当类只能有一个实例而且客户可以从一个众所周知的访问点访问它时。
当这个唯一实例应该是通过子类化可扩展的,并且客户应该无需更改代码就能使用一个扩展的实例时。
意图将一个类的接口转换成另外一个客户希望的接口。
Adapter 模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
适用性你想使用一个已经存在的类,而它的接口不符合你的需求。
你想创建一个可以复用的类,该类可以与其他不相关的类或不可预见的类(即那些接口可能不一定兼容的类)协同工作。
(仅适用于对象Adapter)你想使用一些已经存在的子类,但是不可能对每一个都进行子类化以匹配它们的接口。
对象适配器可以适配它的父类接口。
意图将抽象部分与它的实现部分分离,使它们都可以独立地变化。
适用性你不希望在抽象和它的实现部分之间有一个固定的绑定关系。
例如这种情况可能是因为,在程序运行时刻实现部分应可以被选择或者切换。
类的抽象以及它的实现都应该可以通过生成子类的方法加以扩充。
这时B r i d g e 模式使你可以对不同的抽象接口和实现部分进行组合,并分别对它们进行扩充。
对一个抽象的实现部分的修改应对客户不产生影响,即客户的代码不必重新编译。
(C++)你想对客户完全隐藏抽象的实现部分。
在C++中,类的表示在类接口中是可见的。
有许多类要生成。
这样一种类层次结构说明你必须将一个对象分解成两个部分。
Rumbaugh称这种类层次结构为“嵌套的普化”(nested generalizations )。
你想在多个对象间共享实现(可能使用引用计数),但同时要求客户并不知道这一点。
一个简单的例子便是Coplien的String类,在这个类中多个对象可以共享同一个字符串表示(StringRep)。
意图将对象组合成树形结构以表示“部分-整体”的层次结构。
C o m p o s i t e 使得用户对单个对象和组合对象的使用具有一致性。
适用性你想表示对象的部分—整体层次结构。
你希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。
意图动态地给一个对象添加一些额外的职责。
就增加功能来说,Decorator模式相比生成子类更为灵活。
适用性在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。
处理那些可以撤消的职责。
当不能采用生成子类的方法进行扩充时。
一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。
另一种情况可能是因为类定义被隐藏,或类定义不能用于生成子类。
意图为子系统中的一组接口提供一个一致的界面,Facade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
适用性当你要为一个复杂子系统提供一个简单接口时。
子系统往往因为不断演化而变得越来越复杂。
大多数模式使用时都会产生更多更小的类。
这使得子系统更具可重用性,也更容易对子系统进行定制,但这也给那些不需要定制子系统的用户带来一些使用上的困难。
Facade可以提供一个简单的缺省视图,这一视图对大多数用户来说已经足够,而那些需要更多的可定制性的用户可以越过Facade层。
客户程序与抽象类的实现部分之间存在着很大的依赖性。
引入Facade将这个子系统与客户以及其他的子系统分离,可以提高子系统的独立性和可移植性。
当你需要构建一个层次结构的子系统时,使用门面模式定义子系统中每层的入口点。
如果子系统之间是相互依赖的,你可以让它们仅通过Facade进行通讯,从而简化了它们之间的依赖关系。
意图运用共享技术有效地支持大量细粒度的对象。
适用性一个应用程序使用了大量的对象。
完全由于使用大量的对象,造成很大的存储开销。
对象的大多数状态都可变为外部状态。
如果删除对象的外部状态,那么可以用相对较少的共享对象取代很多组对象。
应用程序不依赖于对象标识。
由于Flyweight对象可以被共享,对于概念上明显有别的对象,标识测试将返回真值。
意图为其他对象提供一种代理以控制对这个对象的访问。
适用性在需要用比较通用和复杂的对象指针代替简单的指针的时候,使用Proxy模式。
下面是一 些可以使用Proxy模式常见情况:远程代理(Remote Proxy)为一个对象在不同的地址空间提供局部代表。
虚代理(Virtual Proxy)根据需要创建开销很大的对象。
保护代理(Protection Proxy)控制对原始对象的访问。
保护代理用于对象应该有不同 的访问权限的时候。
智能指引(Smart Reference)取代了简单的指针,它在访问对象时执行一些附加操作。
它的典型用途包括:对指向实际对象的引用计数,这样当该对象没有引用时,可以自动释放它(也称为SmartPointers)。
当第一次引用一个持久对象时,将它装入内存。
在访问一个实际对象前,检查是否已经锁定了它,以确保其他对象不能改变它。
意图使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。
将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
适用性有多个的对象可以处理一个请求,哪个对象处理该请求运行时刻自动确定。
你想在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。
可处理一个请求的对象集合应被动态指定。
意图将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可取消的操作适用性像上面讨论的MenuItem对象那样,抽象出待执行的动作以参数化某对象。
你可用过程语言中的回调(callback)函数表达这种参数化机制。
所谓回调函数是指函数先在某处注册,而它将在稍后某个需要的时候被调用。
Command模式是回调机制的一个面向对象的替代品。
在不同的时刻指定、排列和执行请求。
一个Command对象可以有一个与初始请求无关的生存期。
如果一个请求的接收者可用一种与地址空间无关的方式表达,那么就可将负责该请求的命令对象传送给另一个不同的进程并在那儿实现该请求。
支持取消操作。
Command的Execute操作可在实施操作前将状态存储起来,在取消操作时这个状态用来消除该操作的影响。
Command接口必须添加一个Execute操作,该操作取消上一次Execute调用的效果。
执行的命令被存储在一个历史列表中。
可通过向后和向前遍历这一列表并分别调用Unexecute和Execute来实现重数不限的“取消”和“重做”。
支持修改日志,这样当系统崩溃时,这些修改可以被重做一遍。
在Command接口中添加装载操作和存储操作,可以用来保持变动的一个一致的修改日志。
从崩溃中恢复的过程包括从磁盘中重新读入记录下来的命令并用Execute操作重新执行它们。
用构建在原语操作上的高层操作构造一个系统。
这样一种结构在支持事务(Transaction)的信息系统中很常见。
一个事务封装了对数据的一组变动。
Command模式提供了对事务进行建模的方法。
Command有一个公共的接口,使得你可以用同一种方式调用所有的事务。
同时使用该模式也易于添加新事务以扩展系统。
意图给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。
适用性当有一个语言需要解释执行, 并且你可将该语言中的句子表示为一个抽象语法树时,可使用解释器模式。
而当存在以下情况时该模式效果最好:该文法简单对于复杂的文法, 文法的类层次变得庞大而无法管理。
此时语法分析程序生成器这样的工具是更好的选择。
它们无需构建抽象语法树即可解释表达式, 这样可以节省空间而且还可能节省时间。
效率不是一个关键问题最高效的解释器通常不是通过直接解释语法分析树实现的, 而是首先将它们转换成另一种形式。
例如,正则表达式通常被转换成状态机。
但即使在这种情况下, 转换器仍可用解释器模式实现, 该模式仍是有用的。
意图提供一种方法顺序访问一个聚合对象中各个元素, 而又不需暴露该对象的内部表示。
适用性访问一个聚合对象的内容而无需暴露它的内部表示。
支持对聚合对象的多种遍历。
为遍历不同的聚合结构提供一个统一的接口(即, 支持多态迭代)。
意图用一个中介对象来封装一系列的对象交互。
中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
适用性一组对象以定义良好但是复杂的方式进行通信。
产生的相互依赖关系结构混乱且难以理解。
一个对象引用其他很多对象并且直接与这些对象通信,导致难以复用该对象。
想定制一个分布在多个类中的行为,而又不想生成太多的子类。
意图在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。
这样以后就可将该对象恢复到保存的状态。
适用性必须保存一个对象在某一个时刻的(部分)状态, 这样以后需要时它才能恢复到先前的状态。
如果一个用接口来让其它对象直接得到这些状态,将会暴露对象的实现细节并破坏对象的封装性。
意图定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时, 所有依赖于它的对象都得到通知并被自动更新。
适用性当一个抽象模型有两个方面, 其中一个方面依赖于另一方面。
将这二者封装在独立的对象中以使它们可以各自独立地改变和复用。
当对一个对象的改变需要同时改变其它对象, 而不知道具体有多少对象有待改变。
当一个对象必须通知其它对象,而它又不能假定其它对象是谁。
换言之,你不希望这些对象是紧密耦合的。
意图允许一个对象在其内部状态改变时改变它的行为。
对象看起来似乎修改了它的类。
适用性一个对象的行为取决于它的状态, 并且它必须在运行时刻根据状态改变它的行为。
一个操作中含有庞大的多分支的条件语句,且这些分支依赖于该对象的状态。
这个状态通常用一个或多个枚举常量表示。
通常, 有多个操作包含这一相同的条件结构。
State模式将每一个条件分支放入一个独立的类中。
这使得你可以根据对象自身的情况将对象的状态作为一个对象,这一对象可以不依赖于其他对象而独立变化。
意图定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。
本模式使得算法可独立于使用它的客户而变化。
适用性许多相关的类仅仅是行为有异。
“策略”提供了一种用多个行为中的一个行为来配置一个类的方法。
需要使用一个算法的不同变体。
例如,你可能会定义一些反映不同的空间/时间权衡的算法。
当这些变体实现为一个算法的类层次时,可以使用策略模式。
算法使用客户不应该知道的数据。
可使用策略模式以避免暴露复杂的、与算法相关的数据结构。
一个类定义了多种行为, 并且这些行为在这个类的操作中以多个条件语句的形式出现。
将相关的条件分支移入它们各自的Strategy类中以代替这些条件语句。
意图定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。
Te m p l a t e M e t h o d 使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
适用性一次性实现一个算法的不变的部分,并将可变的行为留给子类来实现。
各子类中公共的行为应被提取出来并集中到一个公共父类中以避免代码重复。
这是Opdyke和Johnson所描述过的“重分解以一般化”的一个很好的例子。
首先识别现有代码中的不同之处,并且将不同之处分离为新的操作。
最后,用一个调用这些新的操作的模板方法来替换这些不同的代码。
控制子类扩展。
模板方法只在特定点调用“hook”操作,这样就只允许在这些点进行扩展。
意图表示一个作用于某对象结构中的各元素的操作。
它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。
适用性一个对象结构包含很多类对象,它们有不同的接口,而你想对这些对象实施一些依赖于其具体类的操作。
需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而你想避免让这些操作“污染”这些对象的类。
Visitor使得你可以将相关的操作集中起来定义在一个类中。
当该对象结构被很多应用共享时,用Visitor模式让每个应用仅包含需要用到的操作。
定义对象结构的类很少改变,但经常需要在此结构上定义新的操作。
改变对象结构类需要重定义对所有访问者的接口,这可能需要很大的代价。
如果对象结构类经常改变,那么可能还是在这些类中定义这些操作较好。