状态机复合状态 怎么写代码_状态不属于代码

状态机复合状态 怎么写代码

Web应用程序中的“状态”是什么? 它是要存储的数据(与目的地无关—内存,数据库,文件系统)。 应用程序本身不得在代码中存储任何状态。 这意味着您的类应该只包含带有无状态对象的字段。 换句话说,在程序流程期间,您不应在服务,DAO或控制器中存储任何内容。 这是服务层的完整“必须”。 为什么?

您的应用程序需要可扩展。 这意味着它需要在集群中运行,而状态是最难分配的。 如果您将状态存储的位置最小化,则可以将群集的复杂性最小化。 但是状态应该存在,在这里拥有状态就可以了:

  • 数据库–无论是SQL,NoSQL还是搜索引擎,它都是存储状态的主要内容。 它应该是支持集群的东西,或者是处理来自多个其他“代码”服务器的请求的大型专用计算机。 该代码与数据库进行通信,但是代码本身不会为一个以上的客户请求存储任何内容。
  • 缓存-缓存相对容易分发(基本上是键值)。 有许多现成的解决方案,例如EhCache和memcached。 因此,您可以配置缓存并将结果存储在内存中,而不是计算结果或根据每个请求从数据库获取结果。 但是,代码仍然没有存储任何内容,它只是填充并查询缓存。
  • HTTP会话–在Web组件(控制器,托管Bean,无论您叫什么)中。 它与缓存非常相似,但是具有不同的目的–允许识别同一用户的后续操作(http本身是无状态的)。 但是,由于您的代码在多台计算机上运行,​​因此负载均衡器可能并不总是将后续请求发送到同一服务器。 因此,会话也应该在所有服务器之间复制。 幸运的是,大多数容器都内置了该选项,因此您只需添加一条配置行。 或者,您可以指示负载均衡器使用“粘性会话”(根据会话cookie来确定发送请求的服务器),但是它也会将一些状态管理也移至负载均衡器。 无论您选择哪种选项,都不要在会话中放入太多数据
  • 文件系统–存储文件时,需要所有计算机都可以访问它们。 这里有多个选项,包括SAN或使用Amazon S3之类的云存储服务,可通过API访问

所有这些都在代码之外进行管理。 您的代码仅通过API(会话API,缓存API,JDBC,S3 /文件系统API)使用它们。 如果代码包含该状态中的任何一个(作为对象的实例变量),则该应用程序将难以支持(您必须自己管理状态),并且可伸缩性也会降低。 当然,在少数情况下,如果不将状态存储在代码中就行不通。 记录这些,并确保它们不依赖于在集群中工作。

但是,如果将状态存储在执行业务逻辑的对象中,那会出错吗? 然后,您有两个选择:

  • 同步对字段的访问–这会降低性能,因为所有发出请求的用户都必须排队等待服务来管理其字段;
  • 为每个HTTP请求创建类的新实例,并以某种方式管理实例。 管理这些实例是困难的部分。 人们可能会倾向于选择会话来执行此操作,这意味着会话会变得非常大且难以复制(跨多台计算机共享大量数据的速度较慢,会话复制必须快速)。 更不用说不必要地增加了内存占用。

这是不做什么的简单例子。 您应该将这些类型的值作为方法参数传递,而不是将其存储在实例中:

class OrderService {
   double orderPrice;

   void processOrder(OrderDto order) {
         for (Entry entry : order.getEntries() {
              orderPrice += entry.getPrice();
         }
         boolean discounts = hasDiscounts(order);
   }
   boolean hasDiscounts(OrderDto order) {
        return order.getEntries().length > 5 && orderPrice > 200;
   }
}

因此,使您的所有代码都为无状态–这将确保至少某种程度的可伸缩性。

参考:我们的JCG合作伙伴 未将State 列入 守则   Bozho的技术博客中的 Bozhidar Bozhanov


翻译自: https://www.javacodegeeks.com/2012/02/state-does-not-belong-in-code.html

状态机复合状态 怎么写代码

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值