组合模式(Composite Pattern)

一、模式动机

处理树型结构

组合模式(Composite Pattern)关注那些存在叶子构件和容器构件的结构以及它们的组织形式叶子构件中不能包含成员对象,而容器构件中可以包含成员对象,这些成员对象可能是叶子构件对象,也可能是容器构件对象。这些对象可以构成一个树形结构组合模式用面向对象的方式来处理树形结构,它为叶子构件和容器构件提供了一个公共的抽象构件类,客户端可以针对该抽象类进行处理,而无需关心所操作的是哪种类型的对象。


  • 在树形目录结构中,包含文件和文件夹两类不同的元素
  • 在文件夹中可以包含文件,还可以继续包含子文件夹
  • 在文件中不能再包含子文件或者子文件夹
    • 文件夹 容器(Container)
    • 文件 叶子(Leaf)

如何将容器对象和叶子对象进行递归组合,使得用户在使用时无须对它们进行区分,可以一致地对待容器对象和叶子对象?

  • 对于树形结构.当容器对象(如文件夹)的某一个方法被调川时,将遍历整个树形结构,寻找也包含这个方法的成员对象(可以是容器对象,也可以是叶子对象,如子文件夹和文件)并调用执行,牵一而动百,其中使用了递归调用的机制来对整个结构进行处理由于容器对象和叶子对象在功能上有区别,在使用这些对象的客户端代码中必须有区别地对待容器对象和叶子对象,而实际上大多数情况下客户端希望一致地处理它们。因为对于这些对象的区别对待将会使得程序非常复杂。
  • 组合模式通过一种巧妙的设计方案使得用户可以一致性地处理整个树形结构或者树形结构的一部分,它描述了如何将容器对象和叶子对象进行递归组合,使得用户在使用时无须对它们进行区分,可以一致地对待容器对象和叶子对象。

二、模式定义

  • 组合多个对象形成树形结构以表示“部分-整体”的结构层次。组合模式对单个对象(即叶子对象)和组合对象(即容器对象)的使用具有一致性。
  • 对象结构型模式
  • 将对象组织到树形结构中,可以用来描述整体与部分的关系

三、模式结构

image

四、案例实现

案例背景

文件系统,文件夹为容器,文件为叶子

案例结构

image

代码实现

抽象构件

public interface AbstractFile {

    void add(AbstractFile abstractFile);
    void remove(AbstractFile abstractFile);
    void display();
    AbstractFile getFile(int i);

}

叶子构件
图片文件、视频文件、文本文件

public class ImageFile implements AbstractFile{

    private String fileName;

    public ImageFile(String fileName) {
        this.fileName = fileName;
    }

    @Override
    public void add(AbstractFile abstractFile) {
        System.out.println("无法执行!!");
    }

    @Override
    public void remove(AbstractFile abstractFile) {
        System.out.println("无法执行!!");
    }

    @Override
    public void display() {
        System.out.println("——正在打开"+fileName+"文件 ...... 浏览"+fileName);
    }

    @Override
    public AbstractFile getFile(int i) {
        System.out.println("无法执行!!");
        return null;
    }

}
public class VideoFile implements AbstractFile{

    private String fileName;

    public String getFileName() {
        return fileName;
    }

    public VideoFile(String fileName) {
        this.fileName = fileName;
    }

    @Override
    public void add(AbstractFile abstractFile) {
        System.out.println("无法执行!!");
    }

    @Override
    public void remove(AbstractFile abstractFile) {
        System.out.println("无法执行!!");
    }

    @Override
    public void display() {
        System.out.println("——正在打开"+fileName+"文件 ...... 播放"+fileName);
    }

    @Override
    public AbstractFile getFile(int i) {
        System.out.println("无法执行!!");
        return null;
    }

}
public class TextFile implements AbstractFile{

    private String fileName;

    public TextFile(String fileName) {
        this.fileName = fileName;
    }

    @Override
    public void add(AbstractFile abstractFile) {
        System.out.println("无法执行!!");
    }

    @Override
    public void remove(AbstractFile abstractFile) {
        System.out.println("无法执行!!");
    }

    @Override
    public void display() {
        System.out.println("——正在打开"+fileName+"文件 ...... 查看"+fileName);
    }

    @Override
    public AbstractFile getFile(int i) {
        System.out.println("无法执行!!");
        return null;
    }

}

容器构件
文件夹

public class Folder implements AbstractFile{

    private String fileName;
    private ArrayList<AbstractFile> filelist = new ArrayList<>();

    public Folder(String fileName) {
        this.fileName = fileName;
    }

    @Override
    public void add(AbstractFile abstractFile) {
        filelist.add(abstractFile);
    }

    @Override
    public void remove(AbstractFile abstractFile) {
        filelist.remove(abstractFile);
    }

    @Override
    public void display() {
        System.out.println("——正在打开"+fileName+"文件夹");
        for (Object obj:filelist) {
            ((AbstractFile)obj).display();
        }
    }

    @Override
    public AbstractFile getFile(int i) {
        return (AbstractFile) filelist.get(i);
    }

}

实现结果

image

案例分析

文件不能包含子文件,子文件管理和访问方法需要提供异常处理或错误提示。
文件夹具体业务方法的实现,将递归调用成员构件的业务方法

五、模式分析

  • 叶子结点不能包含子构件,子构件管理和访问方法需要提供异常处理或错误提示。
  • 容器构件具体业务方法的实现,将递归调用成员构件的业务方法

六、总结

模式优点

  • 可以清楚地定义分层次的复杂对象,表示对象的全部或部分层次,让客户端忽略了层次的差异,方便对整个层次结构进行控制
  • 客户端可以一致地使用一个组合结构或其中单个对象,不必关心处理的是单个对象还是整个组合结构,简化了客户端代码
  • 增加新的容器构件和叶子构件都很方便,符合开闭原则
  • 为树形结构的面向对象实现提供了一种灵活的解决方案

模式缺点

  • 设计更加抽象,对象的业务规则如果很复杂,实现组合模式具有较大难度。而且不是所有的方法都与叶子对象子类都有关联。
  • 在增加新构件时很难对容器中的构件类型进行限制

使用情形

  • 在具有整体和部分的层次结构中,希望通过一种方式忽略整体与部分的差异,客户端可以一致地对待它们
  • 在一个使用面向对象语言开发的系统中需要处理一个树形结构
  • 在一个系统中能够分离出叶子对象和容器对象,而且它们的类型不固定,需要增加一些新的类型

扩展

透明组合模式

  • 抽象构件Component中声明了所有用于管理成员对象的方法,包括add()、remove(),以及getChild()等方法
  • 优点是确保所有的构件类都有相同的接口;
  • 在客户端看来,叶子对象与容器对象所提供的方法是一致的,客户端可以一致地对待所有的对象
  • 缺点是不够安全,因为叶子对象和容器对象在本质上是有区别的。

安全组合模式

  • 抽象构件Component中没有声明任何用于管理成员对象的方法,而是在Composite类中声明并实现这些方法
  • 优点是安全
    • 对于叶子对象,客户端不可能调用到这些方法
  • 缺点是不够透明,客户端不能完全针对抽象编程,必须有区别地对待叶子构件和容器构件
  • 使用频率更高

本文来自博客园,作者:街酒,转载请注明原文链接:http://www.cnblogs.com/sorrymine/p/17418701.html

本文转载于网络 如有侵权请联系删除

相关文章

  • dotnet 使用 MessagePack 序列化对象

    和很多序列化库一样,可以通过MessagePack序列化和反序列化,和json相比这个库提供了二进制的序列化,序列化之后的内容长度比json小很多这个库能序列的内容不多,大多数时候建议使用的序列的类都是只有基础的int和bool字符串等,最好不要存在复杂的类使用MessagePack的好处只是序列化出来的内容的长度小,但是从性能等方面,其实和Json差别不大,在序列化简单的类的时候,可以看到MessagePack的序列化速度会比较快。在序列化比较大的类如果序列化到文件,那么因为文件读写的性能,可以看到MessagePack的性能明显比json好。在使用MessagePack之前需要通过Nuget安装安装方法是在Nuget输入MessagePack安装下面写一个简单的方法,将会对这个类序列化[MessagePackObject] publicclassFoo { [Key(0)] publicstringLindexi{set;get;} }复制现在主函数创建这个类varfoo=newFoo{Lindexi="林德熙是逗比"};复制通过MessagePackSeria

  • 研究人员如何使用Shhgit搜索GitHub中的敏感数据

    ShhgitShhgit能够帮助广大研究人员以近乎实时的方式寻找GitHub(包括Gists)、GitLab和BitBucket提交代码中的敏感数据和敏感文件。实际上,在GitHub中发现敏感数据并不算什么新鲜事了。目前也有很多很好的工具可以帮助我们去寻找开源代码库中的敏感信息。比如说,类似gitrob和truggleHog这样的工具,可以帮助我们挖掘commit历史记录并寻找特定代码库的机密令牌。除此之外,GitHub本身也可以通过他们的令牌搜索项目来寻找敏感信息。它们的目标是实时识别提交代码中的秘密令牌,并通知服务提供商采取行动。所以从理论上讲,如果任何AWS密钥被提交到了GitHub,Amazon就会收到通知并自动撤销它们。Shhgit的主要目标是唤起用户的安全意识,并能够主动采取行动。虽然我不知道GitHub令牌扫描项目的内部工作机制,但是社区也可以做出很多努力来防止网络犯罪分子利用这个信息宝库。通过对签名的一些调整,Shhgit将能够给我们提供非常优秀的功能。工具安装广大用户可以直接使用预编译的代码或使用Go来进行源码编译。1、在用户设备上安装Go环境。2、执行下列命令下载并

  • Redux(一):基本概念

    背景React是一个单向数据流的view层框架,单向数据流、组件化、生命周期是其特点。在React组件关系中,组件状态由自己管理,父子组件通过props传递;兄弟组件那么就需要一个共同的父组件作中转;如果涉及层级比较深的话一层一层传递会非常麻烦。所以大量状态共享是React单独难以解决的问题。随着单页面应用的日益复杂,JavaScript需要维护更多的状态,这些状态除了包含服务端返回的数据还有:缓冲数据、未同步到服务端的持久化数据、UI状态等。如果能将这些状态从单个组件剥离出来统一管理,将会更好的维护、拓展Web应用。Redux就是JavaScript应用这样一个可预测化的状态管理容器。Redux本身和React其实并没有任何关系,只是二者共性的函数式编程配合起来会比较方便,当然实际React项目中还要用到react-redux做桥接。三大原则一、单一数据源应用的state保存在一个JavaScript对象树中,并且这个对象树只能存在于唯一的一个store中。import{createStore}from'redux'; conststore=createStore

  • 实验楼课程管理程序-深入学习《C++ Primer第五版》实验报告&学习笔记1

    本片博客为实验楼的训练营课程深入学习《C++Primer第五版》的实验报告和学习笔记。原课程地址为:https://www.shiyanlou.com/courses/405#原文出处:http://www.cnblogs.com/jacklu/p/4793049.html程序设计思路实验结果:源代码:header.h#pragmaonce #include<iostream> #include<string> #include<vector> typedefstructcourse { intid; stringname; }course; voidprintHelp(); voidprintCourseInfo(vector<course>); voidprintHowMany(vector<course>); voidprintTheLongest(vector<course>); intdeleteTheLast(vector<course>&);复制source.cpp#inc

  • WEB框架之---Django初级篇

    一、下载与安装(Windows版)    下载地址:https://www.djangoproject.com/download/    或者通过命令:pipinstalldjango==1.11.2进行安装(Python3使用pip3)推荐使用此版本    安装完成后找到django-admin.exe所在的路径,将其添加到环境变量Path中,以便于今后在任何位置运行命令。 二、创建django程序    1、终端方式创建   django-admin startproject my_site    #创建一个名称为my_site的django程序,即文件夹,在哪个目录执行命令即在那个目录创建复制   执行成功之后会生成如图目录结构:    执行:python manage.py runserver 127.0.0.1:8000复制    这时,django已经在本地跑起来了... 其他常用命令:  pythonmanage.pyrunserver0.0.0.0 #不限定IP和端口     pythonmanage.pystartappappname#在项目中创建app即不同的功能模

  • OPA 5 - CreateButtonTest creates CreateButtonSteps

    版权声明:本文为博主原创文章,遵循CC4.0BY-SA版权协议,转载请附上原文出处链接和本声明。本文链接:https://jerry.blog.csdn.net/article/details/102933825CreatedbyWang,Jerry,lastmodifiedonNov08,2015

  • 死磕 java同步系列之Semaphore源码解析

    问题(1)Semaphore是什么?(2)Semaphore具有哪些特性?(3)Semaphore通常使用在什么场景中?(4)Semaphore的许可次数是否可以动态增减?(5)Semaphore如何实现限流?简介Semaphore,信号量,它保存了一系列的许可(permits),每次调用acquire()都将消耗一个许可,每次调用release()都将归还一个许可。特性Semaphore通常用于限制同一时间对共享资源的访问次数上,也就是常说的限流。下面我们一起来学习Java中Semaphore是如何实现的。类结构Semaphore中包含了一个实现了AQS的同步器Sync,以及它的两个子类FairSync和NonFairSync,这说明Semaphore也是区分公平模式和非公平模式的。源码分析基于之前对于ReentrantLock和ReentrantReadWriteLock的分析,这篇文章相对来说比较简单,之前讲过的一些方法将直接略过,有兴趣的可以拉到文章底部查看之前的文章。内部类Sync//java.util.concurrent.Semaphore.Syncabstractsta

  • 社交互动创新 | 从点赞到击掌

    腾讯ISUXisux.tencent.com社交用户体验设计 1前言如何在产品功能上做更多的创新来体现设计价值一直是设计师关注的话题,尤其是在体系成熟的产品里,如何对完善的基本框架和功能进行突破、如何挖掘用户的互动诉求并拓展更多的互动行为等对于设计师来讲都是很大的挑战。我们从前期互动行为的挖掘、情感化的视觉体验打磨以及趣味的玩法升级三个方面,剖析Qzone击掌功能的整个设计历程,或许能为大家提供一些参考性的思路和设计方法。2何为互动我们先从真实生活场景中的互动说起。人与人之间的互动无处不在,它是我们生活中必要的组成部分,也是整个人类社会的基石。从本质上来讲,社交产品要解决的问题就是人们之间互动的问题。那么如何定义互动呢,我们可以从日常的生活场景中窥得一二。反馈链首先,让我们来看一看日常生活中的互动案例:这是一个很常见的熟人互动案例,我们可以看到,熟人间很容易产生话题,并持续互动下去。但是如果同样的话题发生在不是很熟悉的人之间,可能就会是另一番场景:在例二中,因为A与B互相不熟悉,所以A没有对B的回复产生进一步互动,对话因此而结束。我们可以进一步推理,其实在这个案例中,不管原因变成什么,

  • 诞生了马云和贝索斯的电商,正让变数成为新零售的主旋律

    文/孟永辉曾几何时,新零售这个曾经带给人们无限遐想的词汇已经烂大街。开口即谈“新零售”成为所有想要追赶风口的创业者们的固定姿势,围绕着“新零售”开始出现一系列的概念,但是对于新零售究竟是什么,新零售的真实样子是怎样的,或许到现在我们都还没有看到。至少从当下的发展情况来看,新零售对于我们来讲依然仅仅只是一个概念而已,并无真正实质性的内涵与意义。因为即使是从互联网巨头的财报当中,我们看到的仅仅只是新零售只占据很小份额的事实。根据阿里巴巴最新公布的财报数据显示,旗下零售连锁店盒马鲜生继续扩大业务范围,优化现有门店,推出改善消费体验的新举措。在第三季度,盒马鲜生继续实现强劲的同店销售增长。截至第三季度末,通过赋能包括大润发在内的超过470家实体零售门店,消费者可以通过手机淘宝在线下单。面对万亿级的用户,阿里巴巴仅仅赋能470家实体零售门店显然有些太少了。因此,尽管新零售是未来行业发展的一个主要方向,但是如果说现在的时代已经是新零售时代未免有些太过武断了。互联网巨头尚且如此,对于一些新零售的中小玩家来讲无疑更是雪上加霜,他们口中所提到的新零售或许仅仅只是一个为了吸引资本的关注而打造出来的概念而已

  • oracle导出错误904,exp 导出 EXP-00056: 遇到 ORACLE 错误 904

    大家好,又见面了,我是你们的朋友全栈君。 同一台机器上,其中一个备份正常<1>,另外一个报错<2>。同一台机器上导出日志显示的版本居然不一样,哪个高人给指点下。我机器上装的是Oracle9iEnterpriseEditionRelease9.2.0.8.0–Production(client)<1>连接到:Oracle9iEnterpriseEditionRelease9.2.0.8.0–ProductionWiththePartitioning,OLAPandOracleDataMiningoptionsJServerRelease9.2.0.8.0–Production已导出ZHS16GBK字符集和AL16UTF16NCHAR字符集…………………………在没有警告的情况下成功终止导出。<2>连接到:Oracle9iEnterpriseEditionRelease9.2.0.5.0–ProductionWiththePartitioning,OLAPandOracleDataMiningoptionsJServerRelease9.2.0

  • 【计算几何】多边形交集

    问题描述:已知两个多边形Poly1和Poly2,分别由点集C1={P1,P2,...,Pm}和C2={Q1,Q2,...,Qn}表示,求这两个多边形的交集。算法思想:两个多边形相交后,其顶点要么是两个多边形边的交点,要么是在多边形内部的点。算法步骤:1.计算两个多边形每条边之间的交点。2.计算包含在多边形内部的点。3.将交点和多边形内部的点,按逆时针(或顺时针)排序,得出最终的点集。代码基本实现如下:1typedefstructPoint 2{ 3intx; 4inty; 5}Point; 6boolPolygonClip(constvector<Point>&poly1,constvector<Point>&poly2,std::vector<Point>&interPoly) 7{ 8if(poly1.size()<3||poly2.size()<3) 9{ 10returnfalse; 11} 12 13longx,y; 14//计算多边形交点 15for(inti=0;i<poly1.size();i

  • linux replace \r\n to \n

    cattest.log|tr-d'\r'|hexdump-C|tail 复制   

  • 2020年12月19日公告(最后一条

    深思熟虑之后决定本博客要永久停用了。 决定以一个新的身份继续更博(当然不是这个了),就让这个博客永远停留在这里吧。 本人\(QQ:1102960617\),如果有能帮到的地方,必然全力相助,欢迎交流。 如果需要友链的话,加QQ说一声就好(PS:本人不是很难交流的。 还没打算告诉大家新的博客是啥,等到将来可能会公开吧。 感谢这么久以来不少人的支持,真的要淡化出oi/acm了。 哪个oier不想登上acm的舞台呢,看来我是没戏了,祝君好运。 希望自己能在新的方向走下去,也希望大家能够继续加油。 除特殊声明外,本博客作品均由顾z创作。 未经博主允许,不得转载

  • ASP.NET Core轻量级作业调度Job任务框架

    一、背景介绍 在ASP.NETCoreMVC/WebApi项目需要一个按时执行的任务,每隔几分钟执行一个,或者每隔几小时执行一次等等,这个时候就需要一个定时的功能,最简单的就是用Timer自己写一个,但是自己写的性能等各方面有可能不健全等等,虽然ASP.NETCore现在内置提供了自带的WorkerService功能,但是对于复杂时间的作业计划并不支持; 大家可能会想到使用强大的Quartz.Net框架,为什么不选择它,主要是因为太复杂的了,不容易简单快速上手,而现在开源的库也越来越多,功能也越来越好,那么阿笨今天给大家推荐一款轻量级的作业调度Job任务框架,简单且功能强大,很方便的与ASP.NETCore进行结合,那么它的名字是什么。。。。 文章末尾阿笨已经给大家把示例代码进行封装好了,开箱即用。你再也不用为项目中如何执行多个作业任务而感到烦恼了? 二、FluentScheduler介绍 我们是一批站在巨人肩上的人,好的东西也学会用,直接拿来主义。FluentScheduler定时任务库,通过nuget引用,可以设置各种事件间隔,,超级方便简单。 FluentSchedule

  • python-matplotlib库label函数参数即使用

    ```python importmatplotlib.pyplotasplt importnumpyasnp #定义数据 x=np.linspace(-3,3,50) y1=2*x+1 y2=x**2 #定义figure plt.figure() #绘图(x,y2) plt.plot(x,y2) #绘图(x,y1) plt.plot(x,y1,color='red',linewidth=1.0,linestyle='--') #设置坐标返回 plt.xlim((-1,2)) plt.ylim((-2,3)) #设置x轴刻度这里分为5个小刻度 new_ticks=np.linspace(-1,2,5) print(new_ticks) plt.xticks(new_ticks) #设置y轴刻度,这里将刻度以自定义的数字表示出来,比如-2显示为reallybad #使用$来更好的匹配文本以及字体,$\pi$则会显示Pi plt.yticks([-2,-1.8,-1,1.22,3], [r'$really\bad$',r'$bad$',r'$normal$',r'$good$',r'$re

  • codevs2875RY哥查字典

    题目链接:http://codevs.cn/problem/2875/ 题目描述Description   RY哥最近新买了一本字典,他十分高兴,因为这上面的单词都十分的和谐,他天天查字典。 输入描述InputDescription 1个整数N,表示字典里面的单词数量。 接下来N行,每行一个字符串,表示一个单词。 然后第N+2行,一个整数M,表示要查的单词数。 接下来M行,每行一个字符串,表示一个要查的单词。 输出描述OutputDescription 对于每一个要查的单词,如果在字典里面,就输出’Yes’,否则输出’No’,一行一个。 样例输入SampleInput 2 i you 1 love 样例输出SampleOutput No 数据范围及提示DataSize&Hint 1<N<10000 1<M<100 每个单词的长度[1..100] 保证都是小写字母。 题解 hash题,只要强行模拟即可。 #include<cstdio> #include<cstring&g

  • 数据转换处理,拼接

    1、8位,16位,32位数据转换 8位转16位 将2个8位数据high、low合成一个16位数据data_u16: data_u16=(high<<8)|low;复制   16位转8位 将一个16位数据data_u16拆分成2个8位数据high、low: high=(data_u16>>8)&0xff;//高8位 low=data_u16&0xff;//低8位复制 8位转32位将4个8位数据data_u8[4]合成一个32位数据data_u32: data_u32=(data_u8[0]<<24)|(data_u8[1]<<16)|(data_u8[2]<<8)|data_u8[3];复制 32位转8位将一个32位数据data_u32拆分成4个8位数据data_u8[4]: data_u8[0]=(data_u32>>24)&0xff; data_u8[1]=(data_u32>>16)&0xff; data_u8[2]=(data_u32>

  • 多子图绘制

    REF matplotlib说明框中字体粗细,不能使用times字体格式,可以设置matplotlib中x轴y轴字号或字体修改 matplotlib设置图片边缘距离(left=0.1,right=0.9,top=0.9,bottom=0.1) plt.title设置标题或标注和图片之间的距离;各个子图之间的距离 df_check_H为pd.DataFrame,index为时间,如果不是需要用pd.to_datetime()转化一下。 fig=plt.figure(figsize=(10,16),)#layout="constrained",使得图片更加紧凑 #fig.tight_layout() col_i=0 col_j=0 col_num=2 len_fig=int(df_check_H.shape[1]/2) plt.suptitle('$|$ConditionVariance($H_t$)', fontsize=14, #fontweight='medium', weight='bold')#共同title plt.subplots_adjust(left=0.125

  • 数据结构6_顺序队列(循环队列)

    本文实现了顺序队列,与链队列不同的是,顺序队列需要考虑一个问题,问题情况如下,解决办法:循环队列,当rear到分配的数组空间末尾时,转到数组头但是当q.rear==q.front时,又如何区分一种是空队列,一种是满队列的情况呢这里有两种方案本次代码实现了第一种方法,同时设置了一个技术变量length,稍加改动便可实现第二个方法代码如下:#include<iostream>usingnamespacestd;//该顺序队列为循环队列,解决队尾指针达到最大值,队列中有空闲单元,但新元素无法进入队列的情况//classSeqQueue{   int*data;   intfront;   intrear;   intcap;  //存储队列容量   int length;//当前队列长度public:   SeqQueue(intlength)  &nb

  • Hadoop配置的各种问题

    注意,我i这里失败了很多次   首先一定要永“管理员”打开powershell,不然权限不够,会发现没有activenode   第二,我这台电脑很破的,所以这里记录yarn的配置如下(注意不要限制内存为1024mb) <!--SitespecificYARNconfigurationproperties--> <property> <name>yarn.nodemanager.aux-services</name> <value>mapreduce_shuffle</value> </property> <property> <name>yarn.nodemanager.aux-services.mapreduce.shuffle.class</name> <value>org.apache.hadoop.mapred.ShuffleHandler</value> </property> <!--sch

  • 性能测试通过标准

    阿里:https://help.aliyun.com/document_detail/29338.html 一.通用互联网服务端性能 TPS大于期望值错误概率小于0.5%响应时间小于期望值CPU利用率小于75%JVM内存使用率小于80%平均每核CPU的Load小于1FullGC频率大于半小时每次 二.用户感知正常响应时间的标准 一秒为优秀三秒为普通五秒为客户忍受的上限十秒为垃圾超过十秒会认为系统崩了 三.用户感知特殊时间的标准 普通业务操作响应时间:5秒内万级数据量查询业务响应时间:8秒内百万级数据量业务查询响应时间:10秒内千万级别数据量业务查询响应时间:20秒内 四.中间件的一些标准 当前正在运行的线程数不能超过设定的最大值。一般情况下系统性能较好的情况下,线程数最小值设置50和最大值设置200比较合适。当前运行的JDBC连接数不能超过设定的最大值。一般情况下系统性能较好的情况下,JDBC最小值设置50和最大值设置200比较合适。GC频率不能频繁,特别是FULLGC更不能频繁,一般情况下系统性能较好的情况下,JVM最小堆大小和最大堆大小分别设置1024M比较合适。 五.全栈性能修炼

相关推荐

推荐阅读