本质复杂性 偶然复杂性

在数学中,顺序很重要。

取两个函数fg并将它们组合,从而将它们作为f(g(x))g(f(x))应用于参数。 通常,不能假定f(g(x))= g(f(x)) 。 例如,如果f(x)= 2xg(x)= x 2 ,则f(g(3))= 18g(f(3))= 36 。 功能应用的顺序很重要。 数学通常提供多种表达想法的方法,该f(g(x))也可以使用成分运算符o来表示,即“应用于”,使得f(g(x))= fog(x)

纯粹根据其他功能的组成定义的功能本身就是一个组合功能。 在Java中,组合方法可能如下所示:

public void recoverFromException() {View view = registry.get(View.class)view.endWaiting();}

如果我们希望从一种方法对其他方法的调用顺序的角度来看一个方法,那么,除去变量和赋值的混乱,我们可以使用“顺序方程式”对该方法进行“建模”:

recoverFromException = endWaiting o get

这样的组合源于所涉及的调用的必要关系, get()将参数提供给endWaiting() 。 即得到()endWaiting()之前被调用的语法订货要求的明确性,否则程序将无法编译。 但是看似无关的方法调用又是什么呢? 考虑以下:

public void clearViewCache(View view) {view.clearPositionCache();view.clearImageCache();}

此方法表示的语法排序要求比前一种方法弱,因为它不是组合方法,而是根据两个方法调用定义的,而这两个方法都不向另一个提供必要的参数。 一种其调用顺序缺乏必要的明确性的方法称为或有方法。 与先前的方法不允许重新排序不同,此偶然方法显然可以写成:

public void clearViewCache(View view) {view.clearImageCache();view.clearPositionCache();}

当然,事实并非如此。 由于不带参数且不提供返回值,这两个方法调用都具有副作用,因此第二个调用可能会收集第一个调用更改的信息,从而重新排序将导致错误。 显然缺乏必要的命令是否意味着要遵守隐身命令或随意随意洗牌是没有根据的; 重点仍然是,该方法本身无论哪种方式都没有提供语法证据,这样做暗示了组合没有提供的无序性。 这个建议可能是错误的,但仍然存在。 偶然性提出了一个问题,即构图可以完全避免。

程序员重视意图。 例如,肯特·贝克(Kent Beck)的《极限编程说明》(Extreme Programming Explained)声称,简单代码的本质就是“展现其意图”。 罗伯特·C·马丁(Robert C. Martin )进一步断言,“架构不仅仅是意图”,甚至不仅仅是编程。 约束的增加通常与意图的增加相关,因为随着约束的增加,替代方案的数量会减少,因此歧义和误解的机会也会减少。 鉴于组合比顺序约束更多地限制了排序,组合方法比偶然方法显示出更多的意图,因此仅在此狭窄维度上就享有优势。

一些符号可能会有所帮助。 正如o运算符表示合成,我们可以说\运算符表示偶发性。 因此,第二个片段可以写成:

clearViewCache = clearPositionCache \ clearImageCache

根据定义,这等于:

clearViewCache = clearImageCache \ clearPositionCache

程序员如何利用这种琐碎性来阐明意图? 一种方法是最小化或有方法的数量并最大化组合方法的数量。 a,在这里,由于一些不幸的组合规则,整个宇宙都在嘲笑程序员。 松散地:

组成+组成=组成。
应急+应急=应急。
构成+偶然性=偶然性。

也就是说, fogoh构成了一个组合方法,但是fo(g \ h)是一个或有方法,即使它包含一个组合算符。 一旦被命令的歧义所破坏,任何方法都无法逃脱偶然性。 然而,掩盖在混乱的布下甚至是部分意图似乎是可耻的。 因此,让我们进一步说,是一种仅围绕组合运算符或意外事件运算符形成的方法,例如调用序列k \ m \ p \ s或序列komopos ,我们将其称为“简单订单”方法,而同时拥有组合和应急算子的我们将其称为“定单复合”。 因此,将意图最大化就变成了将阶数复合方法粉碎成阶数简单的碎片。

考虑:

a = f \(g o h)

如果我们引入一个组合方法j ,使得j = goh,那么上面的order-compound简化为两个简单的方法:

a = f \ j
j = g o h

如图1所示,这种减少是以增加额外方法和深度为代价的,但是原始方法的偶然性混淆了其总体调用顺序,至少其中一种新方法明确希望其表达顺序。 即使保留了整体偶然性,该程序的一部分也已从偶然性中保存下来。

图1:顺序化合物意外事件的减少,在之前(左)和之后(右)。

遗憾的是,不存在任何保证可以将订单复合方法分解为一组简单订单方法的方法。

调用多参数方法固有地涉及偶然性,因为方法不决定功能参数的评估顺序。

(实际上,\运算符只不过是分隔函数参数的逗号。)然后出现两个问题。

给定一个成功的归约法,那么定序复合方法分解成的简单定序方法集是否唯一?

物产

偶然性的一些属性:

  1. f o (g \ h) = f(g, h)
  2. 可交换性:
    f \ g = g \ f
  3. 关联性:
    (f \ g) \ h = f \ (g \ h)
  4. 偶发权的分配权:
    (f \ g) o h = (f o h) \ (g o h)

其他存在,将在以后的文章中进行研究。

组成简单的订单

让我们检查一些实际的生产代码。 FitNesse提供以下所有摘录,第一个摘录来自PageDriver类。

private NodeList getMatchingTags(NodeFilter filter) throws Exception {String html = examiner.html();Parser parser = new Parser(new Lexer(new Page(html)));NodeList list = parser.parse(null);NodeList matches = list.extractAllNodesThatMatch(filter, true);return matches;}

将其建模为其基本方法调用可得出以下公式:

getMatchingTags = extractAllNodesThatMatch o parse o new Parser o new Lexer o new Page o html

这提供了一个完美的,顺序简单的组合方法,每个方法的调用都取决于先前的方法。 在表达不容篡改的命令时,程序员可以减轻程序员对潜在替代方法的负担,从而帮助阐明方法的意图。 由于顺序简单, PageDriver不会减少任何顺序复杂度。

偶然订单简单

public void close() throws IOException {super.close();removeStopTestLink();publishAndAddLog();maybeMakeErrorNavigatorVisible();finishWritingOutput();}

TestHtmlFormatter类中的此方法表示订单简单偶然性,其等式为:

close = close /  removeStopTestLink / publishAndAddLog / maybeMakeErrorNavigatorVisible / finishWritingOutput

同样,由于顺序简单, TestHtmlFormatter不可简化,但是与前面的示例不同,这很难说明该方法的设计。 程序员的意图对所使用的语法没有任何痕迹,完全解决了朦胧的语义问题。 仍然,至少该方法是简单的命令而不是命令复合的:将偶然性集中到这种纯粹的命令隐含性中,至少会挑出目标化合物还原所指向的意图揭示重构的目标。 重复一遍,降低阶数化合物本身并不会降低整个系统的意外情况,它们会重构正在研究的方法,而不是重构正在研究的方法所调用的方法。 取而代之的是,还原物起着炼油厂的作用,将偶发的污泥泵入金属桶中,供以后排毒。

有序化合物

MultiUserAuthenticator构造函数提供了一个简单的顺序复合示例:

public MultiUserAuthenticator(String passwdFile) throws IOException {PasswordFile passwords = new PasswordFile(passwdFile);users = passwords.getPasswordMap();cipher = passwords.getCipher();}

显然,有序复合条件方法可以通过以下方式建模:

MultiUserAuthenticator = (getPasswordMap \ getCipher) o new PasswordFile

执行有序化合物的还原涉及重构一种方法,以最小化构造该方法的有序化合物的方法。 要执行上述操作,最明显的简化是提取新方法f = getPasswordMap \ getCipher ,从而产生两个方程:

MultiUserAuthenticator = f o new PasswordFile
f = getPasswordMap \ getCipher

这样就消除了所有的阶数复合,从而产生了组合方法和阶数简单的或有方法,从而完成了归约。 产生的源代码如下所示:

public MultiUserAuthenticator(String passwdFile) throws IOException {PasswordFile passwords = new PasswordFile(passwdFile);f(passwords);}private f(PasswordFile passwords) throws IOException {users = passwords.getPasswordMap();cipher = passwords.getCipher();}

(可能存在方法f()的更好名称。)

同样,这种减少导致增加深度的成本。 但是,其他的减少也会出现。 给定上面的规则(4),构造函数的原始模型可以写为:

MultiUserAuthenticator = (getPasswordMap o new PasswordFile) \ (getCipher o new PasswordFile)

这将简化为三个简单的方程式:

MultiUserAuthenticator = f \ g
f = getPasswordMap o new PasswordFile
g = getCipher o new PasswordFile

但是,这样的表述有很多缺点,例如两次调用了PasswordFile构造函数。 如果这是一段计算量很大的代码,那么仅凭性能可能会使第二种说法难以为继。 减少仍然回答了我们的问题。 订单复合方法分解成的一组简单订单方法是否唯一? 没有。

归一化问题

PageHistoryprocessTestFile()方法阐明了一些有趣的困难:

void processTestFile(TestResultRecord record) throws ParseException {Date date = record.getDate();addTestResult(record, date);countResult(record);setMinMaxDate(date);setMaxAssertions(record);pageFiles.put(date, record.getFile());}

前面的示例介绍了方法调用的重复,以此作为探索不同顺序安排的手段。 但是,如果没有重复,就不能表示processTestFile()的顺序方程式。 在最小的情况下,它的getDate()似乎出现了两次:

processTestFile = put o (getDate \ getFile) \ setMaxAssertions \ (setMinMaxDate o getDate) \ countResult \ (addTestResult o getDate)
= put o (getDate \ getFile) \ setMaxAssertions \ countResult \ ((setMinMaxDate \ addTestResult) o getDate)

如果源代码中的方法调用与其在阶数方程中的出现之间存在一一对应的关系,则可以说所研究的方法是正常形式。 此processTestFile()的格式不是正常的,因此,尽管仍可简化,但重复执行调用的性能可能不切实际。

为了完整起见,如果引入a = put o(getDate \ getFile)b =(setMinMaxDate \ addTestResult) ,则得到:

processTestFile = a \ setMaxAssertions \ countResult \ (b o getDate)

最后,我们介绍c = bo getDate我们得到:

processTestFile = a \ setMaxAssertions \ countResult \ c

现在,这是一个简单的或有顺序的方法,将其余的顺序复合隔离到a()方法中,尽管从a()c()都调用了getDate ()

摘要

程序员以怀疑的态度看待绝对。

权变原则是图莱加坦(Tulegatan)原则中最薄弱的一点 ,它几乎无法超越样式指南的波涛汹涌的水域。 考虑到其关注的目标,这也许并不令人惊讶:不是具体的波纹效应而是无定形的意图。 该原则指出应将偶然性降至最低,而不是提倡警惕性消除方法调用的语义顺序,而应提倡在句法约束下增强语义顺序。

奇怪的是,尽管偶然性原理很弱,但它导致代码结构明显。 当新手努力在简化顺序和增加代码深度之间取得平衡时,精通顺序化合物缩减工具的战士会产生稀有敏锐度的重构。

马丁为类开发的SOLID原则经常在方法级别找到应用程序,许多程序员也呼吁该方法遵守单一责任原则。 当然,“单一责任”对不同的人而言意味着不同的事情,但有人会认为,组合方法比定单简单或有方法更遵守该原则,并且两者都大大超出了定序复合方法。 这样,偶然性提供了一个客观的梯度,可以根据该梯度评估主观原则。

这篇文章的下一部分将研究下降的消除,自然产生的订单分层和压实。

翻译自: https://www.javacodegeeks.com/2014/04/structural-contingency-part-one.html

本质复杂性 偶然复杂性

本质复杂性 偶然复杂性_结构偶然性(第一部分)相关推荐

  1. SQL注入漏洞_封神台第一关

    SQL注入漏洞_封神台第一关 http://59.63.200.79:8003/?id=1 一.观察疑似可注入点 ?id=1 二.尝试输入单引号和双引号 使用hackbar进行测试比较好 以下是正常显 ...

  2. _C语言_结构体_vistodio_c报错.+初学者的自闭瞬间。哎。

    在C语言中一直用不好子函数, 前几天看书+视频教学终于弄懂了, 想着用大一上做到的课设重新打一遍 工资纳税系统(不能说是系统就是一个控制台窗口连程序都算不上哈哈哈但是当时做出来的时候真的就是蛮高兴地) ...

  3. 结构偶然性(第一部分)

    在数学中,顺序很重要. 取两个函数f和g并将它们组合,从而将它们作为f(g(x))或g(f(x))应用于参数. 通常,不能假定f(g(x))= g(f(x)) . 例如,如果f(x)= 2x和g(x) ...

  4. 架构的本质是管理复杂性,微服务本身也是架构演化的结果

    为应对如今无线优先和全渠道用户体验的需求和挑战,我们该如何设计灵活的面向体验的微服务架构?它有哪些模式和最佳实践?携程,Netflix和SoundCloud这些知名互联网公司是如何实践面向体验的微服务 ...

  5. pycharm 类型注释_学习Python第一步,变量与数据类型

    Python是一门易学的面向对象的程序设计语言,可以轻易地完成界面.文件.封装等高阶需求,可移植性好,有非常多功能强大的库与包,如Numpy(数值计算).SciPy(数学.科学与工程计算).Matpl ...

  6. byte数组存的是什么_结构体内存对齐是什么鬼?

    前言 上章节讲解C语言中的联合体,位段,以及枚举类型,不清楚的可以回顾上一章节,本章节主要针对结构体内存占用给大家详细介绍. 内存问题 在编写C语言以下程序的时候: struct data {     ...

  7. 可持久化数据结构加扫描线_结构化光扫描

    可持久化数据结构加扫描线 Traditional cameras and image sensors can only obtain two-dimensional images, lacking d ...

  8. 爬虫获取不到网页完整源码_你的第一只网络爬虫

    " 我相信有相当大部分人,学习python最初动机,就是做一个网络爬虫,虽然python的主要强项是数据分析方面(至少我是这样认为的),但这并不妨碍它成为目前最主流的网络爬虫编写语言.&qu ...

  9. 谷歌第一个开源编程语言_我的第一个开源冒险

    谷歌第一个开源编程语言 by Anthony Ng 由Anthony Ng 我的第一个开源冒险 (My First Open Source Adventure) ✨✨灵感✨✨ (✨✨ Inspirat ...

最新文章

  1. 自定义服务器怎么调98k,《刺激战场》如何开自定义房间?升级可领房卡,3倍物资98k随便捡...
  2. linux(6/17)--文件打包上传和下载
  3. 通过缓存数据库结果提高PHP性能(转)
  4. 2.Riesz定理及其应用
  5. 大数据WEB阶段(十六)JavaEE三大 核心技术之监听器Listener
  6. Elasticsearch的用例:灵活的查询缓存
  7. js冒泡排序,简单的冒泡排序
  8. 计算机图形学中向量点乘和叉乘的用途_图形学笔记(一):基础知识
  9. windows下面常用的***测试命令
  10. Struts2的属性驱动与模型驱动的区别
  11. docker容器启动与停止命令
  12. [转]用C++实现插件体系结构
  13. 用数字计算机公式表白,爱情数学简单表白公式
  14. 在线免费OCR文字识别工具,强烈推荐,这是目前用过最良心的
  15. 动态数据可视化图表制作
  16. org.apache.hadoop.hive.ql.exec.mr.MapRedTask. Could not find status of job:job_1649726530586_123811
  17. Android更换logo之后小米手机和部分三星手机通知栏的小图标未显示正确的图标问题
  18. VIBE运动目标检测算法实现
  19. R语言表示文件路径应该如何使用斜杠符号?
  20. createCriteria的用法

热门文章

  1. 爱润妍代理模式营销系统
  2. Win10右击个性化后报错“该文件没有与之关联的应用来执行该操作
  3. GDOI#345. 送礼物「JSOI 2015」01分数规划+RMQ
  4. Android 隐私合规API检查方案
  5. 关于Caused by: com.alibaba.fastjson.JSONException: syntax error, expect }, actual ,
  6. 自动化测试平台(二):开发用户认证接口
  7. HBase基础【HBase简介、HBase安装、HBase shell操作】
  8. java后台jd_2017春季_京东_Java后端研发岗面经
  9. 6.又双叒叕背包模拟
  10. Android RSS订阅