文档章节

理解服务的无状态性

霖vv
 霖vv
发布于 2016/09/09 11:07
字数 887
阅读 17
收藏 0

1.7 理解服务的无状态性(1)

无状态(statelessness)指的是服务内部变量值的存储。如果一个服务的确无状态,那么就能调用服务的任何方法或引用该服务的任何属性,而且只要传递相同的参数,该服务就能以相同的方式正常运行。换言之,服务中存储的值可以被外部调用者改变,而且不会影响操作的结果。

为了了解无状态性,回顾一下代码清单1.10。它展示了一个在商店买东西的过程的服务。

代码清单1.10 不能退货的购物过程示例
 

 
  1. /// <summary> 
  2. /// Class representing the process of buying an item  
  3. /// from a store.  
  4. /// </summary> 
  5. public class SalesclerkNoRefunds  
  6. {  
  7.   /// <summary> 
  8.   /// Method to call when a customer is buying an item.  
  9.   /// </summary> 
  10.   public void SellItem(string itemToSell, string nameOfPurchaser)  
  11.   {  
  12.     var price = GetItemPrice(itemToSell);  
  13.     GetPaymentFromCustomer(price);  
  14.   }  
  15.  
  16.   /// <summary> 
  17.   /// Interacts with the customer to get payment.  
  18.   /// </summary> 
  19.   private void GetPaymentFromCustomer(double amount)  
  20.   {  
  21.     //Get the payment from the customer  
  22.   }  
  23.  
  24.   /// <summary> 
  25.   /// Lookup the price of the item and return it  
  26.   /// </summary> 
  27.   private double GetItemPrice(string itemToSell)  
  28.   {  
  29.     //Lookup the price of the item and return it.  
  30.     return 15.00;  
  31.   }  

在这个销售过程中,我们可以从商店中的任何一个选定的职员处购买东西,而且可以顺利地完成此次购买。该服务没有局部变量和状态,所以任何一个售货员都能处理这个业务。然而,这个过程不允许退货,它仅仅支持购物。让我们来完善这个类,为这个类增加一个退货的方法。思考代码清单1.11所示的已经优化了的类和ReturnItem方法。

代码清单1.11 允许退货的购物过程示例
 

 
  1. /// <summary> 
  2. /// Class representing the process of buying an item.  
  3. /// </summary> 
  4. public class SalesclerkWithState  
  5. {  
  6.   private List<Purchase> _rememberedPurchases;  
  7.  
  8.   public SalesclerkWithState()  
  9.   {  
  10.     _rememberedPurchases = new List<Purchase>();  
  11.   }  
  12.  
  13.   /// <summary> 
  14.   /// Method to call when a customer is buying an item.  
  15.   /// </summary> 
  16.   public void SellItem(string itemToSell, string nameOfPurchaser)  
  17.   {  
  18.     var purchase = new Purchase();  
  19.     purchase.PurchaserName = nameOfPurchaser;  
  20.     purchase.SaleDate = DateTime.Today;  
  21.     purchase.ItemSold = itemToSell;  
  22.     purchase.AmountPaid= GetItemPrice(itemToSell);  
  23.     ReceiveOrRefundPayment(purchase.AmountPaid);  
  24.     _rememberedPurchases.Add(purchase);  
  25.   }  
  26.  
  27.   /// <summary> 
  28.   /// Method to call when the customer is returning the item.  
  29.   /// </summary> 
  30.   public void ReturnItem()  
  31.   {  
  32.     var purchase = RememberItemSoldToCustomer();  
  33.     ReceiveOrRefundPayment(-purchase.AmountPaid);  
  34.   }  
  35.  
  36.   /// <summary> 
  37.   /// Charge the customer credit card for the purchase.  
  38.   /// </summary> 
  39.   private Purchase RememberItemSoldToCustomer()  
  40.   {  
  41.     //Recall the customer and how much they paid.  
  42.     return _rememberedPurchases[0];  
  43.   }  
  44.  
  45.   /// <summary> 
  46.   /// Interacts with the customer to get the credit card number.  
  47.   /// </summary> 
  48.   private void ReceiveOrRefundPayment(double amount)  
  49.   {  
  50.     //Get the payment from the customer  
  51.   }  
  52.  
  53.   /// <summary> 
  54.   /// Lookup the price of the item and return it.  
  55.   /// </summary> 
  56.   private double GetItemPrice(string itemToSell)  
  57.   {  
  58.     //Lookup the price of the item and return it.  
  59.     return 154.00;  
  60.   }  
  61.  
  62.   private class Purchase  
  63.   {  
  64.     public string PurchaserName { get; set; }  
  65.     public double AmountPaid { get; set; }  
  66.     public DateTime SaleDate { get; set; }  
  67.     public string ItemSold { get; set; }  
  68.   }  

该类引入了ReturnItem方法,但需注意的是也在服务中引入了状态。为了允许消费者退货,售货员必须知道消费者为商品支付了多少钱。如果不这么做,有些人可以将大减价期间买的商品在减价结束后以原价退回给商店。因此,售货员需要记得每个购物的人以多少价格购买了什么商品。为了追踪这些信息,我们引入了Purchase类和购物清单。

现在我们可以在同一家商店购物和退货。然而,使用现有的设计,我们必须和最初卖那个商品的售货员进行沟通。注意,Purchase类是私有的,代表它仅由最初的那个售货员通过回忆获取。如果换一个售货员,他将不能记起那次购买,也就不能退款。这是在服务中引入状态的弊端。我们不能实例化Salesclerk类的两个副本,而且也不能在两个副本之间随意返回一些东西,必须找到最初卖给我们商品的店员

© 著作权归作者所有

霖vv

霖vv

粉丝 25
博文 165
码字总数 97397
作品 0
朝阳
程序员
私信 提问
理解本质的 REST

REST本身是一个高度抽象化的架构风格,因而总是很难对它有一个比较深入且印象深刻的理解。写这篇文章的目的,是自己对学习REST的一个总结,也希望可以通过这篇文章,能够让读者真正的理解RES...

vito
2017/10/09
0
0
RESTful API是无状态的,那么身份认证是不是resetful

在REST应用程序中,每个请求必须包含服务器需要理解的所有信息,而不是依赖于服务器记住先前的请求。 在服务器上存储会话状态违反了REST体系结构的无状态约束。因此,会话状态必须完全由客户...

火力全開
02/25
0
0
RESTful 真正意味着什么?

上个月,我在Skillsmatter参加了一个关于RESTful微服务快速进阶的培训课程。课程着重探讨了REST API在web应用和微服务交互方面起到的作用。对我来说,这个课程给我最大的收获是让我更好地理解...

oschina
2016/08/05
17.7K
10
DDD理论学习系列(8)-- 应用服务&领域服务

DDD理论学习系列——案例及目录 1. 引言 单从字面理解,不管是领域服务还是应用服务,都是服务。而什么是服务?从SOA到微服务,它们所描述的服务都是一个宽泛的概念,我们可以理解为服务是行...

圣杰
2017/06/30
0
0
漫谈 REST 架构风格

1. 什么是REST REST是REpresentational State Transfer的缩写,来源于R. Fielding的一篇博士论文:《Architectural Styles and the Design of Network-based Software Architectures 》。RES......

青夜之衫
2017/12/05
0
0

没有更多内容

加载失败,请刷新页面

加载更多

利用mybatis generator生成实体类、Mapper接口以及对应的XML文件

项目中通常会遇到数据的持久化,如果是采用mybatis的orm,就会涉及到生成xml的问题,刚好mybatis官网提供了这么个插件MyBatis Generator,效果简直是棒呆。 1. 首先需要在build.gradle文件中...

啊哈关关
今天
2
0
SpringSocial相关的知识点

使用SprigSocial开发第三方登录 核心类 ServiceProvider(AbstractOauth2ServiceProvider):主要负责实现server提供商(例如QQ,微信等共有的东西),默认实现类是AbstractOauth2ServiceProvider...

chendom
今天
2
0
Java并发之AQS详解

一、概述   谈到并发,不得不谈ReentrantLock;而谈到ReentrantLock,不得不谈AbstractQueuedSynchronizer(AQS)!   类如其名,抽象的队列式的同步器,AQS定义了一套多线程访问共享资源...

群星纪元
昨天
2
0
Fabric-sdk-java最新教程

Fabric Java SDK是Fabric区块链官方提供的用于Java应用开发的SDK,全称为Fabric-sdk-java,网上可用资料不多,本文列出了精心整理的针对Fabric Java SDK的最新精选教程。 如果希望快速掌握F...

汇智网教程
昨天
3
0
react 子组件监听props 变化

componentWillReceiveProps //已经被废弃 getDerivedStateFromProps// 推荐使用//如果条件不存在必须要返回null static getDerivedStateFromProps(props, current_stat...

一箭落旄头
昨天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部