草庐IT

读函数式编程思维笔记05_现实应用

躺柒 2023-04-16 原文

1. Java 8

1.1. 除了增加函数式特性,还增加了一些配合使用的语法糖衣

1.2. 函数式接口

1.2.1. SAM(Single Abstract Method,单抽象方法)接口

1.2.1.1. 含有单一方法的接口是Java的一种习惯用法

1.2.1.2. Runnable和Callable接口都是有代表性的例子

1.2.2. 对旧有SAM接口的增强,它允许我们用lambda块取代传统的匿名类来就地实例化一个接口

1.3. 默认方法

1.3.1. 一些在接口类型中声明的,以default关键字标记的,非抽象、非静态的public方法(且带有方法体定义)

1.4. mixin

1.4.1. 介于接口和父类之间的一种结构

1.4.2. 和接口一样都是类型,都可以执行instanceof检查,也都遵循一样的扩展规则

1.4.3. Ruby、Groovy等类似语言也允许通过mixin的形式,在既有的类层次上增补功能

1.5. Optional类型

1.5.1. min()等内建方法都不直接返回结果值,而是返回一个Optional结构

1.5.2. 提供了ifPresent()方法,可以用在终结操作的位置上,设定在仅当存在有效结果时执行的一个代码块

1.6. stream

1.6.1. 不存储值,只担当从输入源引出的管道角色,一直连接到终结操作上产生输出

1.6.2. 尽可能做到缓求值

1.6.3. 可以没有边界(无限长)

1.6.3.1. 用limit()、findFirst()等方法来取得其一部分子集

1.6.4. 用过之后必须重新生成新的stream才能再次操作

1.6.4.1. 消耗品

1.6.5. 操作分类

1.6.5.1. 中间操作

1.6.5.1.1. 一律返回新的stream,并且总是缓求值的

1.6.5.2. 终结操作

1.6.5.2.1. 遍历stream,产生结果值和副作用

2. 函数式的基础设施

2.1. 架构

2.1.1. 架构永远是取舍的结果

2.1.2. 从根本上贯彻“值不可变”的思路,最大化地发挥其优点

2.1.2.1. Java不允许字典型集合中的键在它被集合引用期间发生取值的变化,值不可变的对象完全符合这项要求

2.1.2.2. Groovy用语法糖衣掩盖了实现值不可变性的繁琐细节

2.1.2.2.1. 添加@Immutable标注

2.1.3. 测试是为了确认代码中成功地制造了我们需要的变化

2.1.3.1. 测试的真正目的是对可变事物的检验——可变的事物越多,就需要越多的测试来保证其正确性

2.1.3.2. 可变的状态越多,要求的测试也越多。

2.1.4. 值不可变的对象天生就是线程安全的,完全不会发生同步方面的问题

2.1.4.1. 具有原子性的失败(failure atomicity):只要对象构造完毕,就不会再发生由值可变性引发的失败

2.1.5. 实现一个值不可变的Java类

2.1.5.1. 把所有的字段都标记为final

2.1.5.1.1. 要么在声明时初始化,要么在构造器中初始化

2.1.5.2. 把类标记为final,防止被子类覆盖

2.1.5.3. 不要提供无参数的构造器

2.1.5.3.1. 一个值不可变的对象,它的一切状态都必须通过构造器来设定
2.1.5.3.2. 值不可变的类根本不应该出现无参数的构造器
2.1.5.3.2.1. 必须提供无参数的构造器,考虑用一个私有的无参数构造器来满足框架的要求
2.1.5.3.2.2. 私有的构造器仍然可以通过反射来访问

2.1.5.4. 提供至少一个构造器

2.1.5.5. 除了构造器之外,不要提供任何制造变化的方法

2.1.5.5.1. 标记了final的对象引用并不等于它所指向的一切都不可改变
2.1.5.5.2. 需要预防性地复制所有通过getXXX方法返回的对象引用

2.1.6. 命令-查询职责隔离架构

2.1.6.1. (Command-Query Responsibility Segregation,CQRS)

2.1.7. 最终一致性(eventual consistency)

2.1.7.1. 不对模型的变更操作施加硬性的时间限制,而只是保证,当更新发生后,模型最终会回复到一致的状态

2.1.7.2. 事务要求系统满足ACID(即原子性Atomic、一致性Consistent、隔离性Isolated、持久性Durable的缩写)性质,而最终一致性要求满足BASE(即基本可用Basically Available、软状态Soft state、最终一致性Eventual consistency的缩写)性质

2.1.7.3. 读取与变更分离之后,逻辑可得到简化

2.1.7.3.1. 承担读取职责的部分可以全面实现值不可变的性质

2.2. Web框架

2.2.1. 整个Web看作是一系列从请求到响应的变换

2.2.1.1. Web领域与函数式编程简直是天作之合

2.2.2. 路由框架

2.2.3. 以函数作为路由的目标

2.2.4. 领域专用语言(DSL)

2.2.4.1. 表达能力有限,专门针对一个狭窄问题域的计算机编程语言

2.2.4.2. 内部DSL是在其宿主语言之上构造出来的新“语言”,且利用宿主语言的语法糖衣来形成自身的风格

2.2.4.2.1. Ruby on Rails Web框架
2.2.4.2.2. C#语言的LINQ扩展

2.2.5. 与构建工具紧密集成

2.2.5.1. 和命令行的构建工具紧密集成,用构建工具来执行从生成新项目骨架到运行测试的一切任务

2.3. 数据库

2.3.1. Datomic是一种值不可变的数据库

2.3.1.1. 存储值而非数据,它的空间利用效率并不低

2.3.1.2. 进入到库里的每一笔事实都会被打上时间戳

2.3.1.3. 在信息上增加了时间的概念,使得每一笔事实都总是维持在正确的上下文里

2.3.1.4. 永久地记录所有的schema变更和数据变更

2.3.1.5. 读取和写入分离

2.3.1.5.1. Datomic拥有一个CQRS系统的内在

2.3.1.6. 事件驱动型架构中的值不可变性和时间戳

2.3.1.6.1. 依靠一个事件流来反映应用程序的状态变化,而一个捕获所有信息并加上时间戳记的数据库,正好可以完美地扮演事件流的角色,数据库本身的特性即可满足回退和重放事件的需求

有关读函数式编程思维笔记05_现实应用的更多相关文章

  1. ruby - 将差异补丁应用于字符串/文件 - 2

    对于具有离线功能的智能手机应用程序,我正在为Xml文件创建单向文本同步。我希望我的服务器将增量/差异(例如GNU差异补丁)发送到目标设备。这是计划:Time=0Server:hasversion_1ofXmlfile(~800kiB)Client:hasversion_1ofXmlfile(~800kiB)Time=1Server:hasversion_1andversion_2ofXmlfile(each~800kiB)computesdeltaoftheseversions(=patch)(~10kiB)sendspatchtoClient(~10kiBtransferred)Cl

  2. ruby-on-rails - Rails 应用程序之间的通信 - 2

    我构建了两个需要相互通信和发送文件的Rails应用程序。例如,一个Rails应用程序会发送请求以查看其他应用程序数据库中的表。然后另一个应用程序将呈现该表的json并将其发回。我还希望一个应用程序将存储在其公共(public)目录中的文本文件发送到另一个应用程序的公共(public)目录。我从来没有做过这样的事情,所以我什至不知道从哪里开始。任何帮助,将不胜感激。谢谢! 最佳答案 无论Rails是什么,几乎所有Web应用程序都有您的要求,大多数现代Web应用程序都需要相互通信。但是有一个小小的理解需要你坚持下去,网站不应直接访问彼此

  3. ruby - 无法运行 Rails 2.x 应用程序 - 2

    我尝试运行2.x应用程序。我使用rvm并为此应用程序设置其他版本的ruby​​:$rvmuseree-1.8.7-head我尝试运行服务器,然后出现很多错误:$script/serverNOTE:Gem.source_indexisdeprecated,useSpecification.Itwillberemovedonorafter2011-11-01.Gem.source_indexcalledfrom/Users/serg/rails_projects_terminal/work_proj/spohelp/config/../vendor/rails/railties/lib/r

  4. ruby-on-rails - Rails 应用程序中的 Rails : How are you using application_controller. rb 是新手吗? - 2

    刚入门rails,开始慢慢理解。有人可以解释或给我一些关于在application_controller中编码的好处或时间和原因的想法吗?有哪些用例。您如何为Rails应用程序使用应用程序Controller?我不想在那里放太多代码,因为据我了解,每个请求都会调用此Controller。这是真的? 最佳答案 ApplicationController实际上是您应用程序中的每个其他Controller都将从中继承的类(尽管这不是强制性的)。我同意不要用太多代码弄乱它并保持干净整洁的态度,尽管在某些情况下ApplicationContr

  5. ruby - 在没有 sass 引擎的情况下使用 sass 颜色函数 - 2

    我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re

  6. ruby-on-rails - 如何在我的 Rails 应用程序 View 中打印 ruby​​ 变量的内容? - 2

    我是一个Rails初学者,但我想从我的RailsView(html.haml文件)中查看Ruby变量的内容。我试图在ruby​​中打印出变量(认为它会在终端中出现),但没有得到任何结果。有什么建议吗?我知道Rails调试器,但更喜欢使用inspect来打印我的变量。 最佳答案 您可以在View中使用puts方法将信息输出到服务器控制台。您应该能够在View中的任何位置使用Haml执行以下操作:-puts@my_variable.inspect 关于ruby-on-rails-如何在我的R

  7. ruby-on-rails - 在 ruby​​ 中使用 gsub 函数替换单词 - 2

    我正在尝试用ruby​​中的gsub函数替换字符串中的某些单词,但有时效果很好,在某些情况下会出现此错误?这种格式有什么问题吗NoMethodError(undefinedmethod`gsub!'fornil:NilClass):模型.rbclassTest"replacethisID1",WAY=>"replacethisID2andID3",DELTA=>"replacethisID4"}end另一个模型.rbclassCheck 最佳答案 啊,我找到了!gsub!是一个非常奇怪的方法。首先,它替换了字符串,所以它实际上修改了

  8. ruby - 在 Ruby 中有条件地定义函数 - 2

    我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin

  9. ruby - 寻找通过阅读代码确定编程语言的ruby gem? - 2

    几个月前,我读了一篇关于ruby​​gem的博客文章,它可以通过阅读代码本身来确定编程语言。对于我的生活,我不记得博客或gem的名称。谷歌搜索“ruby编程语言猜测”及其变体也无济于事。有人碰巧知道相关gem的名称吗? 最佳答案 是这个吗:http://github.com/chrislo/sourceclassifier/tree/master 关于ruby-寻找通过阅读代码确定编程语言的rubygem?,我们在StackOverflow上找到一个类似的问题:

  10. ruby-on-rails - 如何在 Gem 中获取 Rails 应用程序的根目录 - 2

    是否可以在应用程序中包含的gem代码中知道应用程序的Rails文件系统根目录?这是gem来源的示例:moduleMyGemdefself.included(base)putsRails.root#returnnilendendActionController::Base.send:include,MyGem谢谢,抱歉我的英语不好 最佳答案 我发现解决类似问题的解决方案是使用railtie初始化程序包含我的模块。所以,在你的/lib/mygem/railtie.rbmoduleMyGemclassRailtie使用此代码,您的模块将在

随机推荐