当前位置: 首页 > 网络应用技术

功能编程Java编码实践:使用惯性编写高性能和抽象代码

时间:2023-03-06 00:04:24 网络应用技术

  本文将以惯性加载为示例来介绍功能编程中的各种概念,因此读者不需要任何功能编程基础,只需要对Java 8了解一点。

  程序员的梦想是编写“高内部聚会,低耦合”的代码,但是从经验的角度来看,较抽象的代码通常意味着性能越低。计算机可以直接执行最强大的组装性能。其次,C语言,Java由于高抽象水平而具有较低的性能。业务系统也受相同法律的限制。基础删除数量和底层的更改的数量最高。由于添加了各种业务验证和消息发送,因此添加了上层业务界面,从而导致性能低。

  性能问题还限制了程序员对模块的更合理的抽象。

  让我们看一下常见的系统抽象。“用户”是系统中的常见实体。为了统一系统中的“用户”抽象,我们在通用字段中定义了用户。除了用户的ID外,它还包含部门信息。用户的主管等。这些是系统中经常聚集在一起的属性:

  这看起来很好。“用户”都集中在实体上。只要将该用户用作该方法的参数,此方法基本上就不再需要查询其他用户信息。但是,一旦实现了该方法,就会找到问题。部门和主管的信息需要通过远程致电通讯录系统来获得。需要通过远程调用权限获得许可。每个构造的用户必须支付这两个远程调用的价格。

  为了能够在上述方法参数中使用通用用户实体,必须付费:远程呼叫以获取完全无法使用的权限信息。如果权威系统存在问题,它也会影响无关接口的稳定性。

  考虑到这一点,我们可能想放弃通用实体的解决方案,让暴露的UID渗透到系统,并在整个系统中散布的用户信息查询代码。

  实际上,一些改进可以继续使用上述抽象。您只需要将部门,主管和Permssion转变为惰性负载领域。在需要时,将获得外部呼叫。这是非常好的:

  但是,在实践过程中经常遇到一些问题。本文结合了Java的一些技术和功能编程,以将惰性加载工具类实现。

  Java 8引入了一个新功能-Type接口供应商。从旧的Java程序员的角度来看,它只是一个可以获得任何值的接口。lambda只是该接口实现类的语法糖。这是对语言视角的理解,而不是计算角度。当您了解严格和懒惰之间的区别时,您可能会更仔细地了解计算。

  因为Java和C是严格的编程语言,所以我们习惯了定义位置中变量的计算。实际上,当使用变量时,还有另一种编程语言类型,例如功能编程语言Haskell。

  因此,供应商的本质是在Java语言中引入惰性计算机制。为了在Java中实现同等的惰性计算,您可以写下:

  供应商仍然存在一个问题,也就是说,每次通过获取值获得价值时,您都会被重新计算。真正的惯性计算应在第一次获得后缓存值。

  通过懒惰编写先前的惯性计算代码:

  通过此惰性加载工具类优化我们以前的通用用户实体:

  简单构造的用户实体的一个示例如下:

  这看起来还不错,但是当您继续深入使用它时,您会发现一些问题:用户的两个属性部门和主管是关联的,您需要通过RPC接口获得用户部门,然后获得主管通过部门的另一个RPC接口。代码显示如下:

  但是现在部门不再是计算出的值,而是惰性计算懒惰对象。上面的代码应该如何编写?“ takako”用于解决此问题

  快速理解:在Java中可选的流中API或MAP方法。该字母可以理解为接口,并且映射可以理解为接口中的方法。

  1个字母的计算对象

  在Java收藏< T>选修的< T>我们只是意识到懒惰< T>有一个共同的功能,也就是说,它们都有并且只有一个通用参数。在本文中,我们暂时将其称为一个框,并将其记录为框< T>因为它们似乎是一个通用的容器,所以可以将它们包装在任何类型中。

  2字母的定义

  字母的字母可以映射到b框中的功能< T> 鞋面,让它变成框< S>,将框中的数字转换为字符串的示例如下:如下:

  在框中安装的原因不是1和“ 1”,是因为框不一定是一个值,例如设置,甚至更复杂的多值映射关系。

  应该注意的是,它不仅定义签名以满足盒子< S> 地图(功能< T,S> 功能)< T> 成为一封信,以下是一个反面示例:

  因此,Chanzi比MAP方法更为严格。他还要求地图将满足以下法律,称为字母的法律(法律的本质是为了确保地图方法可以真实地反映由参数函数定义的映射关系):

  显然,懒惰符合上述两项法律。

  3个懒惰的信

  尽管我引入了很多理论,但实施非常简单:

  它可以很容易地证明它对Chan Zi定律感到满意。

  通过地图,很容易解决以前遇到的问题。假设已获得部门的信息时,可以计算在地图中传递的功能:

  4我遇到了一个更棘手的情况

  我们不仅可以构建一个惰性值,还可以使用一个惰性值来计算另一个惰性值,该值看起来很完美。但是,当您进一步使用它时,您会发现更多的困难问题。

  我现在需要部门和主管的两个参数来规范权限系统以获得权限,部门和主管的两个值是惰性值。首先,用嵌套地图尝试:

  回报值的类型似乎有些奇怪,我们期待的是懒惰< Set< String>>,但要获得一层懒惰< Lazy< Set< String>>“随着嵌套地图层的增加,Lazy的通用层也会增加。这三个参数的示例如下:

  这需要以下列表操作来解决。

  快速理解:类似于可选的Flatmap功能

  1定义

  单个和字母之间的显着差异是接收的功能。字母的功能通常返回到本地值,单个功能的功能返回一个框值。如果使用下图中的功能代替flatmap,则会导致结果成为俄罗斯娃娃two-layer框。

  当然,列表的列表也有一项法律,但比陈Zi法律更为复杂。在这里不会解释。他的角色类似于Chan Zi的定律,该定律可确保Flatmap可以如实反映功能的映射关系。

  2个懒惰列表

  实施也非常简单:

  使用FlatMap解决之前遇到的问题:

  三个参数:

  法律是最后一个值用于使用地图,而其他值则使用flatmap。

  3问题:功能语言中的单语法糖

  阅读了上述示例后,您肯定会觉得惯性计算很麻烦。每当您将惰性值带入内部时,都需要多次体验flatmap和映射。这实际上是Java没有本机支持功能编程的妥协。在Haskell中,它支持使用DO来简化Monad的操作。上述三参数的示例是用Haskell写的:

  尽管Java中没有语法糖,但上帝关上了一扇门,打开了窗户。如果您在本文之前阅读了内容,则可以肯定地理解此DO方法正在不断地进行Flatmap。

  到目前为止,我们编写的懒惰代码如下:

  使用懒惰来编写构建通用用户实体的工厂:

  工厂类别是构造一棵凭证树。通过工厂类别,您可以清楚地看到用户属性之间的值依赖性依赖关系。同时,用户对象可以自动优化运行时的性能。顶部所有属性的值将被缓存。

  尽管我们使user.getDeppartment()似乎是一个纯粹的内存操作,但实际上是遥不可及的,因此可能存在各种意外的异常,例如加班等。

  不得将异常的治疗方法移交给业务逻辑,这将影响业务逻辑的纯度并让我们放弃我们。理想的方法是为惰性值加载逻辑供应商。异常,尝试或抛出异常。尽管抛出异常时可能不是这样的“功能”,但它更接近Java的编程习惯,当未获得关键值时,它应该通过异常来阻止业务逻辑的运行。

  本文方法构建的实体可以放置在业务建模所需的所有属性中。业务建模只需要考虑在不考虑基本绩效问题的情况下适应业务,并真正实现业务层和物理层的下降。

  同时,UserFactory本质上是外部接口的适配器层。一旦外部接口更改,您只需要修改适配器层即可保护核心业务代码的稳定性。

  由于业务核心代码大大减少,因此代码更接近纯操作,因此很容易编写单元测试。通过单元测试,它可以确保核心代码的稳定性并不能犯错误。

  如果您考虑一下,那就这样做,目的就是一个。C F(a,b)的签名功能可以应用于框类型框,而无需修改< A>和盒子< B> 继续,生成一个盒子< C>有一种更方便的方法可以使用功能性语言,即字母的应用。

  申请信的概念非常简单。它是将框函数应用于框的值。最后,可以获得盒子的值。它可以懒惰:

  但是,在Java中实施此功能是没有用的,因为Java不支持Corride。

  Corride允许我们将函数的参数数量固定到新功能中。如果函数签名为f(a,b),则支持Corride的语言允许直接f(a)调用。目前,返回值已返回。这是一个仅接收b ..的函数

  在支持Corride的情况下,只需要几个连续的申请信即可将普通功能应用于框类型,而Haskell的示例< *> 是在Haskell中应用字母字母的语法糖。F是签名C F(a,b)的函数。

  参考

  资料来源:阿里巴巴云